turnip: Add driver skeleton (v2)

meson files have been updated, autotools and android still need
updating.

Only build tested.

v2 (chadv):
  - Rebase onto master.
  - Fix build breakage in Python scripts.
  - Drop the WSI code. The internal WSI apis have changed recently, and
    will likely change again before the driver goes upstream. To avoid
    unnecessary rebase work, let's drop the WSI code and re-add it when
    we're ready to really use WSI.

(olv, after rebase) do not enable freedreno by default on ARM
This commit is contained in:
Bas Nieuwenhuizen 2018-08-08 22:23:57 +00:00 committed by Chia-I Wu
parent d086d16b81
commit 26380b3a9f
34 changed files with 9893 additions and 2 deletions

View File

@ -203,6 +203,7 @@ endif
with_intel_vk = _vulkan_drivers.contains('intel')
with_amd_vk = _vulkan_drivers.contains('amd')
with_freedreno_vk = _vulkan_drivers.contains('freedreno')
with_any_vk = _vulkan_drivers.length() != 0 and _vulkan_drivers != ['']
if with_dri_swrast and (with_gallium_softpipe or with_gallium_swr)

View File

@ -152,7 +152,7 @@ option(
'vulkan-drivers',
type : 'array',
value : ['auto'],
choices : ['', 'auto', 'amd', 'intel'],
choices : ['', 'auto', 'amd', 'freedreno', 'intel'],
description : 'List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
)
option(

View File

@ -22,3 +22,7 @@ inc_freedreno = include_directories(['.', './registers'])
subdir('drm')
subdir('ir3')
if with_freedreno_vk
subdir('vulkan')
endif

View File

@ -0,0 +1,166 @@
# Copyright © 2018 Advanced Micro Devices, Inc.
# Copyright © 2018 Mauro Rossi issor.oruam@gmail.com
# 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 (including the next
# paragraph) 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.
LOCAL_PATH := $(call my-dir)
# get VULKAN_FILES and VULKAN_GENERATED_FILES
include $(LOCAL_PATH)/Makefile.sources
# The gallium includes are for the util/u_math.h include from main/macros.h
TU_COMMON_INCLUDES := \
$(MESA_TOP)/include \
$(MESA_TOP)/src/ \
$(MESA_TOP)/src/vulkan/wsi \
$(MESA_TOP)/src/vulkan/util \
$(MESA_TOP)/src/amd \
$(MESA_TOP)/src/amd/common \
$(MESA_TOP)/src/compiler \
$(MESA_TOP)/src/mapi \
$(MESA_TOP)/src/mesa \
$(MESA_TOP)/src/mesa/drivers/dri/common \
$(MESA_TOP)/src/gallium/auxiliary \
$(MESA_TOP)/src/gallium/include \
frameworks/native/vulkan/include
TU_SHARED_LIBRARIES := libdrm_amdgpu
ifeq ($(filter $(MESA_ANDROID_MAJOR_VERSION), 4 5 6 7),)
TU_SHARED_LIBRARIES += libnativewindow
endif
#
# libmesa_tu_common
#
include $(CLEAR_VARS)
LOCAL_MODULE := libmesa_tu_common
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
intermediates := $(call local-generated-sources-dir)
LOCAL_SRC_FILES := \
$(VULKAN_FILES)
LOCAL_CFLAGS += -DFORCE_BUILD_AMDGPU # instructs LLVM to declare LLVMInitializeAMDGPU* functions
$(call mesa-build-with-llvm)
LOCAL_C_INCLUDES := \
$(TU_COMMON_INCLUDES) \
$(call generated-sources-dir-for,STATIC_LIBRARIES,libmesa_amd_common,,) \
$(call generated-sources-dir-for,STATIC_LIBRARIES,libmesa_nir,,)/nir \
$(call generated-sources-dir-for,STATIC_LIBRARIES,libmesa_tu_common,,) \
$(call generated-sources-dir-for,STATIC_LIBRARIES,libmesa_vulkan_util,,)/util
LOCAL_WHOLE_STATIC_LIBRARIES := \
libmesa_vulkan_util
LOCAL_GENERATED_SOURCES += $(intermediates)/tu_entrypoints.c
LOCAL_GENERATED_SOURCES += $(intermediates)/tu_entrypoints.h
LOCAL_GENERATED_SOURCES += $(intermediates)/tu_extensions.c
LOCAL_GENERATED_SOURCES += $(intermediates)/tu_extensions.h
LOCAL_GENERATED_SOURCES += $(intermediates)/vk_format_table.c
TU_ENTRYPOINTS_SCRIPT := $(MESA_TOP)/src/amd/vulkan/tu_entrypoints_gen.py
TU_EXTENSIONS_SCRIPT := $(MESA_TOP)/src/amd/vulkan/tu_extensions.py
VK_FORMAT_TABLE_SCRIPT := $(MESA_TOP)/src/amd/vulkan/vk_format_table.py
VK_FORMAT_PARSE_SCRIPT := $(MESA_TOP)/src/amd/vulkan/vk_format_parse.py
vulkan_api_xml = $(MESA_TOP)/src/vulkan/registry/vk.xml
vk_format_layout_csv = $(MESA_TOP)/src/amd/vulkan/vk_format_layout.csv
$(intermediates)/tu_entrypoints.c: $(TU_ENTRYPOINTS_SCRIPT) \
$(TU_EXTENSIONS_SCRIPT) \
$(vulkan_api_xml)
@mkdir -p $(dir $@)
$(MESA_PYTHON2) $(TU_ENTRYPOINTS_SCRIPT) \
--xml $(vulkan_api_xml) \
--outdir $(dir $@)
$(intermediates)/tu_entrypoints.h: $(intermediates)/tu_entrypoints.c
$(intermediates)/tu_extensions.c: $(TU_EXTENSIONS_SCRIPT) $(vulkan_api_xml)
@mkdir -p $(dir $@)
$(MESA_PYTHON2) $(TU_EXTENSIONS_SCRIPT) \
--xml $(vulkan_api_xml) \
--out-c $@ \
--out-h $(addsuffix .h,$(basename $@))
$(intermediates)/tu_extensions.h: $(intermediates)/tu_extensions.c
$(intermediates)/vk_format_table.c: $(VK_FORMAT_TABLE_SCRIPT) \
$(VK_FORMAT_PARSE_SCRIPT) \
$(vk_format_layout_csv)
@mkdir -p $(dir $@)
$(MESA_PYTHON2) $(VK_FORMAT_TABLE_SCRIPT) $(vk_format_layout_csv) > $@
LOCAL_SHARED_LIBRARIES += $(TU_SHARED_LIBRARIES)
LOCAL_EXPORT_C_INCLUDE_DIRS := \
$(MESA_TOP)/src/amd/vulkan \
$(intermediates)
include $(MESA_COMMON_MK)
include $(BUILD_STATIC_LIBRARY)
#
# libvulkan_radeon
#
include $(CLEAR_VARS)
LOCAL_MODULE := vulkan.tu
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_LDFLAGS += -Wl,--build-id=sha1
LOCAL_SRC_FILES := \
$(VULKAN_ANDROID_FILES)
LOCAL_CFLAGS += -DFORCE_BUILD_AMDGPU # instructs LLVM to declare LLVMInitializeAMDGPU* functions
$(call mesa-build-with-llvm)
LOCAL_C_INCLUDES := \
$(TU_COMMON_INCLUDES) \
$(call generated-sources-dir-for,STATIC_LIBRARIES,libmesa_tu_common,,)
LOCAL_EXPORT_C_INCLUDE_DIRS := \
$(MESA_TOP)/src/amd/vulkan \
$(intermediates)
LOCAL_WHOLE_STATIC_LIBRARIES := \
libmesa_util \
libmesa_nir \
libmesa_glsl \
libmesa_compiler \
libmesa_amdgpu_addrlib \
libmesa_amd_common \
libmesa_tu_common
LOCAL_SHARED_LIBRARIES += $(TU_SHARED_LIBRARIES) libz libsync liblog
include $(MESA_COMMON_MK)
include $(BUILD_SHARED_LIBRARY)

View File

@ -0,0 +1,200 @@
# Copyright © 2016 Red Hat
#
# 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 (including the next
# paragraph) 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.
include Makefile.sources
noinst_HEADERS = \
$(top_srcdir)/include/vulkan/vk_platform.h \
$(top_srcdir)/include/vulkan/vulkan_core.h \
$(top_srcdir)/include/vulkan/vulkan_wayland.h \
$(top_srcdir)/include/vulkan/vulkan_xcb.h \
$(top_srcdir)/include/vulkan/vulkan_xlib.h \
$(top_srcdir)/include/vulkan/vulkan.h
lib_LTLIBRARIES = libvulkan_radeon.la
# The gallium includes are for the util/u_math.h include from main/macros.h
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_builddir)/src \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/vulkan/wsi \
-I$(top_builddir)/src/vulkan/util \
-I$(top_srcdir)/src/vulkan/util \
-I$(top_srcdir)/src/amd \
-I$(top_srcdir)/src/amd/common \
-I$(top_builddir)/src/compiler \
-I$(top_builddir)/src/compiler/nir \
-I$(top_srcdir)/src/compiler \
-I$(top_srcdir)/src/mapi \
-I$(top_srcdir)/src/mesa \
-I$(top_srcdir)/src/mesa/drivers/dri/common \
-I$(top_srcdir)/src/gallium/auxiliary \
-I$(top_srcdir)/src/gallium/include \
$(AMDGPU_CFLAGS) \
$(VALGRIND_CFLAGS) \
$(DEFINES)
AM_CFLAGS = \
$(VISIBILITY_CFLAGS) \
$(PTHREAD_CFLAGS) \
$(LLVM_CFLAGS)
AM_CXXFLAGS = \
$(VISIBILITY_CXXFLAGS) \
$(LLVM_CXXFLAGS)
VULKAN_SOURCES = \
$(VULKAN_GENERATED_FILES) \
$(VULKAN_FILES)
VULKAN_LIB_DEPS = \
libvulkan_common.la \
$(top_builddir)/src/vulkan/libvulkan_util.la \
$(top_builddir)/src/vulkan/libvulkan_wsi.la \
$(top_builddir)/src/amd/common/libamd_common.la \
$(top_builddir)/src/amd/addrlib/libamdgpu_addrlib.la \
$(top_builddir)/src/compiler/nir/libnir.la \
$(top_builddir)/src/util/libmesautil.la \
$(LLVM_LIBS) \
$(LIBELF_LIBS) \
$(PTHREAD_LIBS) \
$(AMDGPU_LIBS) \
$(LIBDRM_LIBS) \
$(PTHREAD_LIBS) \
$(DLOPEN_LIBS) \
-lm
if HAVE_PLATFORM_DRM
AM_CPPFLAGS += \
-DVK_USE_PLATFORM_DISPLAY_KHR
VULKAN_SOURCES += $(VULKAN_WSI_DISPLAY_FILES)
endif
if HAVE_XLIB_LEASE
AM_CPPFLAGS += \
-DVK_USE_PLATFORM_XLIB_XRANDR_EXT \
$(XCB_RANDR_CFLAGS) \
$(XLIB_RANDR_CFLAGS)
VULKAN_LIB_DEPS += $(XCB_RANDR_LIBS)
endif
if HAVE_PLATFORM_X11
AM_CPPFLAGS += \
$(XCB_DRI3_CFLAGS) \
-DVK_USE_PLATFORM_XCB_KHR \
-DVK_USE_PLATFORM_XLIB_KHR
VULKAN_SOURCES += $(VULKAN_WSI_X11_FILES)
VULKAN_LIB_DEPS += $(XCB_DRI3_LIBS)
endif
if HAVE_PLATFORM_WAYLAND
AM_CPPFLAGS += \
$(WAYLAND_CLIENT_CFLAGS) \
-DVK_USE_PLATFORM_WAYLAND_KHR
VULKAN_SOURCES += $(VULKAN_WSI_WAYLAND_FILES)
VULKAN_LIB_DEPS += \
$(WAYLAND_CLIENT_LIBS)
endif
if HAVE_PLATFORM_ANDROID
AM_CPPFLAGS += $(ANDROID_CPPFLAGS)
AM_CFLAGS += $(ANDROID_CFLAGS)
VULKAN_LIB_DEPS += $(ANDROID_LIBS)
VULKAN_SOURCES += $(VULKAN_ANDROID_FILES)
endif
noinst_LTLIBRARIES = libvulkan_common.la
libvulkan_common_la_SOURCES = $(VULKAN_SOURCES)
nodist_EXTRA_libvulkan_radeon_la_SOURCES = dummy.cpp
libvulkan_radeon_la_SOURCES = $(VULKAN_GEM_FILES)
vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
tu_entrypoints.c: tu_entrypoints_gen.py tu_extensions.py $(vulkan_api_xml)
$(MKDIR_GEN)
$(AM_V_GEN)$(PYTHON2) $(srcdir)/tu_entrypoints_gen.py \
--xml $(vulkan_api_xml) \
--outdir $(builddir)
tu_entrypoints.h: tu_entrypoints.c
tu_extensions.c: tu_extensions.py \
$(vulkan_api_xml)
$(MKDIR_GEN)
$(AM_V_GEN)$(PYTHON2) $(srcdir)/tu_extensions.py \
--xml $(vulkan_api_xml) \
--out-c tu_extensions.c \
--out-h tu_extensions.h
tu_extensions.h: tu_extensions.c
vk_format_table.c: vk_format_table.py \
vk_format_parse.py \
vk_format_layout.csv
$(PYTHON2) $(srcdir)/vk_format_table.py $(srcdir)/vk_format_layout.csv > $@
BUILT_SOURCES = $(VULKAN_GENERATED_FILES)
CLEANFILES = $(BUILT_SOURCES) dev_icd.json radeon_icd.@host_cpu@.json
EXTRA_DIST = \
$(top_srcdir)/include/vulkan/vk_icd.h \
tu_entrypoints_gen.py \
tu_extensions.py \
tu_icd.py \
vk_format_layout.csv \
vk_format_parse.py \
vk_format_table.py \
meson.build
libvulkan_radeon_la_LIBADD = $(VULKAN_LIB_DEPS)
libvulkan_radeon_la_LDFLAGS = \
-shared \
-module \
-no-undefined \
-avoid-version \
$(BSYMBOLIC) \
$(LLVM_LDFLAGS) \
$(GC_SECTIONS) \
$(LD_NO_UNDEFINED)
icdconfdir = @VULKAN_ICD_INSTALL_DIR@
icdconf_DATA = radeon_icd.@host_cpu@.json
# The following is used for development purposes, by setting VK_ICD_FILENAMES.
noinst_DATA = dev_icd.json
dev_icd.json : tu_extensions.py tu_icd.py
$(AM_V_GEN)$(PYTHON2) $(srcdir)/tu_icd.py \
--lib-path="${abs_top_builddir}/${LIB_DIR}" --out $@
radeon_icd.@host_cpu@.json : tu_extensions.py tu_icd.py
$(AM_V_GEN)$(PYTHON2) $(srcdir)/tu_icd.py \
--lib-path="${libdir}" --out $@
include $(top_srcdir)/install-lib-links.mk

View File

@ -0,0 +1,93 @@
# Copyright © 2016 Red Hat
#
# 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 (including the next
# paragraph) 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.
TU_WS_AMDGPU_FILES := \
winsys/amdgpu/tu_amdgpu_bo.c \
winsys/amdgpu/tu_amdgpu_bo.h \
winsys/amdgpu/tu_amdgpu_cs.c \
winsys/amdgpu/tu_amdgpu_cs.h \
winsys/amdgpu/tu_amdgpu_surface.c \
winsys/amdgpu/tu_amdgpu_surface.h \
winsys/amdgpu/tu_amdgpu_winsys.c \
winsys/amdgpu/tu_amdgpu_winsys.h \
winsys/amdgpu/tu_amdgpu_winsys_public.h
VULKAN_FILES := \
tu_cmd_buffer.c \
tu_cs.h \
tu_debug.c \
tu_debug.h \
tu_device.c \
tu_descriptor_set.c \
tu_descriptor_set.h \
tu_formats.c \
tu_image.c \
tu_meta.c \
tu_meta.h \
tu_meta_blit.c \
tu_meta_blit2d.c \
tu_meta_buffer.c \
tu_meta_bufimage.c \
tu_meta_clear.c \
tu_meta_copy.c \
tu_meta_decompress.c \
tu_meta_fast_clear.c \
tu_meta_resolve.c \
tu_meta_resolve_cs.c \
tu_meta_resolve_fs.c \
tu_nir_to_llvm.c \
tu_llvm_helper.cpp \
tu_pass.c \
tu_pipeline.c \
tu_pipeline_cache.c \
tu_private.h \
tu_radeon_winsys.h \
tu_shader.c \
tu_shader_info.c \
tu_shader.h \
tu_shader_helper.h \
tu_query.c \
tu_util.c \
tu_util.h \
tu_wsi.c \
si_cmd_buffer.c \
vk_format.h \
$(TU_WS_AMDGPU_FILES)
VULKAN_ANDROID_FILES := \
tu_android.c
VULKAN_WSI_WAYLAND_FILES := \
tu_wsi_wayland.c
VULKAN_WSI_X11_FILES := \
tu_wsi_x11.c
VULKAN_WSI_DISPLAY_FILES := \
tu_wsi_display.c
VULKAN_GENERATED_FILES := \
tu_entrypoints.c \
tu_entrypoints.h \
tu_extensions.c \
tu_extensions.h \
vk_format_table.c

View File

@ -0,0 +1,127 @@
# Copyright © 2017 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.
tu_entrypoints = custom_target(
'tu_entrypoints.[ch]',
input : ['tu_entrypoints_gen.py', vk_api_xml],
output : ['tu_entrypoints.h', 'tu_entrypoints.c'],
command : [
prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
meson.current_build_dir()
],
depend_files : files('tu_extensions.py'),
)
tu_extensions_c = custom_target(
'tu_extensions.c',
input : ['tu_extensions.py', vk_api_xml],
output : ['tu_extensions.c', 'tu_extensions.h'],
command : [
prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--out-c', '@OUTPUT0@',
'--out-h', '@OUTPUT1@'
],
)
vk_format_table_c = custom_target(
'vk_format_table.c',
input : ['vk_format_table.py', 'vk_format_layout.csv'],
output : 'vk_format_table.c',
command : [prog_python, '@INPUT@'],
depend_files : files('vk_format_parse.py'),
capture : true,
)
libtu_files = files(
'tu_cmd_buffer.c',
'tu_device.c',
'tu_descriptor_set.c',
'tu_descriptor_set.h',
'tu_formats.c',
'tu_image.c',
'tu_meta_blit.c',
'tu_meta_buffer.c',
'tu_meta_clear.c',
'tu_meta_copy.c',
'tu_meta_resolve.c',
'tu_pass.c',
'tu_pipeline.c',
'tu_pipeline_cache.c',
'tu_private.h',
'tu_query.c',
'tu_util.c',
'tu_util.h',
'vk_format.h',
)
tu_deps = []
tu_flags = []
libvulkan_freedreno = shared_library(
'vulkan_freedreno',
[libtu_files, tu_entrypoints, tu_extensions_c, vk_format_table_c],
include_directories : [
inc_common, inc_compiler, inc_vulkan_util,
],
link_with : [
libvulkan_util,
libmesa_util,
],
dependencies : [
dep_dl,
dep_elf,
dep_libdrm,
dep_llvm,
dep_m,
dep_thread,
dep_valgrind,
idep_nir,
],
c_args : [c_vis_args, no_override_init_args, tu_flags],
link_args : [ld_args_bsymbolic, ld_args_gc_sections],
install : true,
)
freedreno_icd = custom_target(
'freedreno_icd',
input : 'tu_icd.py',
output : 'freedreno_icd.@0@.json'.format(host_machine.cpu()),
command : [
prog_python, '@INPUT@',
'--lib-path', join_paths(get_option('prefix'), get_option('libdir')),
'--out', '@OUTPUT@',
],
depend_files : files('tu_extensions.py'),
build_by_default : true,
install_dir : with_vulkan_icd_dir,
install : true,
)
tu_dev_icd = custom_target(
'tu_dev_icd',
input : 'tu_icd.py',
output : 'dev_icd.json',
command : [
prog_python, '@INPUT@', '--lib-path', meson.current_build_dir(),
'--out', '@OUTPUT@'
],
depend_files : files('tu_extensions.py'),
build_by_default : true,
install : false,
)

View File

@ -0,0 +1,390 @@
/*
* Copyright © 2017, Google Inc.
*
* 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 (including the next
* paragraph) 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.
*/
#include <hardware/gralloc.h>
#include <hardware/hardware.h>
#include <hardware/hwvulkan.h>
#include <libsync.h>
#include <vulkan/vk_android_native_buffer.h>
#include <vulkan/vk_icd.h>
#include "tu_private.h"
static int
tu_hal_open(const struct hw_module_t *mod,
const char *id,
struct hw_device_t **dev);
static int
tu_hal_close(struct hw_device_t *dev);
static void UNUSED
static_asserts(void)
{
STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC);
}
PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
.common =
{
.tag = HARDWARE_MODULE_TAG,
.module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
.id = HWVULKAN_HARDWARE_MODULE_ID,
.name = "AMD Vulkan HAL",
.author = "Google",
.methods =
&(hw_module_methods_t){
.open = tu_hal_open,
},
},
};
/* If any bits in test_mask are set, then unset them and return true. */
static inline bool
unmask32(uint32_t *inout_mask, uint32_t test_mask)
{
uint32_t orig_mask = *inout_mask;
*inout_mask &= ~test_mask;
return *inout_mask != orig_mask;
}
static int
tu_hal_open(const struct hw_module_t *mod,
const char *id,
struct hw_device_t **dev)
{
assert(mod == &HAL_MODULE_INFO_SYM.common);
assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
hwvulkan_device_t *hal_dev = malloc(sizeof(*hal_dev));
if (!hal_dev)
return -1;
*hal_dev = (hwvulkan_device_t){
.common =
{
.tag = HARDWARE_DEVICE_TAG,
.version = HWVULKAN_DEVICE_API_VERSION_0_1,
.module = &HAL_MODULE_INFO_SYM.common,
.close = tu_hal_close,
},
.EnumerateInstanceExtensionProperties =
tu_EnumerateInstanceExtensionProperties,
.CreateInstance = tu_CreateInstance,
.GetInstanceProcAddr = tu_GetInstanceProcAddr,
};
*dev = &hal_dev->common;
return 0;
}
static int
tu_hal_close(struct hw_device_t *dev)
{
/* hwvulkan.h claims that hw_device_t::close() is never called. */
return -1;
}
VkResult
tu_image_from_gralloc(VkDevice device_h,
const VkImageCreateInfo *base_info,
const VkNativeBufferANDROID *gralloc_info,
const VkAllocationCallbacks *alloc,
VkImage *out_image_h)
{
TU_FROM_HANDLE(tu_device, device, device_h);
VkImage image_h = VK_NULL_HANDLE;
struct tu_image *image = NULL;
struct tu_bo *bo = NULL;
VkResult result;
result = tu_image_create(
device_h,
&(struct tu_image_create_info){
.vk_info = base_info, .scanout = true, .no_metadata_planes = true },
alloc,
&image_h);
if (result != VK_SUCCESS)
return result;
if (gralloc_info->handle->numFds != 1) {
return vk_errorf(device->instance,
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR,
"VkNativeBufferANDROID::handle::numFds is %d, "
"expected 1",
gralloc_info->handle->numFds);
}
/* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
* must exceed that of the gralloc handle, and we do not own the gralloc
* handle.
*/
int dma_buf = gralloc_info->handle->data[0];
image = tu_image_from_handle(image_h);
VkDeviceMemory memory_h;
const VkMemoryDedicatedAllocateInfoKHR ded_alloc = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
.pNext = NULL,
.buffer = VK_NULL_HANDLE,
.image = image_h
};
const VkImportMemoryFdInfoKHR import_info = {
.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
.pNext = &ded_alloc,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR,
.fd = dup(dma_buf),
};
/* Find the first VRAM memory type, or GART for PRIME images. */
int memory_type_index = -1;
for (int i = 0;
i < device->physical_device->memory_properties.memoryTypeCount;
++i) {
bool is_local =
!!(device->physical_device->memory_properties.memoryTypes[i]
.propertyFlags &
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (is_local) {
memory_type_index = i;
break;
}
}
/* fallback */
if (memory_type_index == -1)
memory_type_index = 0;
result =
tu_AllocateMemory(device_h,
&(VkMemoryAllocateInfo){
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &import_info,
.allocationSize = image->size,
.memoryTypeIndex = memory_type_index,
},
alloc,
&memory_h);
if (result != VK_SUCCESS)
goto fail_create_image;
tu_BindImageMemory(device_h, image_h, memory_h, 0);
image->owned_memory = memory_h;
/* Don't clobber the out-parameter until success is certain. */
*out_image_h = image_h;
return VK_SUCCESS;
fail_create_image:
fail_size:
tu_DestroyImage(device_h, image_h, alloc);
return result;
}
VkResult
tu_GetSwapchainGrallocUsageANDROID(VkDevice device_h,
VkFormat format,
VkImageUsageFlags imageUsage,
int *grallocUsage)
{
TU_FROM_HANDLE(tu_device, device, device_h);
struct tu_physical_device *phys_dev = device->physical_device;
VkPhysicalDevice phys_dev_h = tu_physical_device_to_handle(phys_dev);
VkResult result;
*grallocUsage = 0;
/* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
* returned to applications via
* VkSurfaceCapabilitiesKHR::supportedUsageFlags.
* The relevant code in libvulkan/swapchain.cpp contains this fun comment:
*
* TODO(jessehall): I think these are right, but haven't thought hard
* about it. Do we need to query the driver for support of any of
* these?
*
* Any disagreement between this function and the hardcoded
* VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
* dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
*/
const VkPhysicalDeviceImageFormatInfo2KHR image_format_info = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
.format = format,
.type = VK_IMAGE_TYPE_2D,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = imageUsage,
};
VkImageFormatProperties2KHR image_format_props = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR,
};
/* Check that requested format and usage are supported. */
result = tu_GetPhysicalDeviceImageFormatProperties2(
phys_dev_h, &image_format_info, &image_format_props);
if (result != VK_SUCCESS) {
return vk_errorf(device->instance,
result,
"tu_GetPhysicalDeviceImageFormatProperties2 failed "
"inside %s",
__func__);
}
if (unmask32(&imageUsage,
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
*grallocUsage |= GRALLOC_USAGE_HW_RENDER;
if (unmask32(&imageUsage,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
*grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
/* All VkImageUsageFlags not explicitly checked here are unsupported for
* gralloc swapchains.
*/
if (imageUsage != 0) {
return vk_errorf(device->instance,
VK_ERROR_FORMAT_NOT_SUPPORTED,
"unsupported VkImageUsageFlags(0x%x) for gralloc "
"swapchain",
imageUsage);
}
/*
* FINISHME: Advertise all display-supported formats. Mostly
* DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
* what we need for 30-bit colors.
*/
if (format == VK_FORMAT_B8G8R8A8_UNORM ||
format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
*grallocUsage |= GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER |
GRALLOC_USAGE_EXTERNAL_DISP;
}
if (*grallocUsage == 0)
return VK_ERROR_FORMAT_NOT_SUPPORTED;
return VK_SUCCESS;
}
VkResult
tu_AcquireImageANDROID(VkDevice device,
VkImage image_h,
int nativeFenceFd,
VkSemaphore semaphore,
VkFence fence)
{
VkResult semaphore_result = VK_SUCCESS, fence_result = VK_SUCCESS;
if (semaphore != VK_NULL_HANDLE) {
int semaphore_fd =
nativeFenceFd >= 0 ? dup(nativeFenceFd) : nativeFenceFd;
semaphore_result = tu_ImportSemaphoreFdKHR(
device,
&(VkImportSemaphoreFdInfoKHR){
.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,
.fd = semaphore_fd,
.semaphore = semaphore,
});
}
if (fence != VK_NULL_HANDLE) {
int fence_fd = nativeFenceFd >= 0 ? dup(nativeFenceFd) : nativeFenceFd;
fence_result = tu_ImportFenceFdKHR(
device,
&(VkImportFenceFdInfoKHR){
.sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
.flags = VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,
.fd = fence_fd,
.fence = fence,
});
}
close(nativeFenceFd);
if (semaphore_result != VK_SUCCESS)
return semaphore_result;
return fence_result;
}
VkResult
tu_QueueSignalReleaseImageANDROID(VkQueue _queue,
uint32_t waitSemaphoreCount,
const VkSemaphore *pWaitSemaphores,
VkImage image,
int *pNativeFenceFd)
{
TU_FROM_HANDLE(tu_queue, queue, _queue);
VkResult result = VK_SUCCESS;
if (waitSemaphoreCount == 0) {
if (pNativeFenceFd)
*pNativeFenceFd = -1;
return VK_SUCCESS;
}
int fd = -1;
for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
int tmp_fd;
result = tu_GetSemaphoreFdKHR(
tu_device_to_handle(queue->device),
&(VkSemaphoreGetFdInfoKHR){
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR,
.semaphore = pWaitSemaphores[i],
},
&tmp_fd);
if (result != VK_SUCCESS) {
if (fd >= 0)
close(fd);
return result;
}
if (fd < 0)
fd = tmp_fd;
else if (tmp_fd >= 0) {
sync_accumulate("tu", &fd, tmp_fd);
close(tmp_fd);
}
}
if (pNativeFenceFd) {
*pNativeFenceFd = fd;
} else if (fd >= 0) {
close(fd);
/* We still need to do the exports, to reset the semaphores, but
* otherwise we don't wait on them. */
}
return VK_SUCCESS;
}

View File

@ -0,0 +1,936 @@
/*
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* based in part on anv driver which is:
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
#include "vk_format.h"
const struct tu_dynamic_state default_dynamic_state = {
.viewport =
{
.count = 0,
},
.scissor =
{
.count = 0,
},
.line_width = 1.0f,
.depth_bias =
{
.bias = 0.0f,
.clamp = 0.0f,
.slope = 0.0f,
},
.blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
.depth_bounds =
{
.min = 0.0f,
.max = 1.0f,
},
.stencil_compare_mask =
{
.front = ~0u,
.back = ~0u,
},
.stencil_write_mask =
{
.front = ~0u,
.back = ~0u,
},
.stencil_reference =
{
.front = 0u,
.back = 0u,
},
};
static void
tu_bind_dynamic_state(struct tu_cmd_buffer *cmd_buffer,
const struct tu_dynamic_state *src)
{
struct tu_dynamic_state *dest = &cmd_buffer->state.dynamic;
uint32_t copy_mask = src->mask;
uint32_t dest_mask = 0;
/* Make sure to copy the number of viewports/scissors because they can
* only be specified at pipeline creation time.
*/
dest->viewport.count = src->viewport.count;
dest->scissor.count = src->scissor.count;
dest->discard_rectangle.count = src->discard_rectangle.count;
if (copy_mask & TU_DYNAMIC_VIEWPORT) {
if (memcmp(&dest->viewport.viewports,
&src->viewport.viewports,
src->viewport.count * sizeof(VkViewport))) {
typed_memcpy(dest->viewport.viewports,
src->viewport.viewports,
src->viewport.count);
dest_mask |= TU_DYNAMIC_VIEWPORT;
}
}
if (copy_mask & TU_DYNAMIC_SCISSOR) {
if (memcmp(&dest->scissor.scissors,
&src->scissor.scissors,
src->scissor.count * sizeof(VkRect2D))) {
typed_memcpy(
dest->scissor.scissors, src->scissor.scissors, src->scissor.count);
dest_mask |= TU_DYNAMIC_SCISSOR;
}
}
if (copy_mask & TU_DYNAMIC_LINE_WIDTH) {
if (dest->line_width != src->line_width) {
dest->line_width = src->line_width;
dest_mask |= TU_DYNAMIC_LINE_WIDTH;
}
}
if (copy_mask & TU_DYNAMIC_DEPTH_BIAS) {
if (memcmp(
&dest->depth_bias, &src->depth_bias, sizeof(src->depth_bias))) {
dest->depth_bias = src->depth_bias;
dest_mask |= TU_DYNAMIC_DEPTH_BIAS;
}
}
if (copy_mask & TU_DYNAMIC_BLEND_CONSTANTS) {
if (memcmp(&dest->blend_constants,
&src->blend_constants,
sizeof(src->blend_constants))) {
typed_memcpy(dest->blend_constants, src->blend_constants, 4);
dest_mask |= TU_DYNAMIC_BLEND_CONSTANTS;
}
}
if (copy_mask & TU_DYNAMIC_DEPTH_BOUNDS) {
if (memcmp(&dest->depth_bounds,
&src->depth_bounds,
sizeof(src->depth_bounds))) {
dest->depth_bounds = src->depth_bounds;
dest_mask |= TU_DYNAMIC_DEPTH_BOUNDS;
}
}
if (copy_mask & TU_DYNAMIC_STENCIL_COMPARE_MASK) {
if (memcmp(&dest->stencil_compare_mask,
&src->stencil_compare_mask,
sizeof(src->stencil_compare_mask))) {
dest->stencil_compare_mask = src->stencil_compare_mask;
dest_mask |= TU_DYNAMIC_STENCIL_COMPARE_MASK;
}
}
if (copy_mask & TU_DYNAMIC_STENCIL_WRITE_MASK) {
if (memcmp(&dest->stencil_write_mask,
&src->stencil_write_mask,
sizeof(src->stencil_write_mask))) {
dest->stencil_write_mask = src->stencil_write_mask;
dest_mask |= TU_DYNAMIC_STENCIL_WRITE_MASK;
}
}
if (copy_mask & TU_DYNAMIC_STENCIL_REFERENCE) {
if (memcmp(&dest->stencil_reference,
&src->stencil_reference,
sizeof(src->stencil_reference))) {
dest->stencil_reference = src->stencil_reference;
dest_mask |= TU_DYNAMIC_STENCIL_REFERENCE;
}
}
if (copy_mask & TU_DYNAMIC_DISCARD_RECTANGLE) {
if (memcmp(&dest->discard_rectangle.rectangles,
&src->discard_rectangle.rectangles,
src->discard_rectangle.count * sizeof(VkRect2D))) {
typed_memcpy(dest->discard_rectangle.rectangles,
src->discard_rectangle.rectangles,
src->discard_rectangle.count);
dest_mask |= TU_DYNAMIC_DISCARD_RECTANGLE;
}
}
}
static VkResult
tu_create_cmd_buffer(struct tu_device *device,
struct tu_cmd_pool *pool,
VkCommandBufferLevel level,
VkCommandBuffer *pCommandBuffer)
{
struct tu_cmd_buffer *cmd_buffer;
cmd_buffer = vk_zalloc(
&pool->alloc, sizeof(*cmd_buffer), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (cmd_buffer == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
cmd_buffer->device = device;
cmd_buffer->pool = pool;
cmd_buffer->level = level;
if (pool) {
list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
cmd_buffer->queue_family_index = pool->queue_family_index;
} else {
/* Init the pool_link so we can safely call list_del when we destroy
* the command buffer
*/
list_inithead(&cmd_buffer->pool_link);
cmd_buffer->queue_family_index = TU_QUEUE_GENERAL;
}
*pCommandBuffer = tu_cmd_buffer_to_handle(cmd_buffer);
list_inithead(&cmd_buffer->upload.list);
return VK_SUCCESS;
}
static void
tu_cmd_buffer_destroy(struct tu_cmd_buffer *cmd_buffer)
{
list_del(&cmd_buffer->pool_link);
for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++)
free(cmd_buffer->descriptors[i].push_set.set.mapped_ptr);
vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
}
static VkResult
tu_reset_cmd_buffer(struct tu_cmd_buffer *cmd_buffer)
{
cmd_buffer->record_result = VK_SUCCESS;
for (unsigned i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; i++) {
cmd_buffer->descriptors[i].dirty = 0;
cmd_buffer->descriptors[i].valid = 0;
cmd_buffer->descriptors[i].push_dirty = false;
}
cmd_buffer->status = TU_CMD_BUFFER_STATUS_INITIAL;
return cmd_buffer->record_result;
}
VkResult
tu_AllocateCommandBuffers(VkDevice _device,
const VkCommandBufferAllocateInfo *pAllocateInfo,
VkCommandBuffer *pCommandBuffers)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_cmd_pool, pool, pAllocateInfo->commandPool);
VkResult result = VK_SUCCESS;
uint32_t i;
for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
if (!list_empty(&pool->free_cmd_buffers)) {
struct tu_cmd_buffer *cmd_buffer = list_first_entry(
&pool->free_cmd_buffers, struct tu_cmd_buffer, pool_link);
list_del(&cmd_buffer->pool_link);
list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
result = tu_reset_cmd_buffer(cmd_buffer);
cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
cmd_buffer->level = pAllocateInfo->level;
pCommandBuffers[i] = tu_cmd_buffer_to_handle(cmd_buffer);
} else {
result = tu_create_cmd_buffer(
device, pool, pAllocateInfo->level, &pCommandBuffers[i]);
}
if (result != VK_SUCCESS)
break;
}
if (result != VK_SUCCESS) {
tu_FreeCommandBuffers(
_device, pAllocateInfo->commandPool, i, pCommandBuffers);
/* From the Vulkan 1.0.66 spec:
*
* "vkAllocateCommandBuffers can be used to create multiple
* command buffers. If the creation of any of those command
* buffers fails, the implementation must destroy all
* successfully created command buffer objects from this
* command, set all entries of the pCommandBuffers array to
* NULL and return the error."
*/
memset(pCommandBuffers,
0,
sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
}
return result;
}
void
tu_FreeCommandBuffers(VkDevice device,
VkCommandPool commandPool,
uint32_t commandBufferCount,
const VkCommandBuffer *pCommandBuffers)
{
for (uint32_t i = 0; i < commandBufferCount; i++) {
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
if (cmd_buffer) {
if (cmd_buffer->pool) {
list_del(&cmd_buffer->pool_link);
list_addtail(&cmd_buffer->pool_link,
&cmd_buffer->pool->free_cmd_buffers);
} else
tu_cmd_buffer_destroy(cmd_buffer);
}
}
}
VkResult
tu_ResetCommandBuffer(VkCommandBuffer commandBuffer,
VkCommandBufferResetFlags flags)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
return tu_reset_cmd_buffer(cmd_buffer);
}
VkResult
tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo *pBeginInfo)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
VkResult result = VK_SUCCESS;
if (cmd_buffer->status != TU_CMD_BUFFER_STATUS_INITIAL) {
/* If the command buffer has already been resetted with
* vkResetCommandBuffer, no need to do it again.
*/
result = tu_reset_cmd_buffer(cmd_buffer);
if (result != VK_SUCCESS)
return result;
}
memset(&cmd_buffer->state, 0, sizeof(cmd_buffer->state));
cmd_buffer->usage_flags = pBeginInfo->flags;
/* setup initial configuration into command buffer */
if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
switch (cmd_buffer->queue_family_index) {
case TU_QUEUE_GENERAL:
/* init */
break;
default:
break;
}
}
cmd_buffer->status = TU_CMD_BUFFER_STATUS_RECORDING;
return result;
}
void
tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer *pBuffers,
const VkDeviceSize *pOffsets)
{
}
void
tu_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
VkBuffer buffer,
VkDeviceSize offset,
VkIndexType indexType)
{
}
void
tu_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipelineLayout _layout,
uint32_t firstSet,
uint32_t descriptorSetCount,
const VkDescriptorSet *pDescriptorSets,
uint32_t dynamicOffsetCount,
const uint32_t *pDynamicOffsets)
{
}
void
tu_CmdPushConstants(VkCommandBuffer commandBuffer,
VkPipelineLayout layout,
VkShaderStageFlags stageFlags,
uint32_t offset,
uint32_t size,
const void *pValues)
{
}
VkResult
tu_EndCommandBuffer(VkCommandBuffer commandBuffer)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
cmd_buffer->status = TU_CMD_BUFFER_STATUS_EXECUTABLE;
return cmd_buffer->record_result;
}
void
tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipeline _pipeline)
{
}
void
tu_CmdSetViewport(VkCommandBuffer commandBuffer,
uint32_t firstViewport,
uint32_t viewportCount,
const VkViewport *pViewports)
{
}
void
tu_CmdSetScissor(VkCommandBuffer commandBuffer,
uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D *pScissors)
{
}
void
tu_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
{
}
void
tu_CmdSetDepthBias(VkCommandBuffer commandBuffer,
float depthBiasConstantFactor,
float depthBiasClamp,
float depthBiasSlopeFactor)
{
}
void
tu_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
const float blendConstants[4])
{
}
void
tu_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
float minDepthBounds,
float maxDepthBounds)
{
}
void
tu_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t compareMask)
{
}
void
tu_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t writeMask)
{
}
void
tu_CmdSetStencilReference(VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t reference)
{
}
void
tu_CmdExecuteCommands(VkCommandBuffer commandBuffer,
uint32_t commandBufferCount,
const VkCommandBuffer *pCmdBuffers)
{
}
VkResult
tu_CreateCommandPool(VkDevice _device,
const VkCommandPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkCommandPool *pCmdPool)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_cmd_pool *pool;
pool = vk_alloc2(&device->alloc,
pAllocator,
sizeof(*pool),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pool == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
if (pAllocator)
pool->alloc = *pAllocator;
else
pool->alloc = device->alloc;
list_inithead(&pool->cmd_buffers);
list_inithead(&pool->free_cmd_buffers);
pool->queue_family_index = pCreateInfo->queueFamilyIndex;
*pCmdPool = tu_cmd_pool_to_handle(pool);
return VK_SUCCESS;
}
void
tu_DestroyCommandPool(VkDevice _device,
VkCommandPool commandPool,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
if (!pool)
return;
list_for_each_entry_safe(
struct tu_cmd_buffer, cmd_buffer, &pool->cmd_buffers, pool_link)
{
tu_cmd_buffer_destroy(cmd_buffer);
}
list_for_each_entry_safe(
struct tu_cmd_buffer, cmd_buffer, &pool->free_cmd_buffers, pool_link)
{
tu_cmd_buffer_destroy(cmd_buffer);
}
vk_free2(&device->alloc, pAllocator, pool);
}
VkResult
tu_ResetCommandPool(VkDevice device,
VkCommandPool commandPool,
VkCommandPoolResetFlags flags)
{
TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
VkResult result;
list_for_each_entry(
struct tu_cmd_buffer, cmd_buffer, &pool->cmd_buffers, pool_link)
{
result = tu_reset_cmd_buffer(cmd_buffer);
if (result != VK_SUCCESS)
return result;
}
return VK_SUCCESS;
}
void
tu_TrimCommandPool(VkDevice device,
VkCommandPool commandPool,
VkCommandPoolTrimFlagsKHR flags)
{
TU_FROM_HANDLE(tu_cmd_pool, pool, commandPool);
if (!pool)
return;
list_for_each_entry_safe(
struct tu_cmd_buffer, cmd_buffer, &pool->free_cmd_buffers, pool_link)
{
tu_cmd_buffer_destroy(cmd_buffer);
}
}
void
tu_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo *pRenderPassBegin,
VkSubpassContents contents)
{
}
void
tu_CmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo *pRenderPassBeginInfo,
const VkSubpassBeginInfoKHR *pSubpassBeginInfo)
{
tu_CmdBeginRenderPass(
commandBuffer, pRenderPassBeginInfo, pSubpassBeginInfo->contents);
}
void
tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
{
}
void
tu_CmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
const VkSubpassEndInfoKHR *pSubpassEndInfo)
{
tu_CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
}
struct tu_draw_info
{
/**
* Number of vertices.
*/
uint32_t count;
/**
* Index of the first vertex.
*/
int32_t vertex_offset;
/**
* First instance id.
*/
uint32_t first_instance;
/**
* Number of instances.
*/
uint32_t instance_count;
/**
* First index (indexed draws only).
*/
uint32_t first_index;
/**
* Whether it's an indexed draw.
*/
bool indexed;
/**
* Indirect draw parameters resource.
*/
struct tu_buffer *indirect;
uint64_t indirect_offset;
uint32_t stride;
/**
* Draw count parameters resource.
*/
struct tu_buffer *count_buffer;
uint64_t count_buffer_offset;
};
static void
tu_draw(struct tu_cmd_buffer *cmd_buffer, const struct tu_draw_info *info)
{
}
void
tu_CmdDraw(VkCommandBuffer commandBuffer,
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
struct tu_draw_info info = {};
info.count = vertexCount;
info.instance_count = instanceCount;
info.first_instance = firstInstance;
info.vertex_offset = firstVertex;
tu_draw(cmd_buffer, &info);
}
void
tu_CmdDrawIndexed(VkCommandBuffer commandBuffer,
uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
uint32_t firstInstance)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
struct tu_draw_info info = {};
info.indexed = true;
info.count = indexCount;
info.instance_count = instanceCount;
info.first_index = firstIndex;
info.vertex_offset = vertexOffset;
info.first_instance = firstInstance;
tu_draw(cmd_buffer, &info);
}
void
tu_CmdDrawIndirect(VkCommandBuffer commandBuffer,
VkBuffer _buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
struct tu_draw_info info = {};
info.count = drawCount;
info.indirect = buffer;
info.indirect_offset = offset;
info.stride = stride;
tu_draw(cmd_buffer, &info);
}
void
tu_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
VkBuffer _buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
struct tu_draw_info info = {};
info.indexed = true;
info.count = drawCount;
info.indirect = buffer;
info.indirect_offset = offset;
info.stride = stride;
tu_draw(cmd_buffer, &info);
}
struct tu_dispatch_info
{
/**
* Determine the layout of the grid (in block units) to be used.
*/
uint32_t blocks[3];
/**
* A starting offset for the grid. If unaligned is set, the offset
* must still be aligned.
*/
uint32_t offsets[3];
/**
* Whether it's an unaligned compute dispatch.
*/
bool unaligned;
/**
* Indirect compute parameters resource.
*/
struct tu_buffer *indirect;
uint64_t indirect_offset;
};
static void
tu_dispatch(struct tu_cmd_buffer *cmd_buffer,
const struct tu_dispatch_info *info)
{
}
void
tu_CmdDispatchBase(VkCommandBuffer commandBuffer,
uint32_t base_x,
uint32_t base_y,
uint32_t base_z,
uint32_t x,
uint32_t y,
uint32_t z)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
struct tu_dispatch_info info = {};
info.blocks[0] = x;
info.blocks[1] = y;
info.blocks[2] = z;
info.offsets[0] = base_x;
info.offsets[1] = base_y;
info.offsets[2] = base_z;
tu_dispatch(cmd_buffer, &info);
}
void
tu_CmdDispatch(VkCommandBuffer commandBuffer,
uint32_t x,
uint32_t y,
uint32_t z)
{
tu_CmdDispatchBase(commandBuffer, 0, 0, 0, x, y, z);
}
void
tu_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
VkBuffer _buffer,
VkDeviceSize offset)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
struct tu_dispatch_info info = {};
info.indirect = buffer;
info.indirect_offset = offset;
tu_dispatch(cmd_buffer, &info);
}
void
tu_CmdEndRenderPass(VkCommandBuffer commandBuffer)
{
}
void
tu_CmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
const VkSubpassEndInfoKHR *pSubpassEndInfo)
{
tu_CmdEndRenderPass(commandBuffer);
}
struct tu_barrier_info
{
uint32_t eventCount;
const VkEvent *pEvents;
VkPipelineStageFlags srcStageMask;
};
static void
tu_barrier(struct tu_cmd_buffer *cmd_buffer,
uint32_t memoryBarrierCount,
const VkMemoryBarrier *pMemoryBarriers,
uint32_t bufferMemoryBarrierCount,
const VkBufferMemoryBarrier *pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier *pImageMemoryBarriers,
const struct tu_barrier_info *info)
{
}
void
tu_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags destStageMask,
VkBool32 byRegion,
uint32_t memoryBarrierCount,
const VkMemoryBarrier *pMemoryBarriers,
uint32_t bufferMemoryBarrierCount,
const VkBufferMemoryBarrier *pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier *pImageMemoryBarriers)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
struct tu_barrier_info info;
info.eventCount = 0;
info.pEvents = NULL;
info.srcStageMask = srcStageMask;
tu_barrier(cmd_buffer,
memoryBarrierCount,
pMemoryBarriers,
bufferMemoryBarrierCount,
pBufferMemoryBarriers,
imageMemoryBarrierCount,
pImageMemoryBarriers,
&info);
}
static void
write_event(struct tu_cmd_buffer *cmd_buffer,
struct tu_event *event,
VkPipelineStageFlags stageMask,
unsigned value)
{
}
void
tu_CmdSetEvent(VkCommandBuffer commandBuffer,
VkEvent _event,
VkPipelineStageFlags stageMask)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_event, event, _event);
write_event(cmd_buffer, event, stageMask, 1);
}
void
tu_CmdResetEvent(VkCommandBuffer commandBuffer,
VkEvent _event,
VkPipelineStageFlags stageMask)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_event, event, _event);
write_event(cmd_buffer, event, stageMask, 0);
}
void
tu_CmdWaitEvents(VkCommandBuffer commandBuffer,
uint32_t eventCount,
const VkEvent *pEvents,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
uint32_t memoryBarrierCount,
const VkMemoryBarrier *pMemoryBarriers,
uint32_t bufferMemoryBarrierCount,
const VkBufferMemoryBarrier *pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier *pImageMemoryBarriers)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
struct tu_barrier_info info;
info.eventCount = eventCount;
info.pEvents = pEvents;
info.srcStageMask = 0;
tu_barrier(cmd_buffer,
memoryBarrierCount,
pMemoryBarriers,
bufferMemoryBarrierCount,
pBufferMemoryBarriers,
imageMemoryBarrierCount,
pImageMemoryBarriers,
&info);
}
void
tu_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
{
/* No-op */
}

View File

@ -0,0 +1,565 @@
/*
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* 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 (including the next
* paragraph) 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.
*/
#include <assert.h>
#include <fcntl.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include "tu_private.h"
#include "util/mesa-sha1.h"
#include "vk_util.h"
static int
binding_compare(const void *av, const void *bv)
{
const VkDescriptorSetLayoutBinding *a =
(const VkDescriptorSetLayoutBinding *)av;
const VkDescriptorSetLayoutBinding *b =
(const VkDescriptorSetLayoutBinding *)bv;
return (a->binding < b->binding) ? -1 : (a->binding > b->binding) ? 1 : 0;
}
static VkDescriptorSetLayoutBinding *
create_sorted_bindings(const VkDescriptorSetLayoutBinding *bindings,
unsigned count)
{
VkDescriptorSetLayoutBinding *sorted_bindings =
malloc(count * sizeof(VkDescriptorSetLayoutBinding));
if (!sorted_bindings)
return NULL;
memcpy(
sorted_bindings, bindings, count * sizeof(VkDescriptorSetLayoutBinding));
qsort(sorted_bindings,
count,
sizeof(VkDescriptorSetLayoutBinding),
binding_compare);
return sorted_bindings;
}
VkResult
tu_CreateDescriptorSetLayout(
VkDevice _device,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDescriptorSetLayout *pSetLayout)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_descriptor_set_layout *set_layout;
assert(pCreateInfo->sType ==
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT *variable_flags =
vk_find_struct_const(pCreateInfo->pNext,
DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT);
uint32_t max_binding = 0;
uint32_t immutable_sampler_count = 0;
for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
max_binding = MAX2(max_binding, pCreateInfo->pBindings[j].binding);
if (pCreateInfo->pBindings[j].pImmutableSamplers)
immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
}
uint32_t samplers_offset =
sizeof(struct tu_descriptor_set_layout) +
(max_binding + 1) * sizeof(set_layout->binding[0]);
size_t size =
samplers_offset + immutable_sampler_count * 4 * sizeof(uint32_t);
set_layout = vk_alloc2(
&device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!set_layout)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
set_layout->flags = pCreateInfo->flags;
/* We just allocate all the samplers at the end of the struct */
uint32_t *samplers = (uint32_t *)&set_layout->binding[max_binding + 1];
VkDescriptorSetLayoutBinding *bindings =
create_sorted_bindings(pCreateInfo->pBindings, pCreateInfo->bindingCount);
if (!bindings) {
vk_free2(&device->alloc, pAllocator, set_layout);
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
set_layout->binding_count = max_binding + 1;
set_layout->shader_stages = 0;
set_layout->dynamic_shader_stages = 0;
set_layout->has_immutable_samplers = false;
set_layout->size = 0;
memset(
set_layout->binding, 0, size - sizeof(struct tu_descriptor_set_layout));
uint32_t buffer_count = 0;
uint32_t dynamic_offset_count = 0;
for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
const VkDescriptorSetLayoutBinding *binding = bindings + j;
uint32_t b = binding->binding;
uint32_t alignment;
unsigned binding_buffer_count = 0;
switch (binding->descriptorType) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
assert(!(pCreateInfo->flags &
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
set_layout->binding[b].dynamic_offset_count = 1;
set_layout->dynamic_shader_stages |= binding->stageFlags;
set_layout->binding[b].size = 0;
binding_buffer_count = 1;
alignment = 1;
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
set_layout->binding[b].size = 16;
binding_buffer_count = 1;
alignment = 16;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
/* main descriptor + fmask descriptor */
set_layout->binding[b].size = 64;
binding_buffer_count = 1;
alignment = 32;
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
/* main descriptor + fmask descriptor + sampler */
set_layout->binding[b].size = 96;
binding_buffer_count = 1;
alignment = 32;
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
set_layout->binding[b].size = 16;
alignment = 16;
break;
default:
unreachable("unknown descriptor type\n");
break;
}
set_layout->size = align(set_layout->size, alignment);
set_layout->binding[b].type = binding->descriptorType;
set_layout->binding[b].array_size = binding->descriptorCount;
set_layout->binding[b].offset = set_layout->size;
set_layout->binding[b].buffer_offset = buffer_count;
set_layout->binding[b].dynamic_offset_offset = dynamic_offset_count;
if (variable_flags && binding->binding < variable_flags->bindingCount &&
(variable_flags->pBindingFlags[binding->binding] &
VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)) {
assert(!binding->pImmutableSamplers); /* Terribly ill defined how many
samplers are valid */
assert(binding->binding == max_binding);
set_layout->has_variable_descriptors = true;
}
if (binding->pImmutableSamplers) {
set_layout->binding[b].immutable_samplers_offset = samplers_offset;
set_layout->has_immutable_samplers = true;
}
set_layout->size +=
binding->descriptorCount * set_layout->binding[b].size;
buffer_count += binding->descriptorCount * binding_buffer_count;
dynamic_offset_count +=
binding->descriptorCount * set_layout->binding[b].dynamic_offset_count;
set_layout->shader_stages |= binding->stageFlags;
}
free(bindings);
set_layout->buffer_count = buffer_count;
set_layout->dynamic_offset_count = dynamic_offset_count;
*pSetLayout = tu_descriptor_set_layout_to_handle(set_layout);
return VK_SUCCESS;
}
void
tu_DestroyDescriptorSetLayout(VkDevice _device,
VkDescriptorSetLayout _set_layout,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_descriptor_set_layout, set_layout, _set_layout);
if (!set_layout)
return;
vk_free2(&device->alloc, pAllocator, set_layout);
}
void
tu_GetDescriptorSetLayoutSupport(
VkDevice device,
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
VkDescriptorSetLayoutSupport *pSupport)
{
VkDescriptorSetLayoutBinding *bindings =
create_sorted_bindings(pCreateInfo->pBindings, pCreateInfo->bindingCount);
if (!bindings) {
pSupport->supported = false;
return;
}
const VkDescriptorSetLayoutBindingFlagsCreateInfoEXT *variable_flags =
vk_find_struct_const(pCreateInfo->pNext,
DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT);
VkDescriptorSetVariableDescriptorCountLayoutSupportEXT *variable_count =
vk_find_struct(
(void *)pCreateInfo->pNext,
DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT);
if (variable_count) {
variable_count->maxVariableDescriptorCount = 0;
}
bool supported = true;
uint64_t size = 0;
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
const VkDescriptorSetLayoutBinding *binding = bindings + i;
uint64_t descriptor_size = 0;
uint64_t descriptor_alignment = 1;
switch (binding->descriptorType) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
descriptor_size = 16;
descriptor_alignment = 16;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
descriptor_size = 64;
descriptor_alignment = 32;
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
descriptor_size = 96;
descriptor_alignment = 32;
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
descriptor_size = 16;
descriptor_alignment = 16;
break;
default:
unreachable("unknown descriptor type\n");
break;
}
if (size && !align_u64(size, descriptor_alignment)) {
supported = false;
}
size = align_u64(size, descriptor_alignment);
uint64_t max_count = UINT64_MAX;
if (descriptor_size)
max_count = (UINT64_MAX - size) / descriptor_size;
if (max_count < binding->descriptorCount) {
supported = false;
}
if (variable_flags && binding->binding < variable_flags->bindingCount &&
variable_count &&
(variable_flags->pBindingFlags[binding->binding] &
VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)) {
variable_count->maxVariableDescriptorCount =
MIN2(UINT32_MAX, max_count);
}
size += binding->descriptorCount * descriptor_size;
}
free(bindings);
pSupport->supported = supported;
}
/*
* Pipeline layouts. These have nothing to do with the pipeline. They are
* just multiple descriptor set layouts pasted together.
*/
VkResult
tu_CreatePipelineLayout(VkDevice _device,
const VkPipelineLayoutCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkPipelineLayout *pPipelineLayout)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_pipeline_layout *layout;
struct mesa_sha1 ctx;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
layout = vk_alloc2(&device->alloc,
pAllocator,
sizeof(*layout),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (layout == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
layout->num_sets = pCreateInfo->setLayoutCount;
unsigned dynamic_offset_count = 0;
_mesa_sha1_init(&ctx);
for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
TU_FROM_HANDLE(
tu_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[set]);
layout->set[set].layout = set_layout;
layout->set[set].dynamic_offset_start = dynamic_offset_count;
for (uint32_t b = 0; b < set_layout->binding_count; b++) {
dynamic_offset_count += set_layout->binding[b].array_size *
set_layout->binding[b].dynamic_offset_count;
if (set_layout->binding[b].immutable_samplers_offset)
_mesa_sha1_update(
&ctx,
tu_immutable_samplers(set_layout, set_layout->binding + b),
set_layout->binding[b].array_size * 4 * sizeof(uint32_t));
}
_mesa_sha1_update(&ctx,
set_layout->binding,
sizeof(set_layout->binding[0]) *
set_layout->binding_count);
}
layout->dynamic_offset_count = dynamic_offset_count;
layout->push_constant_size = 0;
for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i;
layout->push_constant_size =
MAX2(layout->push_constant_size, range->offset + range->size);
}
layout->push_constant_size = align(layout->push_constant_size, 16);
_mesa_sha1_update(
&ctx, &layout->push_constant_size, sizeof(layout->push_constant_size));
_mesa_sha1_final(&ctx, layout->sha1);
*pPipelineLayout = tu_pipeline_layout_to_handle(layout);
return VK_SUCCESS;
}
void
tu_DestroyPipelineLayout(VkDevice _device,
VkPipelineLayout _pipelineLayout,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_pipeline_layout, pipeline_layout, _pipelineLayout);
if (!pipeline_layout)
return;
vk_free2(&device->alloc, pAllocator, pipeline_layout);
}
#define EMPTY 1
VkResult
tu_CreateDescriptorPool(VkDevice _device,
const VkDescriptorPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDescriptorPool *pDescriptorPool)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_descriptor_pool *pool;
return VK_SUCCESS;
}
void
tu_DestroyDescriptorPool(VkDevice _device,
VkDescriptorPool _pool,
const VkAllocationCallbacks *pAllocator)
{
}
VkResult
tu_ResetDescriptorPool(VkDevice _device,
VkDescriptorPool descriptorPool,
VkDescriptorPoolResetFlags flags)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_descriptor_pool, pool, descriptorPool);
return VK_SUCCESS;
}
VkResult
tu_AllocateDescriptorSets(VkDevice _device,
const VkDescriptorSetAllocateInfo *pAllocateInfo,
VkDescriptorSet *pDescriptorSets)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_descriptor_pool, pool, pAllocateInfo->descriptorPool);
return VK_SUCCESS;
}
VkResult
tu_FreeDescriptorSets(VkDevice _device,
VkDescriptorPool descriptorPool,
uint32_t count,
const VkDescriptorSet *pDescriptorSets)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_descriptor_pool, pool, descriptorPool);
return VK_SUCCESS;
}
void
tu_update_descriptor_sets(struct tu_device *device,
struct tu_cmd_buffer *cmd_buffer,
VkDescriptorSet dstSetOverride,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet *pDescriptorWrites,
uint32_t descriptorCopyCount,
const VkCopyDescriptorSet *pDescriptorCopies)
{
}
void
tu_UpdateDescriptorSets(VkDevice _device,
uint32_t descriptorWriteCount,
const VkWriteDescriptorSet *pDescriptorWrites,
uint32_t descriptorCopyCount,
const VkCopyDescriptorSet *pDescriptorCopies)
{
TU_FROM_HANDLE(tu_device, device, _device);
tu_update_descriptor_sets(device,
NULL,
VK_NULL_HANDLE,
descriptorWriteCount,
pDescriptorWrites,
descriptorCopyCount,
pDescriptorCopies);
}
VkResult
tu_CreateDescriptorUpdateTemplate(
VkDevice _device,
const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(
tu_descriptor_set_layout, set_layout, pCreateInfo->descriptorSetLayout);
const uint32_t entry_count = pCreateInfo->descriptorUpdateEntryCount;
const size_t size =
sizeof(struct tu_descriptor_update_template) +
sizeof(struct tu_descriptor_update_template_entry) * entry_count;
struct tu_descriptor_update_template *templ;
uint32_t i;
templ = vk_alloc2(
&device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!templ)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
*pDescriptorUpdateTemplate = tu_descriptor_update_template_to_handle(templ);
return VK_SUCCESS;
}
void
tu_DestroyDescriptorUpdateTemplate(
VkDevice _device,
VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(
tu_descriptor_update_template, templ, descriptorUpdateTemplate);
if (!templ)
return;
vk_free2(&device->alloc, pAllocator, templ);
}
void
tu_update_descriptor_set_with_template(
struct tu_device *device,
struct tu_cmd_buffer *cmd_buffer,
struct tu_descriptor_set *set,
VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
const void *pData)
{
TU_FROM_HANDLE(
tu_descriptor_update_template, templ, descriptorUpdateTemplate);
}
void
tu_UpdateDescriptorSetWithTemplate(
VkDevice _device,
VkDescriptorSet descriptorSet,
VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
const void *pData)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_descriptor_set, set, descriptorSet);
tu_update_descriptor_set_with_template(
device, NULL, set, descriptorUpdateTemplate, pData);
}
VkResult
tu_CreateSamplerYcbcrConversion(
VkDevice device,
const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSamplerYcbcrConversion *pYcbcrConversion)
{
*pYcbcrConversion = VK_NULL_HANDLE;
return VK_SUCCESS;
}
void
tu_DestroySamplerYcbcrConversion(VkDevice device,
VkSamplerYcbcrConversion ycbcrConversion,
const VkAllocationCallbacks *pAllocator)
{
/* Do nothing. */
}

View File

@ -0,0 +1,102 @@
/*
* Copyright © 2016 Bas Nieuwenhuizen
*
* 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 (including the next
* paragraph) 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.
*/
#ifndef TU_DESCRIPTOR_SET_H
#define TU_DESCRIPTOR_SET_H
#include <vulkan/vulkan.h>
#define MAX_SETS 32
struct tu_descriptor_set_binding_layout
{
VkDescriptorType type;
/* Number of array elements in this binding */
uint32_t array_size;
uint32_t offset;
uint32_t buffer_offset;
uint16_t dynamic_offset_offset;
uint16_t dynamic_offset_count;
/* redundant with the type, each for a single array element */
uint32_t size;
/* Offset in the tu_descriptor_set_layout of the immutable samplers, or 0
* if there are no immutable samplers. */
uint32_t immutable_samplers_offset;
};
struct tu_descriptor_set_layout
{
/* The create flags for this descriptor set layout */
VkDescriptorSetLayoutCreateFlags flags;
/* Number of bindings in this descriptor set */
uint32_t binding_count;
/* Total size of the descriptor set with room for all array entries */
uint32_t size;
/* Shader stages affected by this descriptor set */
uint16_t shader_stages;
uint16_t dynamic_shader_stages;
/* Number of buffers in this descriptor set */
uint32_t buffer_count;
/* Number of dynamic offsets used by this descriptor set */
uint16_t dynamic_offset_count;
bool has_immutable_samplers;
bool has_variable_descriptors;
/* Bindings in this descriptor set */
struct tu_descriptor_set_binding_layout binding[0];
};
struct tu_pipeline_layout
{
struct
{
struct tu_descriptor_set_layout *layout;
uint32_t size;
uint32_t dynamic_offset_start;
} set[MAX_SETS];
uint32_t num_sets;
uint32_t push_constant_size;
uint32_t dynamic_offset_count;
unsigned char sha1[20];
};
static inline const uint32_t *
tu_immutable_samplers(const struct tu_descriptor_set_layout *set,
const struct tu_descriptor_set_binding_layout *binding)
{
return (const uint32_t *)((const char *)set +
binding->immutable_samplers_offset);
}
#endif /* TU_DESCRIPTOR_SET_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,506 @@
# coding=utf-8
#
# Copyright © 2015, 2017 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 (including the next
# paragraph) 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.
#
import argparse
import functools
import math
import os
import xml.etree.cElementTree as et
from collections import OrderedDict, namedtuple
from mako.template import Template
from tu_extensions import VkVersion, MAX_API_VERSION, EXTENSIONS
# We generate a static hash table for entry point lookup
# (vkGetProcAddress). We use a linear congruential generator for our hash
# function and a power-of-two size table. The prime numbers are determined
# experimentally.
# We currently don't use layers in tu, but keeping the ability for anv
# anyways, so we can use it for device groups.
LAYERS = [
'tu'
]
TEMPLATE_H = Template("""\
/* This file generated from ${filename}, don't edit directly. */
struct tu_dispatch_table {
union {
void *entrypoints[${len(entrypoints)}];
struct {
% for e in entrypoints:
% if e.guard is not None:
#ifdef ${e.guard}
PFN_${e.name} ${e.name};
#else
void *${e.name};
# endif
% else:
PFN_${e.name} ${e.name};
% endif
% endfor
};
};
};
% for e in entrypoints:
% if e.alias:
<% continue %>
% endif
% if e.guard is not None:
#ifdef ${e.guard}
% endif
% for layer in LAYERS:
${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()});
% endfor
% if e.guard is not None:
#endif // ${e.guard}
% endif
% endfor
""", output_encoding='utf-8')
TEMPLATE_C = Template(u"""\
/*
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
/* This file generated from ${filename}, don't edit directly. */
#include "tu_private.h"
struct string_map_entry {
uint32_t name;
uint32_t hash;
uint32_t num;
};
/* We use a big string constant to avoid lots of relocations from the entry
* point table to lots of little strings. The entries in the entry point table
* store the index into this big string.
*/
static const char strings[] =
% for s in strmap.sorted_strings:
"${s.string}\\0"
% endfor
;
static const struct string_map_entry string_map_entries[] = {
% for s in strmap.sorted_strings:
{ ${s.offset}, ${'{:0=#8x}'.format(s.hash)}, ${s.num} }, /* ${s.string} */
% endfor
};
/* Hash table stats:
* size ${len(strmap.sorted_strings)} entries
* collisions entries:
% for i in range(10):
* ${i}${'+' if i == 9 else ' '} ${strmap.collisions[i]}
% endfor
*/
#define none 0xffff
static const uint16_t string_map[${strmap.hash_size}] = {
% for e in strmap.mapping:
${ '{:0=#6x}'.format(e) if e >= 0 else 'none' },
% endfor
};
/* Weak aliases for all potential implementations. These will resolve to
* NULL if they're not defined, which lets the resolve_entrypoint() function
* either pick the correct entry point.
*/
% for layer in LAYERS:
% for e in entrypoints:
% if e.alias:
<% continue %>
% endif
% if e.guard is not None:
#ifdef ${e.guard}
% endif
${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak));
% if e.guard is not None:
#endif // ${e.guard}
% endif
% endfor
const struct tu_dispatch_table ${layer}_layer = {
% for e in entrypoints:
% if e.guard is not None:
#ifdef ${e.guard}
% endif
.${e.name} = ${e.prefixed_name(layer)},
% if e.guard is not None:
#endif // ${e.guard}
% endif
% endfor
};
% endfor
static void * __attribute__ ((noinline))
tu_resolve_entrypoint(uint32_t index)
{
return tu_layer.entrypoints[index];
}
/** Return true if the core version or extension in which the given entrypoint
* is defined is enabled.
*
* If instance is NULL, we only allow the 3 commands explicitly allowed by the vk
* spec.
*
* If device is NULL, all device extensions are considered enabled.
*/
static bool
tu_entrypoint_is_enabled(int index, uint32_t core_version,
const struct tu_instance_extension_table *instance,
const struct tu_device_extension_table *device)
{
switch (index) {
% for e in entrypoints:
case ${e.num}:
% if not e.device_command:
if (device) return false;
% endif
% if e.name == 'vkCreateInstance' or e.name == 'vkEnumerateInstanceExtensionProperties' or e.name == 'vkEnumerateInstanceLayerProperties' or e.name == 'vkEnumerateInstanceVersion':
return !device;
% elif e.core_version:
return instance && ${e.core_version.c_vk_version()} <= core_version;
% elif e.extensions:
% for ext in e.extensions:
% if ext.type == 'instance':
if (instance && instance->${ext.name[3:]}) return true;
% else:
if (instance && (!device || device->${ext.name[3:]})) return true;
% endif
%endfor
return false;
% else:
return instance;
% endif
% endfor
default:
return false;
}
}
static int
tu_lookup_entrypoint(const char *name)
{
static const uint32_t prime_factor = ${strmap.prime_factor};
static const uint32_t prime_step = ${strmap.prime_step};
const struct string_map_entry *e;
uint32_t hash, h;
uint16_t i;
const char *p;
hash = 0;
for (p = name; *p; p++)
hash = hash * prime_factor + *p;
h = hash;
while (1) {
i = string_map[h & ${strmap.hash_mask}];
if (i == none)
return -1;
e = &string_map_entries[i];
if (e->hash == hash && strcmp(name, strings + e->name) == 0)
return e->num;
h += prime_step;
}
return -1;
}
void *
tu_lookup_entrypoint_unchecked(const char *name)
{
int index = tu_lookup_entrypoint(name);
if (index < 0)
return NULL;
return tu_resolve_entrypoint(index);
}
void *
tu_lookup_entrypoint_checked(const char *name,
uint32_t core_version,
const struct tu_instance_extension_table *instance,
const struct tu_device_extension_table *device)
{
int index = tu_lookup_entrypoint(name);
if (index < 0 || !tu_entrypoint_is_enabled(index, core_version, instance, device))
return NULL;
return tu_resolve_entrypoint(index);
}""", output_encoding='utf-8')
U32_MASK = 2**32 - 1
PRIME_FACTOR = 5024183
PRIME_STEP = 19
def round_to_pow2(x):
return 2**int(math.ceil(math.log(x, 2)))
class StringIntMapEntry(object):
def __init__(self, string, num):
self.string = string
self.num = num
# Calculate the same hash value that we will calculate in C.
h = 0
for c in string:
h = ((h * PRIME_FACTOR) + ord(c)) & U32_MASK
self.hash = h
self.offset = None
class StringIntMap(object):
def __init__(self):
self.baked = False
self.strings = dict()
def add_string(self, string, num):
assert not self.baked
assert string not in self.strings
assert num >= 0 and num < 2**31
self.strings[string] = StringIntMapEntry(string, num)
def bake(self):
self.sorted_strings = \
sorted(self.strings.values(), key=lambda x: x.string)
offset = 0
for entry in self.sorted_strings:
entry.offset = offset
offset += len(entry.string) + 1
# Save off some values that we'll need in C
self.hash_size = round_to_pow2(len(self.strings) * 1.25)
self.hash_mask = self.hash_size - 1
self.prime_factor = PRIME_FACTOR
self.prime_step = PRIME_STEP
self.mapping = [-1] * self.hash_size
self.collisions = [0] * 10
for idx, s in enumerate(self.sorted_strings):
level = 0
h = s.hash
while self.mapping[h & self.hash_mask] >= 0:
h = h + PRIME_STEP
level = level + 1
self.collisions[min(level, 9)] += 1
self.mapping[h & self.hash_mask] = idx
EntrypointParam = namedtuple('EntrypointParam', 'type name decl')
class EntrypointBase(object):
def __init__(self, name):
self.name = name
self.alias = None
self.guard = None
self.enabled = False
self.num = None
# Extensions which require this entrypoint
self.core_version = None
self.extensions = []
class Entrypoint(EntrypointBase):
def __init__(self, name, return_type, params, guard = None):
super(Entrypoint, self).__init__(name)
self.return_type = return_type
self.params = params
self.guard = guard
self.device_command = len(params) > 0 and (params[0].type == 'VkDevice' or params[0].type == 'VkQueue' or params[0].type == 'VkCommandBuffer')
def prefixed_name(self, prefix):
assert self.name.startswith('vk')
return prefix + '_' + self.name[2:]
def decl_params(self):
return ', '.join(p.decl for p in self.params)
def call_params(self):
return ', '.join(p.name for p in self.params)
class EntrypointAlias(EntrypointBase):
def __init__(self, name, entrypoint):
super(EntrypointAlias, self).__init__(name)
self.alias = entrypoint
self.device_command = entrypoint.device_command
def prefixed_name(self, prefix):
return self.alias.prefixed_name(prefix)
def get_entrypoints(doc, entrypoints_to_defines, start_index):
"""Extract the entry points from the registry."""
entrypoints = OrderedDict()
for command in doc.findall('./commands/command'):
if 'alias' in command.attrib:
alias = command.attrib['name']
target = command.attrib['alias']
entrypoints[alias] = EntrypointAlias(alias, entrypoints[target])
else:
name = command.find('./proto/name').text
ret_type = command.find('./proto/type').text
params = [EntrypointParam(
type = p.find('./type').text,
name = p.find('./name').text,
decl = ''.join(p.itertext())
) for p in command.findall('./param')]
guard = entrypoints_to_defines.get(name)
# They really need to be unique
assert name not in entrypoints
entrypoints[name] = Entrypoint(name, ret_type, params, guard)
for feature in doc.findall('./feature'):
assert feature.attrib['api'] == 'vulkan'
version = VkVersion(feature.attrib['number'])
if version > MAX_API_VERSION:
continue
for command in feature.findall('./require/command'):
e = entrypoints[command.attrib['name']]
e.enabled = True
assert e.core_version is None
e.core_version = version
supported_exts = dict((ext.name, ext) for ext in EXTENSIONS)
for extension in doc.findall('.extensions/extension'):
ext_name = extension.attrib['name']
if ext_name not in supported_exts:
continue
ext = supported_exts[ext_name]
ext.type = extension.attrib['type']
for command in extension.findall('./require/command'):
e = entrypoints[command.attrib['name']]
e.enabled = True
assert e.core_version is None
e.extensions.append(ext)
# if the base command is not supported by the driver yet, don't alias aliases
for e in entrypoints.values():
if e.alias and not e.alias.enabled:
e_clone = copy.deepcopy(e.alias)
e_clone.enabled = True
e_clone.name = e.name
entrypoints[e.name] = e_clone
return [e for e in entrypoints.values() if e.enabled]
def get_entrypoints_defines(doc):
"""Maps entry points to extension defines."""
entrypoints_to_defines = {}
for extension in doc.findall('./extensions/extension[@protect]'):
define = extension.attrib['protect']
for entrypoint in extension.findall('./require/command'):
fullname = entrypoint.attrib['name']
entrypoints_to_defines[fullname] = define
for extension in doc.findall('./extensions/extension[@platform]'):
platform = extension.attrib['platform']
ext = '_KHR'
if platform.upper() == 'XLIB_XRANDR':
ext = '_EXT'
define = 'VK_USE_PLATFORM_' + platform.upper() + ext
for entrypoint in extension.findall('./require/command'):
fullname = entrypoint.attrib['name']
entrypoints_to_defines[fullname] = define
return entrypoints_to_defines
def gen_code(entrypoints):
"""Generate the C code."""
strmap = StringIntMap()
for e in entrypoints:
strmap.add_string(e.name, e.num)
strmap.bake()
return TEMPLATE_C.render(entrypoints=entrypoints,
LAYERS=LAYERS,
strmap=strmap,
filename=os.path.basename(__file__))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--outdir', help='Where to write the files.',
required=True)
parser.add_argument('--xml',
help='Vulkan API XML file.',
required=True,
action='append',
dest='xml_files')
args = parser.parse_args()
entrypoints = []
for filename in args.xml_files:
doc = et.parse(filename)
entrypoints += get_entrypoints(doc, get_entrypoints_defines(doc),
start_index=len(entrypoints))
for num, e in enumerate(entrypoints):
e.num = num
# For outputting entrypoints.h we generate a tu_EntryPoint() prototype
# per entry point.
with open(os.path.join(args.outdir, 'tu_entrypoints.h'), 'wb') as f:
f.write(TEMPLATE_H.render(entrypoints=entrypoints,
LAYERS=LAYERS,
filename=os.path.basename(__file__)))
with open(os.path.join(args.outdir, 'tu_entrypoints.c'), 'wb') as f:
f.write(gen_code(entrypoints))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,275 @@
COPYRIGHT = """\
/*
* Copyright 2017 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, sub license, 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 (including the
* next paragraph) 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 NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
*/
"""
import argparse
import copy
import re
import xml.etree.cElementTree as et
from mako.template import Template
MAX_API_VERSION = '1.1.82'
class Extension:
def __init__(self, name, ext_version, enable):
self.name = name
self.ext_version = int(ext_version)
if enable is True:
self.enable = 'true';
elif enable is False:
self.enable = 'false';
else:
self.enable = enable;
# On Android, we disable all surface and swapchain extensions. Android's Vulkan
# loader implements VK_KHR_surface and VK_KHR_swapchain, and applications
# cannot access the driver's implementation. Moreoever, if the driver exposes
# the those extension strings, then tests dEQP-VK.api.info.instance.extensions
# and dEQP-VK.api.info.device fail due to the duplicated strings.
EXTENSIONS = [
Extension('VK_KHR_bind_memory2', 1, True),
Extension('VK_KHR_create_renderpass2', 1, True),
Extension('VK_KHR_dedicated_allocation', 1, True),
Extension('VK_KHR_get_display_properties2', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_KHR_get_memory_requirements2', 1, True),
Extension('VK_KHR_get_physical_device_properties2', 1, True),
Extension('VK_KHR_get_surface_capabilities2', 1, 'TU_HAS_SURFACE'),
Extension('VK_KHR_maintenance1', 1, True),
Extension('VK_KHR_maintenance2', 1, True),
Extension('VK_KHR_maintenance3', 1, True),
Extension('VK_KHR_surface', 25, 'TU_HAS_SURFACE'),
Extension('VK_KHR_swapchain', 68, 'TU_HAS_SURFACE'),
Extension('VK_KHR_wayland_surface', 6, 'VK_USE_PLATFORM_WAYLAND_KHR'),
Extension('VK_KHR_xcb_surface', 6, 'VK_USE_PLATFORM_XCB_KHR'),
Extension('VK_KHR_xlib_surface', 6, 'VK_USE_PLATFORM_XLIB_KHR'),
Extension('VK_KHR_display', 23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_EXT_direct_mode_display', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
Extension('VK_EXT_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_EXT_display_control', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
Extension('VK_EXT_debug_report', 9, True),
]
class VkVersion:
def __init__(self, string):
split = string.split('.')
self.major = int(split[0])
self.minor = int(split[1])
if len(split) > 2:
assert len(split) == 3
self.patch = int(split[2])
else:
self.patch = None
# Sanity check. The range bits are required by the definition of the
# VK_MAKE_VERSION macro
assert self.major < 1024 and self.minor < 1024
assert self.patch is None or self.patch < 4096
assert(str(self) == string)
def __str__(self):
ver_list = [str(self.major), str(self.minor)]
if self.patch is not None:
ver_list.append(str(self.patch))
return '.'.join(ver_list)
def c_vk_version(self):
patch = self.patch if self.patch is not None else 0
ver_list = [str(self.major), str(self.minor), str(patch)]
return 'VK_MAKE_VERSION(' + ', '.join(ver_list) + ')'
def __int_ver(self):
# This is just an expansion of VK_VERSION
patch = self.patch if self.patch is not None else 0
return (self.major << 22) | (self.minor << 12) | patch
def __gt__(self, other):
# If only one of them has a patch version, "ignore" it by making
# other's patch version match self.
if (self.patch is None) != (other.patch is None):
other = copy.copy(other)
other.patch = self.patch
return self.__int_ver() > other.__int_ver()
MAX_API_VERSION = VkVersion(MAX_API_VERSION)
def _init_exts_from_xml(xml):
""" Walk the Vulkan XML and fill out extra extension information. """
xml = et.parse(xml)
ext_name_map = {}
for ext in EXTENSIONS:
ext_name_map[ext.name] = ext
for ext_elem in xml.findall('.extensions/extension'):
ext_name = ext_elem.attrib['name']
if ext_name not in ext_name_map:
continue
ext = ext_name_map[ext_name]
ext.type = ext_elem.attrib['type']
_TEMPLATE_H = Template(COPYRIGHT + """
#ifndef TU_EXTENSIONS_H
#define TU_EXTENSIONS_H
enum {
TU_INSTANCE_EXTENSION_COUNT = ${len(instance_extensions)},
TU_DEVICE_EXTENSION_COUNT = ${len(device_extensions)},
};
struct tu_instance_extension_table {
union {
bool extensions[TU_INSTANCE_EXTENSION_COUNT];
struct {
%for ext in instance_extensions:
bool ${ext.name[3:]};
%endfor
};
};
};
struct tu_device_extension_table {
union {
bool extensions[TU_DEVICE_EXTENSION_COUNT];
struct {
%for ext in device_extensions:
bool ${ext.name[3:]};
%endfor
};
};
};
extern const VkExtensionProperties tu_instance_extensions[TU_INSTANCE_EXTENSION_COUNT];
extern const VkExtensionProperties tu_device_extensions[TU_DEVICE_EXTENSION_COUNT];
extern const struct tu_instance_extension_table tu_supported_instance_extensions;
struct tu_physical_device;
void tu_fill_device_extension_table(const struct tu_physical_device *device,
struct tu_device_extension_table* table);
#endif
""")
_TEMPLATE_C = Template(COPYRIGHT + """
#include "tu_private.h"
#include "vk_util.h"
/* Convert the VK_USE_PLATFORM_* defines to booleans */
%for platform in ['ANDROID_KHR', 'WAYLAND_KHR', 'XCB_KHR', 'XLIB_KHR', 'DISPLAY_KHR', 'XLIB_XRANDR_EXT']:
#ifdef VK_USE_PLATFORM_${platform}
# undef VK_USE_PLATFORM_${platform}
# define VK_USE_PLATFORM_${platform} true
#else
# define VK_USE_PLATFORM_${platform} false
#endif
%endfor
/* And ANDROID too */
#ifdef ANDROID
# undef ANDROID
# define ANDROID true
#else
# define ANDROID false
#endif
#define TU_HAS_SURFACE (VK_USE_PLATFORM_WAYLAND_KHR || \\
VK_USE_PLATFORM_XCB_KHR || \\
VK_USE_PLATFORM_XLIB_KHR || \\
VK_USE_PLATFORM_DISPLAY_KHR)
const VkExtensionProperties tu_instance_extensions[TU_INSTANCE_EXTENSION_COUNT] = {
%for ext in instance_extensions:
{"${ext.name}", ${ext.ext_version}},
%endfor
};
const VkExtensionProperties tu_device_extensions[TU_DEVICE_EXTENSION_COUNT] = {
%for ext in device_extensions:
{"${ext.name}", ${ext.ext_version}},
%endfor
};
const struct tu_instance_extension_table tu_supported_instance_extensions = {
%for ext in instance_extensions:
.${ext.name[3:]} = ${ext.enable},
%endfor
};
void tu_fill_device_extension_table(const struct tu_physical_device *device,
struct tu_device_extension_table* table)
{
%for ext in device_extensions:
table->${ext.name[3:]} = ${ext.enable};
%endfor
}
VkResult tu_EnumerateInstanceVersion(
uint32_t* pApiVersion)
{
*pApiVersion = ${MAX_API_VERSION.c_vk_version()};
return VK_SUCCESS;
}
uint32_t
tu_physical_device_api_version(struct tu_physical_device *dev)
{
return VK_MAKE_VERSION(1, 1, 82);
}
""")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--out-c', help='Output C file.', required=True)
parser.add_argument('--out-h', help='Output H file.', required=True)
parser.add_argument('--xml',
help='Vulkan API XML file.',
required=True,
action='append',
dest='xml_files')
args = parser.parse_args()
for filename in args.xml_files:
_init_exts_from_xml(filename)
for ext in EXTENSIONS:
assert ext.type == 'instance' or ext.type == 'device'
template_env = {
'MAX_API_VERSION': MAX_API_VERSION,
'instance_extensions': [e for e in EXTENSIONS if e.type == 'instance'],
'device_extensions': [e for e in EXTENSIONS if e.type == 'device'],
}
with open(args.out_c, 'w') as f:
f.write(_TEMPLATE_C.render(**template_env))
with open(args.out_h, 'w') as f:
f.write(_TEMPLATE_H.render(**template_env))

View File

@ -0,0 +1,410 @@
/*
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
#include "vk_format.h"
#include "vk_util.h"
#include "util/format_r11g11b10f.h"
#include "util/format_srgb.h"
#include "util/u_half.h"
static void
tu_physical_device_get_format_properties(
struct tu_physical_device *physical_device,
VkFormat format,
VkFormatProperties *out_properties)
{
VkFormatFeatureFlags linear = 0, tiled = 0, buffer = 0;
const struct vk_format_description *desc = vk_format_description(format);
if (!desc) {
out_properties->linearTilingFeatures = linear;
out_properties->optimalTilingFeatures = tiled;
out_properties->bufferFeatures = buffer;
return;
}
out_properties->linearTilingFeatures = linear;
out_properties->optimalTilingFeatures = tiled;
out_properties->bufferFeatures = buffer;
}
void
tu_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
VkFormat format,
VkFormatProperties *pFormatProperties)
{
TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
tu_physical_device_get_format_properties(
physical_device, format, pFormatProperties);
}
void
tu_GetPhysicalDeviceFormatProperties2(
VkPhysicalDevice physicalDevice,
VkFormat format,
VkFormatProperties2KHR *pFormatProperties)
{
TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
tu_physical_device_get_format_properties(
physical_device, format, &pFormatProperties->formatProperties);
}
static VkResult
tu_get_image_format_properties(struct tu_physical_device *physical_device,
const VkPhysicalDeviceImageFormatInfo2KHR *info,
VkImageFormatProperties *pImageFormatProperties)
{
VkFormatProperties format_props;
VkFormatFeatureFlags format_feature_flags;
VkExtent3D maxExtent;
uint32_t maxMipLevels;
uint32_t maxArraySize;
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
tu_physical_device_get_format_properties(
physical_device, info->format, &format_props);
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
format_feature_flags = format_props.linearTilingFeatures;
} else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
format_feature_flags = format_props.optimalTilingFeatures;
} else {
unreachable("bad VkImageTiling");
}
if (format_feature_flags == 0)
goto unsupported;
if (info->type != VK_IMAGE_TYPE_2D &&
vk_format_is_depth_or_stencil(info->format))
goto unsupported;
switch (info->type) {
default:
unreachable("bad vkimage type\n");
case VK_IMAGE_TYPE_1D:
maxExtent.width = 16384;
maxExtent.height = 1;
maxExtent.depth = 1;
maxMipLevels = 15; /* log2(maxWidth) + 1 */
maxArraySize = 2048;
break;
case VK_IMAGE_TYPE_2D:
maxExtent.width = 16384;
maxExtent.height = 16384;
maxExtent.depth = 1;
maxMipLevels = 15; /* log2(maxWidth) + 1 */
maxArraySize = 2048;
break;
case VK_IMAGE_TYPE_3D:
maxExtent.width = 2048;
maxExtent.height = 2048;
maxExtent.depth = 2048;
maxMipLevels = 12; /* log2(maxWidth) + 1 */
maxArraySize = 1;
break;
}
if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
info->type == VK_IMAGE_TYPE_2D &&
(format_feature_flags &
(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
!(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
!(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
sampleCounts |=
VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
}
if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
if (!(format_feature_flags &
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
goto unsupported;
}
}
*pImageFormatProperties = (VkImageFormatProperties){
.maxExtent = maxExtent,
.maxMipLevels = maxMipLevels,
.maxArrayLayers = maxArraySize,
.sampleCounts = sampleCounts,
/* FINISHME: Accurately calculate
* VkImageFormatProperties::maxResourceSize.
*/
.maxResourceSize = UINT32_MAX,
};
return VK_SUCCESS;
unsupported:
*pImageFormatProperties = (VkImageFormatProperties){
.maxExtent = { 0, 0, 0 },
.maxMipLevels = 0,
.maxArrayLayers = 0,
.sampleCounts = 0,
.maxResourceSize = 0,
};
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
VkResult
tu_GetPhysicalDeviceImageFormatProperties(
VkPhysicalDevice physicalDevice,
VkFormat format,
VkImageType type,
VkImageTiling tiling,
VkImageUsageFlags usage,
VkImageCreateFlags createFlags,
VkImageFormatProperties *pImageFormatProperties)
{
TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
const VkPhysicalDeviceImageFormatInfo2KHR info = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
.pNext = NULL,
.format = format,
.type = type,
.tiling = tiling,
.usage = usage,
.flags = createFlags,
};
return tu_get_image_format_properties(
physical_device, &info, pImageFormatProperties);
}
static void
get_external_image_format_properties(
const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
VkExternalMemoryHandleTypeFlagBitsKHR handleType,
VkExternalMemoryPropertiesKHR *external_properties)
{
VkExternalMemoryFeatureFlagBitsKHR flags = 0;
VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
switch (handleType) {
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
switch (pImageFormatInfo->type) {
case VK_IMAGE_TYPE_2D:
flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR |
VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR |
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
compat_flags = export_flags =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
break;
default:
break;
}
break;
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
break;
default:
break;
}
*external_properties = (VkExternalMemoryPropertiesKHR){
.externalMemoryFeatures = flags,
.exportFromImportedHandleTypes = export_flags,
.compatibleHandleTypes = compat_flags,
};
}
VkResult
tu_GetPhysicalDeviceImageFormatProperties2(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceImageFormatInfo2KHR *base_info,
VkImageFormatProperties2KHR *base_props)
{
TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
const VkPhysicalDeviceExternalImageFormatInfoKHR *external_info = NULL;
VkExternalImageFormatPropertiesKHR *external_props = NULL;
VkResult result;
result = tu_get_image_format_properties(
physical_device, base_info, &base_props->imageFormatProperties);
if (result != VK_SUCCESS)
return result;
/* Extract input structs */
vk_foreach_struct_const(s, base_info->pNext)
{
switch (s->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR:
external_info = (const void *)s;
break;
default:
break;
}
}
/* Extract output structs */
vk_foreach_struct(s, base_props->pNext)
{
switch (s->sType) {
case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR:
external_props = (void *)s;
break;
default:
break;
}
}
/* From the Vulkan 1.0.42 spec:
*
* If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will
* behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was not
* present and VkExternalImageFormatPropertiesKHR will be ignored.
*/
if (external_info && external_info->handleType != 0) {
switch (external_info->handleType) {
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
get_external_image_format_properties(
base_info,
external_info->handleType,
&external_props->externalMemoryProperties);
break;
default:
/* From the Vulkan 1.0.42 spec:
*
* If handleType is not compatible with the [parameters]
* specified
* in VkPhysicalDeviceImageFormatInfo2KHR, then
* vkGetPhysicalDeviceImageFormatProperties2KHR returns
* VK_ERROR_FORMAT_NOT_SUPPORTED.
*/
result =
vk_errorf(physical_device->instance,
VK_ERROR_FORMAT_NOT_SUPPORTED,
"unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
external_info->handleType);
goto fail;
}
}
return VK_SUCCESS;
fail:
if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
/* From the Vulkan 1.0.42 spec:
*
* If the combination of parameters to
* vkGetPhysicalDeviceImageFormatProperties2KHR is not supported by
* the implementation for use in vkCreateImage, then all members of
* imageFormatProperties will be filled with zero.
*/
base_props->imageFormatProperties = (VkImageFormatProperties){ 0 };
}
return result;
}
void
tu_GetPhysicalDeviceSparseImageFormatProperties(
VkPhysicalDevice physicalDevice,
VkFormat format,
VkImageType type,
uint32_t samples,
VkImageUsageFlags usage,
VkImageTiling tiling,
uint32_t *pNumProperties,
VkSparseImageFormatProperties *pProperties)
{
/* Sparse images are not yet supported. */
*pNumProperties = 0;
}
void
tu_GetPhysicalDeviceSparseImageFormatProperties2(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo,
uint32_t *pPropertyCount,
VkSparseImageFormatProperties2KHR *pProperties)
{
/* Sparse images are not yet supported. */
*pPropertyCount = 0;
}
void
tu_GetPhysicalDeviceExternalBufferProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
VkExternalBufferPropertiesKHR *pExternalBufferProperties)
{
VkExternalMemoryFeatureFlagBitsKHR flags = 0;
VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
switch (pExternalBufferInfo->handleType) {
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR |
VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
compat_flags = export_flags =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
break;
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
break;
default:
break;
}
pExternalBufferProperties->externalMemoryProperties =
(VkExternalMemoryPropertiesKHR){
.externalMemoryFeatures = flags,
.exportFromImportedHandleTypes = export_flags,
.compatibleHandleTypes = compat_flags,
};
}

View File

@ -0,0 +1,47 @@
# Copyright 2017 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, sub license, 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 (including the
# next paragraph) 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 NON-INFRINGEMENT.
# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
import json
import os.path
from tu_extensions import *
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--out', help='Output json file.', required=True)
parser.add_argument('--lib-path', help='Path to libvulkan_freedreno.so')
args = parser.parse_args()
path = 'libvulkan_freedreno.so'
if args.lib_path:
path = os.path.join(args.lib_path, path)
json_data = {
'file_format_version': '1.0.0',
'ICD': {
'library_path': path,
'api_version': str(MAX_API_VERSION),
},
}
with open(args.out, 'w') as f:
json.dump(json_data, f, indent = 4, sort_keys=True, separators=(',', ': '))

View File

@ -0,0 +1,243 @@
/*
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* based in part on anv driver which is:
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
#include "util/debug.h"
#include "util/u_atomic.h"
#include "vk_format.h"
#include "vk_util.h"
VkResult
tu_image_create(VkDevice _device,
const struct tu_image_create_info *create_info,
const VkAllocationCallbacks *alloc,
VkImage *pImage)
{
TU_FROM_HANDLE(tu_device, device, _device);
const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
struct tu_image *image = NULL;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
tu_assert(pCreateInfo->mipLevels > 0);
tu_assert(pCreateInfo->arrayLayers > 0);
tu_assert(pCreateInfo->samples > 0);
tu_assert(pCreateInfo->extent.width > 0);
tu_assert(pCreateInfo->extent.height > 0);
tu_assert(pCreateInfo->extent.depth > 0);
image = vk_zalloc2(&device->alloc,
alloc,
sizeof(*image),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!image)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
image->type = pCreateInfo->imageType;
image->vk_format = pCreateInfo->format;
image->tiling = pCreateInfo->tiling;
image->usage = pCreateInfo->usage;
image->flags = pCreateInfo->flags;
image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
if (pCreateInfo->pQueueFamilyIndices[i] ==
VK_QUEUE_FAMILY_EXTERNAL_KHR)
image->queue_family_mask |= (1u << TU_MAX_QUEUE_FAMILIES) - 1u;
else
image->queue_family_mask |= 1u
<< pCreateInfo->pQueueFamilyIndices[i];
}
image->shareable =
vk_find_struct_const(pCreateInfo->pNext,
EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR) != NULL;
*pImage = tu_image_to_handle(image);
return VK_SUCCESS;
}
void
tu_image_view_init(struct tu_image_view *iview,
struct tu_device *device,
const VkImageViewCreateInfo *pCreateInfo)
{
}
unsigned
tu_image_queue_family_mask(const struct tu_image *image,
uint32_t family,
uint32_t queue_family)
{
if (!image->exclusive)
return image->queue_family_mask;
if (family == VK_QUEUE_FAMILY_EXTERNAL_KHR)
return (1u << TU_MAX_QUEUE_FAMILIES) - 1u;
if (family == VK_QUEUE_FAMILY_IGNORED)
return 1u << queue_family;
return 1u << family;
}
VkResult
tu_CreateImage(VkDevice device,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkImage *pImage)
{
#ifdef ANDROID
const VkNativeBufferANDROID *gralloc_info =
vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
if (gralloc_info)
return tu_image_from_gralloc(
device, pCreateInfo, gralloc_info, pAllocator, pImage);
#endif
return tu_image_create(device,
&(struct tu_image_create_info) {
.vk_info = pCreateInfo,
.scanout = false,
},
pAllocator,
pImage);
}
void
tu_DestroyImage(VkDevice _device,
VkImage _image,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_image, image, _image);
if (!image)
return;
if (image->owned_memory != VK_NULL_HANDLE)
tu_FreeMemory(_device, image->owned_memory, pAllocator);
vk_free2(&device->alloc, pAllocator, image);
}
void
tu_GetImageSubresourceLayout(VkDevice _device,
VkImage _image,
const VkImageSubresource *pSubresource,
VkSubresourceLayout *pLayout)
{
}
VkResult
tu_CreateImageView(VkDevice _device,
const VkImageViewCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkImageView *pView)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_image_view *view;
view = vk_alloc2(&device->alloc,
pAllocator,
sizeof(*view),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (view == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
tu_image_view_init(view, device, pCreateInfo);
*pView = tu_image_view_to_handle(view);
return VK_SUCCESS;
}
void
tu_DestroyImageView(VkDevice _device,
VkImageView _iview,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_image_view, iview, _iview);
if (!iview)
return;
vk_free2(&device->alloc, pAllocator, iview);
}
void
tu_buffer_view_init(struct tu_buffer_view *view,
struct tu_device *device,
const VkBufferViewCreateInfo *pCreateInfo)
{
TU_FROM_HANDLE(tu_buffer, buffer, pCreateInfo->buffer);
view->range = pCreateInfo->range == VK_WHOLE_SIZE
? buffer->size - pCreateInfo->offset
: pCreateInfo->range;
view->vk_format = pCreateInfo->format;
}
VkResult
tu_CreateBufferView(VkDevice _device,
const VkBufferViewCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkBufferView *pView)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_buffer_view *view;
view = vk_alloc2(&device->alloc,
pAllocator,
sizeof(*view),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!view)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
tu_buffer_view_init(view, device, pCreateInfo);
*pView = tu_buffer_view_to_handle(view);
return VK_SUCCESS;
}
void
tu_DestroyBufferView(VkDevice _device,
VkBufferView bufferView,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_buffer_view, view, bufferView);
if (!view)
return;
vk_free2(&device->alloc, pAllocator, view);
}

View File

@ -0,0 +1,38 @@
/*
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
#include "nir/nir_builder.h"
void
tu_CmdBlitImage(VkCommandBuffer commandBuffer,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage destImage,
VkImageLayout destImageLayout,
uint32_t regionCount,
const VkImageBlit *pRegions,
VkFilter filter)
{
}

View File

@ -0,0 +1,28 @@
#include "tu_private.h"
void
tu_CmdFillBuffer(VkCommandBuffer commandBuffer,
VkBuffer dstBuffer,
VkDeviceSize dstOffset,
VkDeviceSize fillSize,
uint32_t data)
{
}
void
tu_CmdCopyBuffer(VkCommandBuffer commandBuffer,
VkBuffer srcBuffer,
VkBuffer destBuffer,
uint32_t regionCount,
const VkBufferCopy *pRegions)
{
}
void
tu_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
VkBuffer dstBuffer,
VkDeviceSize dstOffset,
VkDeviceSize dataSize,
const void *pData)
{
}

View File

@ -0,0 +1,53 @@
/*
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
void
tu_CmdClearColorImage(VkCommandBuffer commandBuffer,
VkImage image_h,
VkImageLayout imageLayout,
const VkClearColorValue *pColor,
uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
}
void
tu_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
VkImage image_h,
VkImageLayout imageLayout,
const VkClearDepthStencilValue *pDepthStencil,
uint32_t rangeCount,
const VkImageSubresourceRange *pRanges)
{
}
void
tu_CmdClearAttachments(VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
const VkClearAttachment *pAttachments,
uint32_t rectCount,
const VkClearRect *pRects)
{
}

View File

@ -0,0 +1,113 @@
/*
* Copyright © 2016 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
static void
meta_copy_buffer_to_image(struct tu_cmd_buffer *cmd_buffer,
struct tu_buffer *buffer,
struct tu_image *image,
VkImageLayout layout,
uint32_t regionCount,
const VkBufferImageCopy *pRegions)
{
}
void
tu_CmdCopyBufferToImage(VkCommandBuffer commandBuffer,
VkBuffer srcBuffer,
VkImage destImage,
VkImageLayout destImageLayout,
uint32_t regionCount,
const VkBufferImageCopy *pRegions)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_image, dest_image, destImage);
TU_FROM_HANDLE(tu_buffer, src_buffer, srcBuffer);
meta_copy_buffer_to_image(cmd_buffer,
src_buffer,
dest_image,
destImageLayout,
regionCount,
pRegions);
}
static void
meta_copy_image_to_buffer(struct tu_cmd_buffer *cmd_buffer,
struct tu_buffer *buffer,
struct tu_image *image,
VkImageLayout layout,
uint32_t regionCount,
const VkBufferImageCopy *pRegions)
{
}
void
tu_CmdCopyImageToBuffer(VkCommandBuffer commandBuffer,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkBuffer destBuffer,
uint32_t regionCount,
const VkBufferImageCopy *pRegions)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_image, src_image, srcImage);
TU_FROM_HANDLE(tu_buffer, dst_buffer, destBuffer);
meta_copy_image_to_buffer(
cmd_buffer, dst_buffer, src_image, srcImageLayout, regionCount, pRegions);
}
static void
meta_copy_image(struct tu_cmd_buffer *cmd_buffer,
struct tu_image *src_image,
VkImageLayout src_image_layout,
struct tu_image *dest_image,
VkImageLayout dest_image_layout,
uint32_t regionCount,
const VkImageCopy *pRegions)
{
}
void
tu_CmdCopyImage(VkCommandBuffer commandBuffer,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkImage destImage,
VkImageLayout destImageLayout,
uint32_t regionCount,
const VkImageCopy *pRegions)
{
TU_FROM_HANDLE(tu_cmd_buffer, cmd_buffer, commandBuffer);
TU_FROM_HANDLE(tu_image, src_image, srcImage);
TU_FROM_HANDLE(tu_image, dest_image, destImage);
meta_copy_image(cmd_buffer,
src_image,
srcImageLayout,
dest_image,
destImageLayout,
regionCount,
pRegions);
}

View File

@ -0,0 +1,40 @@
/*
* Copyright © 2016 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 (including the next
* paragraph) 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.
*/
#include <assert.h>
#include <stdbool.h>
#include "tu_private.h"
#include "nir/nir_builder.h"
#include "vk_format.h"
void
tu_CmdResolveImage(VkCommandBuffer cmd_buffer_h,
VkImage src_image_h,
VkImageLayout src_image_layout,
VkImage dest_image_h,
VkImageLayout dest_image_layout,
uint32_t region_count,
const VkImageResolve *regions)
{
}

View File

@ -0,0 +1,414 @@
/*
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* based in part on anv driver which is:
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
#include "vk_util.h"
VkResult
tu_CreateRenderPass(VkDevice _device,
const VkRenderPassCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkRenderPass *pRenderPass)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_render_pass *pass;
size_t size;
size_t attachments_offset;
VkRenderPassMultiviewCreateInfoKHR *multiview_info = NULL;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
size = sizeof(*pass);
size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
attachments_offset = size;
size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
pass = vk_alloc2(
&device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pass == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
memset(pass, 0, size);
pass->attachment_count = pCreateInfo->attachmentCount;
pass->subpass_count = pCreateInfo->subpassCount;
pass->attachments = (void *)pass + attachments_offset;
vk_foreach_struct(ext, pCreateInfo->pNext)
{
switch (ext->sType) {
case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR:
multiview_info = (VkRenderPassMultiviewCreateInfoKHR *)ext;
break;
default:
break;
}
}
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
struct tu_render_pass_attachment *att = &pass->attachments[i];
att->format = pCreateInfo->pAttachments[i].format;
att->samples = pCreateInfo->pAttachments[i].samples;
att->load_op = pCreateInfo->pAttachments[i].loadOp;
att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
att->initial_layout = pCreateInfo->pAttachments[i].initialLayout;
att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
// att->store_op = pCreateInfo->pAttachments[i].storeOp;
// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
}
uint32_t subpass_attachment_count = 0;
struct tu_subpass_attachment *p;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
subpass_attachment_count +=
desc->inputAttachmentCount + desc->colorAttachmentCount +
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
(desc->pDepthStencilAttachment != NULL);
}
if (subpass_attachment_count) {
pass->subpass_attachments = vk_alloc2(
&device->alloc,
pAllocator,
subpass_attachment_count * sizeof(struct tu_subpass_attachment),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pass->subpass_attachments == NULL) {
vk_free2(&device->alloc, pAllocator, pass);
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
} else
pass->subpass_attachments = NULL;
p = pass->subpass_attachments;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
uint32_t color_sample_count = 1, depth_sample_count = 1;
struct tu_subpass *subpass = &pass->subpasses[i];
subpass->input_count = desc->inputAttachmentCount;
subpass->color_count = desc->colorAttachmentCount;
if (multiview_info)
subpass->view_mask = multiview_info->pViewMasks[i];
if (desc->inputAttachmentCount > 0) {
subpass->input_attachments = p;
p += desc->inputAttachmentCount;
for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
subpass->input_attachments[j] = (struct tu_subpass_attachment){
.attachment = desc->pInputAttachments[j].attachment,
.layout = desc->pInputAttachments[j].layout,
};
if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
pass->attachments[desc->pInputAttachments[j].attachment]
.view_mask |= subpass->view_mask;
}
}
if (desc->colorAttachmentCount > 0) {
subpass->color_attachments = p;
p += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
subpass->color_attachments[j] = (struct tu_subpass_attachment){
.attachment = desc->pColorAttachments[j].attachment,
.layout = desc->pColorAttachments[j].layout,
};
if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
pass->attachments[desc->pColorAttachments[j].attachment]
.view_mask |= subpass->view_mask;
color_sample_count =
pCreateInfo
->pAttachments[desc->pColorAttachments[j].attachment]
.samples;
}
}
}
subpass->has_resolve = false;
if (desc->pResolveAttachments) {
subpass->resolve_attachments = p;
p += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
uint32_t a = desc->pResolveAttachments[j].attachment;
subpass->resolve_attachments[j] = (struct tu_subpass_attachment){
.attachment = desc->pResolveAttachments[j].attachment,
.layout = desc->pResolveAttachments[j].layout,
};
if (a != VK_ATTACHMENT_UNUSED) {
subpass->has_resolve = true;
pass->attachments[desc->pResolveAttachments[j].attachment]
.view_mask |= subpass->view_mask;
}
}
}
if (desc->pDepthStencilAttachment) {
subpass->depth_stencil_attachment = (struct tu_subpass_attachment){
.attachment = desc->pDepthStencilAttachment->attachment,
.layout = desc->pDepthStencilAttachment->layout,
};
if (desc->pDepthStencilAttachment->attachment !=
VK_ATTACHMENT_UNUSED) {
pass->attachments[desc->pDepthStencilAttachment->attachment]
.view_mask |= subpass->view_mask;
depth_sample_count =
pCreateInfo
->pAttachments[desc->pDepthStencilAttachment->attachment]
.samples;
}
} else {
subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
}
subpass->max_sample_count = MAX2(color_sample_count, depth_sample_count);
}
for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
if (dst == VK_SUBPASS_EXTERNAL) {
pass->end_barrier.src_stage_mask =
pCreateInfo->pDependencies[i].srcStageMask;
pass->end_barrier.src_access_mask =
pCreateInfo->pDependencies[i].srcAccessMask;
pass->end_barrier.dst_access_mask =
pCreateInfo->pDependencies[i].dstAccessMask;
} else {
pass->subpasses[dst].start_barrier.src_stage_mask =
pCreateInfo->pDependencies[i].srcStageMask;
pass->subpasses[dst].start_barrier.src_access_mask =
pCreateInfo->pDependencies[i].srcAccessMask;
pass->subpasses[dst].start_barrier.dst_access_mask =
pCreateInfo->pDependencies[i].dstAccessMask;
}
}
*pRenderPass = tu_render_pass_to_handle(pass);
return VK_SUCCESS;
}
VkResult
tu_CreateRenderPass2KHR(VkDevice _device,
const VkRenderPassCreateInfo2KHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkRenderPass *pRenderPass)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_render_pass *pass;
size_t size;
size_t attachments_offset;
assert(pCreateInfo->sType ==
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
size = sizeof(*pass);
size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
attachments_offset = size;
size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
pass = vk_alloc2(
&device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pass == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
memset(pass, 0, size);
pass->attachment_count = pCreateInfo->attachmentCount;
pass->subpass_count = pCreateInfo->subpassCount;
pass->attachments = (void *)pass + attachments_offset;
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
struct tu_render_pass_attachment *att = &pass->attachments[i];
att->format = pCreateInfo->pAttachments[i].format;
att->samples = pCreateInfo->pAttachments[i].samples;
att->load_op = pCreateInfo->pAttachments[i].loadOp;
att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
att->initial_layout = pCreateInfo->pAttachments[i].initialLayout;
att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
// att->store_op = pCreateInfo->pAttachments[i].storeOp;
// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
}
uint32_t subpass_attachment_count = 0;
struct tu_subpass_attachment *p;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
subpass_attachment_count +=
desc->inputAttachmentCount + desc->colorAttachmentCount +
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
(desc->pDepthStencilAttachment != NULL);
}
if (subpass_attachment_count) {
pass->subpass_attachments = vk_alloc2(
&device->alloc,
pAllocator,
subpass_attachment_count * sizeof(struct tu_subpass_attachment),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (pass->subpass_attachments == NULL) {
vk_free2(&device->alloc, pAllocator, pass);
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
} else
pass->subpass_attachments = NULL;
p = pass->subpass_attachments;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
uint32_t color_sample_count = 1, depth_sample_count = 1;
struct tu_subpass *subpass = &pass->subpasses[i];
subpass->input_count = desc->inputAttachmentCount;
subpass->color_count = desc->colorAttachmentCount;
subpass->view_mask = desc->viewMask;
if (desc->inputAttachmentCount > 0) {
subpass->input_attachments = p;
p += desc->inputAttachmentCount;
for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
subpass->input_attachments[j] = (struct tu_subpass_attachment){
.attachment = desc->pInputAttachments[j].attachment,
.layout = desc->pInputAttachments[j].layout,
};
if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
pass->attachments[desc->pInputAttachments[j].attachment]
.view_mask |= subpass->view_mask;
}
}
if (desc->colorAttachmentCount > 0) {
subpass->color_attachments = p;
p += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
subpass->color_attachments[j] = (struct tu_subpass_attachment){
.attachment = desc->pColorAttachments[j].attachment,
.layout = desc->pColorAttachments[j].layout,
};
if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
pass->attachments[desc->pColorAttachments[j].attachment]
.view_mask |= subpass->view_mask;
color_sample_count =
pCreateInfo
->pAttachments[desc->pColorAttachments[j].attachment]
.samples;
}
}
}
subpass->has_resolve = false;
if (desc->pResolveAttachments) {
subpass->resolve_attachments = p;
p += desc->colorAttachmentCount;
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
uint32_t a = desc->pResolveAttachments[j].attachment;
subpass->resolve_attachments[j] = (struct tu_subpass_attachment){
.attachment = desc->pResolveAttachments[j].attachment,
.layout = desc->pResolveAttachments[j].layout,
};
if (a != VK_ATTACHMENT_UNUSED) {
subpass->has_resolve = true;
pass->attachments[desc->pResolveAttachments[j].attachment]
.view_mask |= subpass->view_mask;
}
}
}
if (desc->pDepthStencilAttachment) {
subpass->depth_stencil_attachment = (struct tu_subpass_attachment){
.attachment = desc->pDepthStencilAttachment->attachment,
.layout = desc->pDepthStencilAttachment->layout,
};
if (desc->pDepthStencilAttachment->attachment !=
VK_ATTACHMENT_UNUSED) {
pass->attachments[desc->pDepthStencilAttachment->attachment]
.view_mask |= subpass->view_mask;
depth_sample_count =
pCreateInfo
->pAttachments[desc->pDepthStencilAttachment->attachment]
.samples;
}
} else {
subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
}
subpass->max_sample_count = MAX2(color_sample_count, depth_sample_count);
}
for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
if (dst == VK_SUBPASS_EXTERNAL) {
pass->end_barrier.src_stage_mask =
pCreateInfo->pDependencies[i].srcStageMask;
pass->end_barrier.src_access_mask =
pCreateInfo->pDependencies[i].srcAccessMask;
pass->end_barrier.dst_access_mask =
pCreateInfo->pDependencies[i].dstAccessMask;
} else {
pass->subpasses[dst].start_barrier.src_stage_mask =
pCreateInfo->pDependencies[i].srcStageMask;
pass->subpasses[dst].start_barrier.src_access_mask =
pCreateInfo->pDependencies[i].srcAccessMask;
pass->subpasses[dst].start_barrier.dst_access_mask =
pCreateInfo->pDependencies[i].dstAccessMask;
}
}
*pRenderPass = tu_render_pass_to_handle(pass);
return VK_SUCCESS;
}
void
tu_DestroyRenderPass(VkDevice _device,
VkRenderPass _pass,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_render_pass, pass, _pass);
if (!_pass)
return;
vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
vk_free2(&device->alloc, pAllocator, pass);
}
void
tu_GetRenderAreaGranularity(VkDevice device,
VkRenderPass renderPass,
VkExtent2D *pGranularity)
{
pGranularity->width = 1;
pGranularity->height = 1;
}

View File

@ -0,0 +1,113 @@
/*
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* based in part on anv driver which is:
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
#include "nir/nir.h"
#include "nir/nir_builder.h"
#include "spirv/nir_spirv.h"
#include "util/mesa-sha1.h"
#include "util/u_atomic.h"
#include "vk_util.h"
#include "main/menums.h"
#include "util/debug.h"
#include "vk_format.h"
VkResult
tu_graphics_pipeline_create(
VkDevice _device,
VkPipelineCache _cache,
const VkGraphicsPipelineCreateInfo *pCreateInfo,
const struct tu_graphics_pipeline_create_info *extra,
const VkAllocationCallbacks *pAllocator,
VkPipeline *pPipeline)
{
return VK_SUCCESS;
}
VkResult
tu_CreateGraphicsPipelines(VkDevice _device,
VkPipelineCache pipelineCache,
uint32_t count,
const VkGraphicsPipelineCreateInfo *pCreateInfos,
const VkAllocationCallbacks *pAllocator,
VkPipeline *pPipelines)
{
VkResult result = VK_SUCCESS;
unsigned i = 0;
for (; i < count; i++) {
VkResult r;
r = tu_graphics_pipeline_create(_device,
pipelineCache,
&pCreateInfos[i],
NULL,
pAllocator,
&pPipelines[i]);
if (r != VK_SUCCESS) {
result = r;
pPipelines[i] = VK_NULL_HANDLE;
}
}
return result;
}
static VkResult
tu_compute_pipeline_create(VkDevice _device,
VkPipelineCache _cache,
const VkComputePipelineCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkPipeline *pPipeline)
{
return VK_SUCCESS;
}
VkResult
tu_CreateComputePipelines(VkDevice _device,
VkPipelineCache pipelineCache,
uint32_t count,
const VkComputePipelineCreateInfo *pCreateInfos,
const VkAllocationCallbacks *pAllocator,
VkPipeline *pPipelines)
{
VkResult result = VK_SUCCESS;
unsigned i = 0;
for (; i < count; i++) {
VkResult r;
r = tu_compute_pipeline_create(
_device, pipelineCache, &pCreateInfos[i], pAllocator, &pPipelines[i]);
if (r != VK_SUCCESS) {
result = r;
pPipelines[i] = VK_NULL_HANDLE;
}
}
return result;
}

View File

@ -0,0 +1,424 @@
/*
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include "tu_private.h"
#include "util/debug.h"
#include "util/disk_cache.h"
#include "util/mesa-sha1.h"
#include "util/u_atomic.h"
struct cache_entry_variant_info
{
};
struct cache_entry
{
union
{
unsigned char sha1[20];
uint32_t sha1_dw[5];
};
uint32_t code_sizes[MESA_SHADER_STAGES];
struct tu_shader_variant *variants[MESA_SHADER_STAGES];
char code[0];
};
void
tu_pipeline_cache_init(struct tu_pipeline_cache *cache,
struct tu_device *device)
{
cache->device = device;
pthread_mutex_init(&cache->mutex, NULL);
cache->modified = false;
cache->kernel_count = 0;
cache->total_size = 0;
cache->table_size = 1024;
const size_t byte_size = cache->table_size * sizeof(cache->hash_table[0]);
cache->hash_table = malloc(byte_size);
/* We don't consider allocation failure fatal, we just start with a 0-sized
* cache. Disable caching when we want to keep shader debug info, since
* we don't get the debug info on cached shaders. */
if (cache->hash_table == NULL)
cache->table_size = 0;
else
memset(cache->hash_table, 0, byte_size);
}
void
tu_pipeline_cache_finish(struct tu_pipeline_cache *cache)
{
for (unsigned i = 0; i < cache->table_size; ++i)
if (cache->hash_table[i]) {
vk_free(&cache->alloc, cache->hash_table[i]);
}
pthread_mutex_destroy(&cache->mutex);
free(cache->hash_table);
}
static uint32_t
entry_size(struct cache_entry *entry)
{
size_t ret = sizeof(*entry);
for (int i = 0; i < MESA_SHADER_STAGES; ++i)
if (entry->code_sizes[i])
ret += sizeof(struct cache_entry_variant_info) + entry->code_sizes[i];
return ret;
}
void
tu_hash_shaders(unsigned char *hash,
const VkPipelineShaderStageCreateInfo **stages,
const struct tu_pipeline_layout *layout,
const struct tu_pipeline_key *key,
uint32_t flags)
{
struct mesa_sha1 ctx;
_mesa_sha1_init(&ctx);
if (key)
_mesa_sha1_update(&ctx, key, sizeof(*key));
if (layout)
_mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
if (stages[i]) {
TU_FROM_HANDLE(tu_shader_module, module, stages[i]->module);
const VkSpecializationInfo *spec_info = stages[i]->pSpecializationInfo;
_mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
_mesa_sha1_update(&ctx, stages[i]->pName, strlen(stages[i]->pName));
if (spec_info) {
_mesa_sha1_update(&ctx,
spec_info->pMapEntries,
spec_info->mapEntryCount *
sizeof spec_info->pMapEntries[0]);
_mesa_sha1_update(&ctx, spec_info->pData, spec_info->dataSize);
}
}
}
_mesa_sha1_update(&ctx, &flags, 4);
_mesa_sha1_final(&ctx, hash);
}
static struct cache_entry *
tu_pipeline_cache_search_unlocked(struct tu_pipeline_cache *cache,
const unsigned char *sha1)
{
const uint32_t mask = cache->table_size - 1;
const uint32_t start = (*(uint32_t *)sha1);
if (cache->table_size == 0)
return NULL;
for (uint32_t i = 0; i < cache->table_size; i++) {
const uint32_t index = (start + i) & mask;
struct cache_entry *entry = cache->hash_table[index];
if (!entry)
return NULL;
if (memcmp(entry->sha1, sha1, sizeof(entry->sha1)) == 0) {
return entry;
}
}
unreachable("hash table should never be full");
}
static struct cache_entry *
tu_pipeline_cache_search(struct tu_pipeline_cache *cache,
const unsigned char *sha1)
{
struct cache_entry *entry;
pthread_mutex_lock(&cache->mutex);
entry = tu_pipeline_cache_search_unlocked(cache, sha1);
pthread_mutex_unlock(&cache->mutex);
return entry;
}
static void
tu_pipeline_cache_set_entry(struct tu_pipeline_cache *cache,
struct cache_entry *entry)
{
const uint32_t mask = cache->table_size - 1;
const uint32_t start = entry->sha1_dw[0];
/* We'll always be able to insert when we get here. */
assert(cache->kernel_count < cache->table_size / 2);
for (uint32_t i = 0; i < cache->table_size; i++) {
const uint32_t index = (start + i) & mask;
if (!cache->hash_table[index]) {
cache->hash_table[index] = entry;
break;
}
}
cache->total_size += entry_size(entry);
cache->kernel_count++;
}
static VkResult
tu_pipeline_cache_grow(struct tu_pipeline_cache *cache)
{
const uint32_t table_size = cache->table_size * 2;
const uint32_t old_table_size = cache->table_size;
const size_t byte_size = table_size * sizeof(cache->hash_table[0]);
struct cache_entry **table;
struct cache_entry **old_table = cache->hash_table;
table = malloc(byte_size);
if (table == NULL)
return vk_error(cache->device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
cache->hash_table = table;
cache->table_size = table_size;
cache->kernel_count = 0;
cache->total_size = 0;
memset(cache->hash_table, 0, byte_size);
for (uint32_t i = 0; i < old_table_size; i++) {
struct cache_entry *entry = old_table[i];
if (!entry)
continue;
tu_pipeline_cache_set_entry(cache, entry);
}
free(old_table);
return VK_SUCCESS;
}
static void
tu_pipeline_cache_add_entry(struct tu_pipeline_cache *cache,
struct cache_entry *entry)
{
if (cache->kernel_count == cache->table_size / 2)
tu_pipeline_cache_grow(cache);
/* Failing to grow that hash table isn't fatal, but may mean we don't
* have enough space to add this new kernel. Only add it if there's room.
*/
if (cache->kernel_count < cache->table_size / 2)
tu_pipeline_cache_set_entry(cache, entry);
}
struct cache_header
{
uint32_t header_size;
uint32_t header_version;
uint32_t vendor_id;
uint32_t device_id;
uint8_t uuid[VK_UUID_SIZE];
};
void
tu_pipeline_cache_load(struct tu_pipeline_cache *cache,
const void *data,
size_t size)
{
struct tu_device *device = cache->device;
struct cache_header header;
if (size < sizeof(header))
return;
memcpy(&header, data, sizeof(header));
if (header.header_size < sizeof(header))
return;
if (header.header_version != VK_PIPELINE_CACHE_HEADER_VERSION_ONE)
return;
if (header.vendor_id != 0 /* TODO */)
return;
if (header.device_id != 0 /* TODO */)
return;
if (memcmp(header.uuid, device->physical_device->cache_uuid, VK_UUID_SIZE) !=
0)
return;
char *end = (void *)data + size;
char *p = (void *)data + header.header_size;
while (end - p >= sizeof(struct cache_entry)) {
struct cache_entry *entry = (struct cache_entry *)p;
struct cache_entry *dest_entry;
size_t size = entry_size(entry);
if (end - p < size)
break;
dest_entry =
vk_alloc(&cache->alloc, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_CACHE);
if (dest_entry) {
memcpy(dest_entry, entry, size);
for (int i = 0; i < MESA_SHADER_STAGES; ++i)
dest_entry->variants[i] = NULL;
tu_pipeline_cache_add_entry(cache, dest_entry);
}
p += size;
}
}
VkResult
tu_CreatePipelineCache(VkDevice _device,
const VkPipelineCacheCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkPipelineCache *pPipelineCache)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_pipeline_cache *cache;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO);
assert(pCreateInfo->flags == 0);
cache = vk_alloc2(&device->alloc,
pAllocator,
sizeof(*cache),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (cache == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
if (pAllocator)
cache->alloc = *pAllocator;
else
cache->alloc = device->alloc;
tu_pipeline_cache_init(cache, device);
if (pCreateInfo->initialDataSize > 0) {
tu_pipeline_cache_load(
cache, pCreateInfo->pInitialData, pCreateInfo->initialDataSize);
}
*pPipelineCache = tu_pipeline_cache_to_handle(cache);
return VK_SUCCESS;
}
void
tu_DestroyPipelineCache(VkDevice _device,
VkPipelineCache _cache,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_pipeline_cache, cache, _cache);
if (!cache)
return;
tu_pipeline_cache_finish(cache);
vk_free2(&device->alloc, pAllocator, cache);
}
VkResult
tu_GetPipelineCacheData(VkDevice _device,
VkPipelineCache _cache,
size_t *pDataSize,
void *pData)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_pipeline_cache, cache, _cache);
struct cache_header *header;
VkResult result = VK_SUCCESS;
pthread_mutex_lock(&cache->mutex);
const size_t size = sizeof(*header) + cache->total_size;
if (pData == NULL) {
pthread_mutex_unlock(&cache->mutex);
*pDataSize = size;
return VK_SUCCESS;
}
if (*pDataSize < sizeof(*header)) {
pthread_mutex_unlock(&cache->mutex);
*pDataSize = 0;
return VK_INCOMPLETE;
}
void *p = pData, *end = pData + *pDataSize;
header = p;
header->header_size = sizeof(*header);
header->header_version = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
header->vendor_id = 0 /* TODO */;
header->device_id = 0 /* TODO */;
memcpy(header->uuid, device->physical_device->cache_uuid, VK_UUID_SIZE);
p += header->header_size;
struct cache_entry *entry;
for (uint32_t i = 0; i < cache->table_size; i++) {
if (!cache->hash_table[i])
continue;
entry = cache->hash_table[i];
const uint32_t size = entry_size(entry);
if (end < p + size) {
result = VK_INCOMPLETE;
break;
}
memcpy(p, entry, size);
for (int j = 0; j < MESA_SHADER_STAGES; ++j)
((struct cache_entry *)p)->variants[j] = NULL;
p += size;
}
*pDataSize = p - pData;
pthread_mutex_unlock(&cache->mutex);
return result;
}
static void
tu_pipeline_cache_merge(struct tu_pipeline_cache *dst,
struct tu_pipeline_cache *src)
{
for (uint32_t i = 0; i < src->table_size; i++) {
struct cache_entry *entry = src->hash_table[i];
if (!entry || tu_pipeline_cache_search(dst, entry->sha1))
continue;
tu_pipeline_cache_add_entry(dst, entry);
src->hash_table[i] = NULL;
}
}
VkResult
tu_MergePipelineCaches(VkDevice _device,
VkPipelineCache destCache,
uint32_t srcCacheCount,
const VkPipelineCache *pSrcCaches)
{
TU_FROM_HANDLE(tu_pipeline_cache, dst, destCache);
for (uint32_t i = 0; i < srcCacheCount; i++) {
TU_FROM_HANDLE(tu_pipeline_cache, src, pSrcCaches[i]);
tu_pipeline_cache_merge(dst, src);
}
return VK_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,123 @@
/*
* Copyrigh 2016 Red Hat Inc.
* Based on anv:
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include <assert.h>
#include <fcntl.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include "tu_private.h"
#include "nir/nir_builder.h"
VkResult
tu_CreateQueryPool(VkDevice _device,
const VkQueryPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkQueryPool *pQueryPool)
{
TU_FROM_HANDLE(tu_device, device, _device);
struct tu_query_pool *pool = vk_alloc2(&device->alloc,
pAllocator,
sizeof(*pool),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!pool)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
*pQueryPool = tu_query_pool_to_handle(pool);
return VK_SUCCESS;
}
void
tu_DestroyQueryPool(VkDevice _device,
VkQueryPool _pool,
const VkAllocationCallbacks *pAllocator)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_query_pool, pool, _pool);
if (!pool)
return;
vk_free2(&device->alloc, pAllocator, pool);
}
VkResult
tu_GetQueryPoolResults(VkDevice _device,
VkQueryPool queryPool,
uint32_t firstQuery,
uint32_t queryCount,
size_t dataSize,
void *pData,
VkDeviceSize stride,
VkQueryResultFlags flags)
{
return VK_SUCCESS;
}
void
tu_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t firstQuery,
uint32_t queryCount,
VkBuffer dstBuffer,
VkDeviceSize dstOffset,
VkDeviceSize stride,
VkQueryResultFlags flags)
{
}
void
tu_CmdResetQueryPool(VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t firstQuery,
uint32_t queryCount)
{
}
void
tu_CmdBeginQuery(VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t query,
VkQueryControlFlags flags)
{
}
void
tu_CmdEndQuery(VkCommandBuffer commandBuffer,
VkQueryPool queryPool,
uint32_t query)
{
}
void
tu_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
VkPipelineStageFlagBits pipelineStage,
VkQueryPool queryPool,
uint32_t query)
{
}

View File

@ -0,0 +1,115 @@
/*
* Copyright © 2015 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 (including the next
* paragraph) 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.
*/
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tu_private.h"
#include "vk_enum_to_str.h"
#include "util/u_math.h"
/** Log an error message. */
void tu_printflike(1, 2) tu_loge(const char *format, ...)
{
va_list va;
va_start(va, format);
tu_loge_v(format, va);
va_end(va);
}
/** \see tu_loge() */
void
tu_loge_v(const char *format, va_list va)
{
fprintf(stderr, "vk: error: ");
vfprintf(stderr, format, va);
fprintf(stderr, "\n");
}
/** Log an error message. */
void tu_printflike(1, 2) tu_logi(const char *format, ...)
{
va_list va;
va_start(va, format);
tu_logi_v(format, va);
va_end(va);
}
/** \see tu_logi() */
void
tu_logi_v(const char *format, va_list va)
{
fprintf(stderr, "tu: info: ");
vfprintf(stderr, format, va);
fprintf(stderr, "\n");
}
void tu_printflike(3, 4)
__tu_finishme(const char *file, int line, const char *format, ...)
{
va_list ap;
char buffer[256];
va_start(ap, format);
vsnprintf(buffer, sizeof(buffer), format, ap);
va_end(ap);
fprintf(stderr, "%s:%d: FINISHME: %s\n", file, line, buffer);
}
VkResult
__vk_errorf(struct tu_instance *instance,
VkResult error,
const char *file,
int line,
const char *format,
...)
{
va_list ap;
char buffer[256];
const char *error_str = vk_Result_to_str(error);
#ifndef DEBUG
return error;
#endif
if (format) {
va_start(ap, format);
vsnprintf(buffer, sizeof(buffer), format, ap);
va_end(ap);
fprintf(stderr, "%s:%d: %s (%s)\n", file, line, buffer, error_str);
} else {
fprintf(stderr, "%s:%d: %s\n", file, line, error_str);
}
return error;
}

View File

@ -0,0 +1,11 @@
#ifndef TU_UTIL_H
#define TU_UTIL_H
#ifdef HAVE___BUILTIN_POPCOUNT
#define util_bitcount(i) __builtin_popcount(i)
#else
extern unsigned int
util_bitcount(unsigned int n);
#endif
#endif /* TU_UTIL_H */

View File

@ -0,0 +1,545 @@
/*
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
*
* Based on u_format.h which is:
* Copyright 2009-2010 Vmware, Inc.
* 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 (including the next
* paragraph) 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.
*/
#ifndef VK_FORMAT_H
#define VK_FORMAT_H
#include <assert.h>
#include <util/macros.h>
#include <vulkan/vulkan.h>
enum vk_format_layout
{
/**
* Formats with vk_format_block::width == vk_format_block::height == 1
* that can be described as an ordinary data structure.
*/
VK_FORMAT_LAYOUT_PLAIN = 0,
/**
* Formats with sub-sampled channels.
*
* This is for formats like YVYU where there is less than one sample per
* pixel.
*/
VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
/**
* S3 Texture Compression formats.
*/
VK_FORMAT_LAYOUT_S3TC = 4,
/**
* Red-Green Texture Compression formats.
*/
VK_FORMAT_LAYOUT_RGTC = 5,
/**
* Ericsson Texture Compression
*/
VK_FORMAT_LAYOUT_ETC = 6,
/**
* BC6/7 Texture Compression
*/
VK_FORMAT_LAYOUT_BPTC = 7,
/**
* ASTC
*/
VK_FORMAT_LAYOUT_ASTC = 8,
/**
* Everything else that doesn't fit in any of the above layouts.
*/
VK_FORMAT_LAYOUT_OTHER = 9
};
struct vk_format_block
{
/** Block width in pixels */
unsigned width;
/** Block height in pixels */
unsigned height;
/** Block size in bits */
unsigned bits;
};
enum vk_format_type
{
VK_FORMAT_TYPE_VOID = 0,
VK_FORMAT_TYPE_UNSIGNED = 1,
VK_FORMAT_TYPE_SIGNED = 2,
VK_FORMAT_TYPE_FIXED = 3,
VK_FORMAT_TYPE_FLOAT = 4
};
enum vk_format_colorspace
{
VK_FORMAT_COLORSPACE_RGB = 0,
VK_FORMAT_COLORSPACE_SRGB = 1,
VK_FORMAT_COLORSPACE_YUV = 2,
VK_FORMAT_COLORSPACE_ZS = 3
};
struct vk_format_channel_description
{
unsigned type : 5;
unsigned normalized : 1;
unsigned pure_integer : 1;
unsigned scaled : 1;
unsigned size : 8;
unsigned shift : 16;
};
struct vk_format_description
{
VkFormat format;
const char *name;
const char *short_name;
struct vk_format_block block;
enum vk_format_layout layout;
unsigned nr_channels : 3;
unsigned is_array : 1;
unsigned is_bitmask : 1;
unsigned is_mixed : 1;
struct vk_format_channel_description channel[4];
unsigned char swizzle[4];
enum vk_format_colorspace colorspace;
};
extern const struct vk_format_description vk_format_description_table[];
const struct vk_format_description *
vk_format_description(VkFormat format);
/**
* Return total bits needed for the pixel format per block.
*/
static inline unsigned
vk_format_get_blocksizebits(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
assert(desc);
if (!desc) {
return 0;
}
return desc->block.bits;
}
/**
* Return bytes per block (not pixel) for the given format.
*/
static inline unsigned
vk_format_get_blocksize(VkFormat format)
{
unsigned bits = vk_format_get_blocksizebits(format);
unsigned bytes = bits / 8;
assert(bits % 8 == 0);
assert(bytes > 0);
if (bytes == 0) {
bytes = 1;
}
return bytes;
}
static inline unsigned
vk_format_get_blockwidth(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
assert(desc);
if (!desc) {
return 1;
}
return desc->block.width;
}
static inline unsigned
vk_format_get_blockheight(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
assert(desc);
if (!desc) {
return 1;
}
return desc->block.height;
}
/**
* Return the index of the first non-void channel
* -1 if no non-void channels
*/
static inline int
vk_format_get_first_non_void_channel(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
int i;
for (i = 0; i < 4; i++)
if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
break;
if (i == 4)
return -1;
return i;
}
enum vk_swizzle
{
VK_SWIZZLE_X,
VK_SWIZZLE_Y,
VK_SWIZZLE_Z,
VK_SWIZZLE_W,
VK_SWIZZLE_0,
VK_SWIZZLE_1,
VK_SWIZZLE_NONE,
VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
};
static inline VkImageAspectFlags
vk_format_aspects(VkFormat format)
{
switch (format) {
case VK_FORMAT_UNDEFINED:
return 0;
case VK_FORMAT_S8_UINT:
return VK_IMAGE_ASPECT_STENCIL_BIT;
case VK_FORMAT_D16_UNORM_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D32_SFLOAT:
return VK_IMAGE_ASPECT_DEPTH_BIT;
default:
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}
static inline enum vk_swizzle
tu_swizzle_conv(VkComponentSwizzle component,
const unsigned char chan[4],
VkComponentSwizzle vk_swiz)
{
int x;
if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
vk_swiz = component;
switch (vk_swiz) {
case VK_COMPONENT_SWIZZLE_ZERO:
return VK_SWIZZLE_0;
case VK_COMPONENT_SWIZZLE_ONE:
return VK_SWIZZLE_1;
case VK_COMPONENT_SWIZZLE_R:
for (x = 0; x < 4; x++)
if (chan[x] == 0)
return x;
return VK_SWIZZLE_0;
case VK_COMPONENT_SWIZZLE_G:
for (x = 0; x < 4; x++)
if (chan[x] == 1)
return x;
return VK_SWIZZLE_0;
case VK_COMPONENT_SWIZZLE_B:
for (x = 0; x < 4; x++)
if (chan[x] == 2)
return x;
return VK_SWIZZLE_0;
case VK_COMPONENT_SWIZZLE_A:
for (x = 0; x < 4; x++)
if (chan[x] == 3)
return x;
return VK_SWIZZLE_1;
default:
unreachable("Illegal swizzle");
}
}
static inline void
vk_format_compose_swizzles(const VkComponentMapping *mapping,
const unsigned char swz[4],
enum vk_swizzle dst[4])
{
dst[0] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_R, swz, mapping->r);
dst[1] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_G, swz, mapping->g);
dst[2] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_B, swz, mapping->b);
dst[3] = tu_swizzle_conv(VK_COMPONENT_SWIZZLE_A, swz, mapping->a);
}
static inline bool
vk_format_is_compressed(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
assert(desc);
if (!desc) {
return false;
}
switch (desc->layout) {
case VK_FORMAT_LAYOUT_S3TC:
case VK_FORMAT_LAYOUT_RGTC:
case VK_FORMAT_LAYOUT_ETC:
case VK_FORMAT_LAYOUT_BPTC:
case VK_FORMAT_LAYOUT_ASTC:
/* XXX add other formats in the future */
return true;
default:
return false;
}
}
static inline bool
vk_format_has_depth(const struct vk_format_description *desc)
{
return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
desc->swizzle[0] != VK_SWIZZLE_NONE;
}
static inline bool
vk_format_has_stencil(const struct vk_format_description *desc)
{
return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
desc->swizzle[1] != VK_SWIZZLE_NONE;
}
static inline bool
vk_format_is_depth_or_stencil(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
assert(desc);
if (!desc) {
return false;
}
return vk_format_has_depth(desc) || vk_format_has_stencil(desc);
}
static inline bool
vk_format_is_depth(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
assert(desc);
if (!desc) {
return false;
}
return vk_format_has_depth(desc);
}
static inline bool
vk_format_is_stencil(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
assert(desc);
if (!desc) {
return false;
}
return vk_format_has_stencil(desc);
}
static inline bool
vk_format_is_color(VkFormat format)
{
return !vk_format_is_depth_or_stencil(format);
}
static inline VkFormat
vk_format_depth_only(VkFormat format)
{
switch (format) {
case VK_FORMAT_D16_UNORM_S8_UINT:
return VK_FORMAT_D16_UNORM;
case VK_FORMAT_D24_UNORM_S8_UINT:
return VK_FORMAT_X8_D24_UNORM_PACK32;
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return VK_FORMAT_D32_SFLOAT;
default:
return format;
}
}
static inline bool
vk_format_is_int(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
int channel = vk_format_get_first_non_void_channel(format);
return channel >= 0 && desc->channel[channel].pure_integer;
}
static inline bool
vk_format_is_srgb(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
}
static inline VkFormat
vk_format_no_srgb(VkFormat format)
{
switch (format) {
case VK_FORMAT_R8_SRGB:
return VK_FORMAT_R8_UNORM;
case VK_FORMAT_R8G8_SRGB:
return VK_FORMAT_R8G8_UNORM;
case VK_FORMAT_R8G8B8_SRGB:
return VK_FORMAT_R8G8B8_UNORM;
case VK_FORMAT_B8G8R8_SRGB:
return VK_FORMAT_B8G8R8_UNORM;
case VK_FORMAT_R8G8B8A8_SRGB:
return VK_FORMAT_R8G8B8A8_UNORM;
case VK_FORMAT_B8G8R8A8_SRGB:
return VK_FORMAT_B8G8R8A8_UNORM;
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
case VK_FORMAT_BC2_SRGB_BLOCK:
return VK_FORMAT_BC2_UNORM_BLOCK;
case VK_FORMAT_BC3_SRGB_BLOCK:
return VK_FORMAT_BC3_UNORM_BLOCK;
case VK_FORMAT_BC7_SRGB_BLOCK:
return VK_FORMAT_BC7_UNORM_BLOCK;
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
default:
assert(!vk_format_is_srgb(format));
return format;
}
}
static inline VkFormat
vk_format_stencil_only(VkFormat format)
{
return VK_FORMAT_S8_UINT;
}
static inline unsigned
vk_format_get_component_bits(VkFormat format,
enum vk_format_colorspace colorspace,
unsigned component)
{
const struct vk_format_description *desc = vk_format_description(format);
enum vk_format_colorspace desc_colorspace;
assert(format);
if (!format) {
return 0;
}
assert(component < 4);
/* Treat RGB and SRGB as equivalent. */
if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
colorspace = VK_FORMAT_COLORSPACE_RGB;
}
if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
} else {
desc_colorspace = desc->colorspace;
}
if (desc_colorspace != colorspace) {
return 0;
}
switch (desc->swizzle[component]) {
case VK_SWIZZLE_X:
return desc->channel[0].size;
case VK_SWIZZLE_Y:
return desc->channel[1].size;
case VK_SWIZZLE_Z:
return desc->channel[2].size;
case VK_SWIZZLE_W:
return desc->channel[3].size;
default:
return 0;
}
}
static inline VkFormat
vk_to_non_srgb_format(VkFormat format)
{
switch (format) {
case VK_FORMAT_R8_SRGB:
return VK_FORMAT_R8_UNORM;
case VK_FORMAT_R8G8_SRGB:
return VK_FORMAT_R8G8_UNORM;
case VK_FORMAT_R8G8B8_SRGB:
return VK_FORMAT_R8G8B8_UNORM;
case VK_FORMAT_B8G8R8_SRGB:
return VK_FORMAT_B8G8R8_UNORM;
case VK_FORMAT_R8G8B8A8_SRGB:
return VK_FORMAT_R8G8B8A8_UNORM;
case VK_FORMAT_B8G8R8A8_SRGB:
return VK_FORMAT_B8G8R8A8_UNORM;
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
default:
return format;
}
}
static inline unsigned
vk_format_get_nr_components(VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
return desc->nr_channels;
}
#endif /* VK_FORMAT_H */

View File

@ -0,0 +1,188 @@
/* this is pretty much taken from the gallium one. */
VK_FORMAT_UNDEFINED , plain, 1, 1, u8 , , , , x001, rgb
VK_FORMAT_R4G4_UNORM_PACK8 , plain, 1, 1, un4 , un4 , , , xy01, rgb
VK_FORMAT_R4G4B4A4_UNORM_PACK16 , plain, 1, 1, un4 , un4 , un4 , un4 , wzyx, rgb
VK_FORMAT_B4G4R4A4_UNORM_PACK16 , plain, 1, 1, un4 , un4 , un4 , un4 , wxyz, rgb
VK_FORMAT_R5G6B5_UNORM_PACK16 , plain, 1, 1, un5 , un6 , un5 , , zyx1, rgb
VK_FORMAT_B5G6R5_UNORM_PACK16 , plain, 1, 1, un5 , un6 , un5 , , xyz1, rgb
VK_FORMAT_R5G5B5A1_UNORM_PACK16 , plain, 1, 1, un1 , un5 , un5 , un5 , wzyx, rgb
VK_FORMAT_B5G5R5A1_UNORM_PACK16 , plain, 1, 1, un1 , un5 , un5 , un5 , wxyz, rgb
VK_FORMAT_A1R5G5B5_UNORM_PACK16 , plain, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb
VK_FORMAT_R8_UNORM , plain, 1, 1, un8 , , , , x001, rgb
VK_FORMAT_R8_SNORM , plain, 1, 1, sn8 , , , , x001, rgb
VK_FORMAT_R8_USCALED , plain, 1, 1, us8 , , , , x001, rgb
VK_FORMAT_R8_SSCALED , plain, 1, 1, ss8 , , , , x001, rgb
VK_FORMAT_R8_UINT , plain, 1, 1, up8 , , , , x001, rgb
VK_FORMAT_R8_SINT , plain, 1, 1, sp8 , , , , x001, rgb
VK_FORMAT_R8_SRGB , plain, 1, 1, un8 , , , , x001, srgb
VK_FORMAT_R8G8_UNORM , plain, 1, 1, un8 , un8 , , , xy01, rgb
VK_FORMAT_R8G8_SNORM , plain, 1, 1, sn8 , sn8 , , , xy01, rgb
VK_FORMAT_R8G8_USCALED , plain, 1, 1, us8 , us8 , , , xy01, rgb
VK_FORMAT_R8G8_SSCALED , plain, 1, 1, ss8 , ss8 , , , xy01, rgb
VK_FORMAT_R8G8_UINT , plain, 1, 1, up8 , up8 , , , xy01, rgb
VK_FORMAT_R8G8_SINT , plain, 1, 1, sp8 , sp8 , , , xy01, rgb
VK_FORMAT_R8G8_SRGB , plain, 1, 1, un8 , un8 , , , xy01, srgb
VK_FORMAT_R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , , xyz1, rgb
VK_FORMAT_R8G8B8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , , xyz1, rgb
VK_FORMAT_R8G8B8_USCALED , plain, 1, 1, us8 , us8 , us8 , , xyz1, rgb
VK_FORMAT_R8G8B8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , , xyz1, rgb
VK_FORMAT_R8G8B8_UINT , plain, 1, 1, up8 , up8 , up8 , , xyz1, rgb
VK_FORMAT_R8G8B8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , , xyz1, rgb
VK_FORMAT_R8G8B8_SRGB , plain, 1, 1, un8 , un8 , un8 , , xyz1, srgb
VK_FORMAT_B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , , zyx1, rgb
VK_FORMAT_B8G8R8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , , zyx1, rgb
VK_FORMAT_B8G8R8_USCALED , plain, 1, 1, us8 , us8 , us8 , , zyx1, rgb
VK_FORMAT_B8G8R8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , , zyx1, rgb
VK_FORMAT_B8G8R8_UINT , plain, 1, 1, up8 , up8 , up8 , , zyx1, rgb
VK_FORMAT_B8G8R8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , , zyx1, rgb
VK_FORMAT_B8G8R8_SRGB , plain, 1, 1, un8 , un8 , un8 , , zyx1, srgb
VK_FORMAT_R8G8B8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb
VK_FORMAT_R8G8B8A8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
VK_FORMAT_R8G8B8A8_USCALED , plain, 1, 1, us8 , us8 , us8 , us8 , xyzw, rgb
VK_FORMAT_R8G8B8A8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , ss8 , xyzw, rgb
VK_FORMAT_R8G8B8A8_UINT , plain, 1, 1, up8 , up8 , up8 , up8 , xyzw, rgb
VK_FORMAT_R8G8B8A8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , sp8 , xyzw, rgb
VK_FORMAT_R8G8B8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, srgb
VK_FORMAT_B8G8R8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, rgb
VK_FORMAT_B8G8R8A8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , zyxw, rgb
VK_FORMAT_B8G8R8A8_USCALED , plain, 1, 1, us8 , us8 , us8 , us8 , zyxw, rgb
VK_FORMAT_B8G8R8A8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , ss8 , zyxw, rgb
VK_FORMAT_B8G8R8A8_UINT , plain, 1, 1, up8 , up8 , up8 , up8 , zyxw, rgb
VK_FORMAT_B8G8R8A8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , sp8 , zyxw, rgb
VK_FORMAT_B8G8R8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, srgb
VK_FORMAT_A8B8G8R8_UNORM_PACK32 , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb
VK_FORMAT_A8B8G8R8_SNORM_PACK32 , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
VK_FORMAT_A8B8G8R8_USCALED_PACK32 , plain, 1, 1, us8 , us8 , us8 , us8 , xyzw, rgb
VK_FORMAT_A8B8G8R8_SSCALED_PACK32 , plain, 1, 1, ss8 , ss8 , ss8 , ss8 , xyzw, rgb
VK_FORMAT_A8B8G8R8_UINT_PACK32 , plain, 1, 1, up8 , up8 , up8 , up8 , xyzw, rgb
VK_FORMAT_A8B8G8R8_SINT_PACK32 , plain, 1, 1, sp8 , sp8 , sp8 , sp8 , xyzw, rgb
VK_FORMAT_A8B8G8R8_SRGB_PACK32 , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, srgb
VK_FORMAT_A2R10G10B10_UNORM_PACK32 , plain, 1, 1, un10, un10, un10, un2 , zyxw, rgb
VK_FORMAT_A2R10G10B10_SNORM_PACK32 , plain, 1, 1, sn10, sn10, sn10, sn2 , zyxw, rgb
VK_FORMAT_A2R10G10B10_USCALED_PACK32 , plain, 1, 1, us10, us10, us10, us2 , zyxw, rgb
VK_FORMAT_A2R10G10B10_SSCALED_PACK32 , plain, 1, 1, ss10, ss10, ss10, ss2 , zyxw, rgb
VK_FORMAT_A2R10G10B10_UINT_PACK32 , plain, 1, 1, up10, up10, up10, up2 , zyxw, rgb
VK_FORMAT_A2R10G10B10_SINT_PACK32 , plain, 1, 1, sp10, sp10, sp10, sp2 , zyxw, rgb
VK_FORMAT_A2B10G10R10_UNORM_PACK32 , plain, 1, 1, un10, un10, un10, un2 , xyzw, rgb
VK_FORMAT_A2B10G10R10_SNORM_PACK32 , plain, 1, 1, sn10, sn10, sn10, sn2 , xyzw, rgb
VK_FORMAT_A2B10G10R10_USCALED_PACK32 , plain, 1, 1, us10, us10, us10, us2 , xyzw, rgb
VK_FORMAT_A2B10G10R10_SSCALED_PACK32 , plain, 1, 1, ss10, ss10, ss10, ss2 , xyzw, rgb
VK_FORMAT_A2B10G10R10_UINT_PACK32 , plain, 1, 1, up10, up10, up10, up2 , xyzw, rgb
VK_FORMAT_A2B10G10R10_SINT_PACK32 , plain, 1, 1, sp10, sp10, sp10, sp2 , xyzw, rgb
VK_FORMAT_R16_UNORM , plain, 1, 1, un16, , , , x001, rgb
VK_FORMAT_R16_SNORM , plain, 1, 1, sn16, , , , x001, rgb
VK_FORMAT_R16_USCALED , plain, 1, 1, us16, , , , x001, rgb
VK_FORMAT_R16_SSCALED , plain, 1, 1, ss16, , , , x001, rgb
VK_FORMAT_R16_UINT , plain, 1, 1, up16, , , , x001, rgb
VK_FORMAT_R16_SINT , plain, 1, 1, sp16, , , , x001, rgb
VK_FORMAT_R16_SFLOAT , plain, 1, 1, f16 , , , , x001, rgb
VK_FORMAT_R16G16_UNORM , plain, 1, 1, un16, un16, , , xy01, rgb
VK_FORMAT_R16G16_SNORM , plain, 1, 1, sn16, sn16, , , xy01, rgb
VK_FORMAT_R16G16_USCALED , plain, 1, 1, us16, us16, , , xy01, rgb
VK_FORMAT_R16G16_SSCALED , plain, 1, 1, ss16, ss16, , , xy01, rgb
VK_FORMAT_R16G16_UINT , plain, 1, 1, up16, up16, , , xy01, rgb
VK_FORMAT_R16G16_SINT , plain, 1, 1, sp16, sp16, , , xy01, rgb
VK_FORMAT_R16G16_SFLOAT , plain, 1, 1, f16 , f16 , , , xy01, rgb
VK_FORMAT_R16G16B16_UNORM , plain, 1, 1, un16, un16, un16, , xyz1, rgb
VK_FORMAT_R16G16B16_SNORM , plain, 1, 1, sn16, sn16, sn16, , xyz1, rgb
VK_FORMAT_R16G16B16_USCALED , plain, 1, 1, us16, us16, us16, , xyz1, rgb
VK_FORMAT_R16G16B16_SSCALED , plain, 1, 1, ss16, ss16, ss16, , xyz1, rgb
VK_FORMAT_R16G16B16_UINT , plain, 1, 1, up16, up16, up16, , xyz1, rgb
VK_FORMAT_R16G16B16_SINT , plain, 1, 1, sp16, sp16, sp16, , xyz1, rgb
VK_FORMAT_R16G16B16_SFLOAT , plain, 1, 1, f16 , f16 , f16 , , xyz1, rgb
VK_FORMAT_R16G16B16A16_UNORM , plain, 1, 1, un16, un16, un16, un16, xyzw, rgb
VK_FORMAT_R16G16B16A16_SNORM , plain, 1, 1, sn16, sn16, sn16, sn16, xyzw, rgb
VK_FORMAT_R16G16B16A16_USCALED , plain, 1, 1, us16, us16, us16, us16, xyzw, rgb
VK_FORMAT_R16G16B16A16_SSCALED , plain, 1, 1, ss16, ss16, ss16, ss16, xyzw, rgb
VK_FORMAT_R16G16B16A16_UINT , plain, 1, 1, up16, up16, up16, up16, xyzw, rgb
VK_FORMAT_R16G16B16A16_SINT , plain, 1, 1, sp16, sp16, sp16, sp16, xyzw, rgb
VK_FORMAT_R16G16B16A16_SFLOAT , plain, 1, 1, f16 , f16 , f16 , f16 , xyzw, rgb
VK_FORMAT_R32_UINT , plain, 1, 1, up32, , , , x001, rgb
VK_FORMAT_R32_SINT , plain, 1, 1, sp32, , , , x001, rgb
VK_FORMAT_R32_SFLOAT , plain, 1, 1, f32 , , , , x001, rgb
VK_FORMAT_R32G32_UINT , plain, 1, 1, up32, up32, , , xy01, rgb
VK_FORMAT_R32G32_SINT , plain, 1, 1, sp32, sp32, , , xy01, rgb
VK_FORMAT_R32G32_SFLOAT , plain, 1, 1, f32 , f32 , , , xy01, rgb
VK_FORMAT_R32G32B32_UINT , plain, 1, 1, up32, up32, up32, , xyz1, rgb
VK_FORMAT_R32G32B32_SINT , plain, 1, 1, sp32, sp32, sp32, , xyz1, rgb
VK_FORMAT_R32G32B32_SFLOAT , plain, 1, 1, f32 , f32 , f32 , , xyz1, rgb
VK_FORMAT_R32G32B32A32_UINT , plain, 1, 1, up32, up32, up32, up32, xyzw, rgb
VK_FORMAT_R32G32B32A32_SINT , plain, 1, 1, sp32, sp32, sp32, sp32, xyzw, rgb
VK_FORMAT_R32G32B32A32_SFLOAT , plain, 1, 1, f32 , f32 , f32 , f32 , xyzw, rgb
VK_FORMAT_R64_UINT , plain, 1, 1, up64, , , , x001, rgb
VK_FORMAT_R64_SINT , plain, 1, 1, sp64, , , , x001, rgb
VK_FORMAT_R64_SFLOAT , plain, 1, 1, f64 , , , , x001, rgb
VK_FORMAT_R64G64_UINT , plain, 1, 1, up64, up64, , , xy01, rgb
VK_FORMAT_R64G64_SINT , plain, 1, 1, sp64, sp64, , , xy01, rgb
VK_FORMAT_R64G64_SFLOAT , plain, 1, 1, f64 , f64 , , , xy01, rgb
VK_FORMAT_R64G64B64_UINT , plain, 1, 1, up64, up64, up64, , xyz1, rgb
VK_FORMAT_R64G64B64_SINT , plain, 1, 1, sp64, sp64, sp64, , xyz1, rgb
VK_FORMAT_R64G64B64_SFLOAT , plain, 1, 1, f64 , f64 , f64 , , xyz1, rgb
VK_FORMAT_R64G64B64A64_UINT , plain, 1, 1, up64, up64, up64, up64, xyzw, rgb
VK_FORMAT_R64G64B64A64_SINT , plain, 1, 1, sp64, sp64, sp64, sp64, xyzw, rgb
VK_FORMAT_R64G64B64A64_SFLOAT , plain, 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
VK_FORMAT_B10G11R11_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb
VK_FORMAT_D16_UNORM , plain, 1, 1, un16, , , , x___, zs
VK_FORMAT_X8_D24_UNORM_PACK32 , plain, 1, 1, un24, x8 , , , x___, zs
VK_FORMAT_D32_SFLOAT , plain, 1, 1, f32 , , , , x___, zs
VK_FORMAT_S8_UINT , plain, 1, 1, up8 , , , , _x__, zs
VK_FORMAT_D16_UNORM_S8_UINT , plain, 1, 1, un16, up8 , , , xy__, zs
VK_FORMAT_D24_UNORM_S8_UINT , plain, 1, 1, un24, up8 , , , xy__, zs
VK_FORMAT_D32_SFLOAT_S8_UINT , plain, 1, 1, f32 , up8 , , , xy__, zs
VK_FORMAT_BC1_RGB_UNORM_BLOCK , s3tc, 4, 4, x64 , , , , xyz1, rgb
VK_FORMAT_BC1_RGB_SRGB_BLOCK , s3tc, 4, 4, x64 , , , , xyz1, srgb
VK_FORMAT_BC1_RGBA_UNORM_BLOCK , s3tc, 4, 4, x64 , , , , xyzw, rgb
VK_FORMAT_BC1_RGBA_SRGB_BLOCK , s3tc, 4, 4, x64 , , , , xyzw, srgb
VK_FORMAT_BC2_UNORM_BLOCK , s3tc, 4, 4, x128, , , , xyzw, rgb
VK_FORMAT_BC2_SRGB_BLOCK , s3tc, 4, 4, x128, , , , xyzw, srgb
VK_FORMAT_BC3_UNORM_BLOCK , s3tc, 4, 4, x128, , , , xyzw, rgb
VK_FORMAT_BC3_SRGB_BLOCK , s3tc, 4, 4, x128, , , , xyzw, srgb
VK_FORMAT_BC4_UNORM_BLOCK , rgtc, 4, 4, x64, , , , x001, rgb
VK_FORMAT_BC4_SNORM_BLOCK , rgtc, 4, 4, x64, , , , x001, rgb
VK_FORMAT_BC5_UNORM_BLOCK , rgtc, 4, 4, x128, , , , xy01, rgb
VK_FORMAT_BC5_SNORM_BLOCK , rgtc, 4, 4, x128, , , , xy01, rgb
VK_FORMAT_BC6H_UFLOAT_BLOCK , bptc, 4, 4, x128, , , , xyz1, rgb
VK_FORMAT_BC6H_SFLOAT_BLOCK , bptc, 4, 4, x128, , , , xyz1, rgb
VK_FORMAT_BC7_UNORM_BLOCK , bptc, 4, 4, x128, , , , xyzw, rgb
VK_FORMAT_BC7_SRGB_BLOCK , bptc, 4, 4, x128, , , , xyzw, srgb
VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK , etc, 4, 4, x64, , , , xyz1, rgb
VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK , etc, 4, 4, x64, , , , xyz1, srgb
VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK , etc, 4, 4, x64, , , , xyzw, rgb
VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK , etc, 4, 4, x64, , , , xyzw, srgb
VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK , etc, 4, 4, x128, , , , xyzw, rgb
VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK , etc, 4, 4, x128, , , , xyzw, srgb
VK_FORMAT_EAC_R11_UNORM_BLOCK , etc, 4, 4, x64, , , , x001, rgb
VK_FORMAT_EAC_R11_SNORM_BLOCK , etc, 4, 4, x64, , , , x001, rgb
VK_FORMAT_EAC_R11G11_UNORM_BLOCK , etc, 4, 4, x128, , , , xy01, rgb
VK_FORMAT_EAC_R11G11_SNORM_BLOCK , etc, 4, 4, x128, , , , xy01, rgb
VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1 /* this is pretty much taken from the gallium one. */
2 VK_FORMAT_UNDEFINED , plain, 1, 1, u8 , , , , x001, rgb
3 VK_FORMAT_R4G4_UNORM_PACK8 , plain, 1, 1, un4 , un4 , , , xy01, rgb
4 VK_FORMAT_R4G4B4A4_UNORM_PACK16 , plain, 1, 1, un4 , un4 , un4 , un4 , wzyx, rgb
5 VK_FORMAT_B4G4R4A4_UNORM_PACK16 , plain, 1, 1, un4 , un4 , un4 , un4 , wxyz, rgb
6 VK_FORMAT_R5G6B5_UNORM_PACK16 , plain, 1, 1, un5 , un6 , un5 , , zyx1, rgb
7 VK_FORMAT_B5G6R5_UNORM_PACK16 , plain, 1, 1, un5 , un6 , un5 , , xyz1, rgb
8 VK_FORMAT_R5G5B5A1_UNORM_PACK16 , plain, 1, 1, un1 , un5 , un5 , un5 , wzyx, rgb
9 VK_FORMAT_B5G5R5A1_UNORM_PACK16 , plain, 1, 1, un1 , un5 , un5 , un5 , wxyz, rgb
10 VK_FORMAT_A1R5G5B5_UNORM_PACK16 , plain, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb
11 VK_FORMAT_R8_UNORM , plain, 1, 1, un8 , , , , x001, rgb
12 VK_FORMAT_R8_SNORM , plain, 1, 1, sn8 , , , , x001, rgb
13 VK_FORMAT_R8_USCALED , plain, 1, 1, us8 , , , , x001, rgb
14 VK_FORMAT_R8_SSCALED , plain, 1, 1, ss8 , , , , x001, rgb
15 VK_FORMAT_R8_UINT , plain, 1, 1, up8 , , , , x001, rgb
16 VK_FORMAT_R8_SINT , plain, 1, 1, sp8 , , , , x001, rgb
17 VK_FORMAT_R8_SRGB , plain, 1, 1, un8 , , , , x001, srgb
18 VK_FORMAT_R8G8_UNORM , plain, 1, 1, un8 , un8 , , , xy01, rgb
19 VK_FORMAT_R8G8_SNORM , plain, 1, 1, sn8 , sn8 , , , xy01, rgb
20 VK_FORMAT_R8G8_USCALED , plain, 1, 1, us8 , us8 , , , xy01, rgb
21 VK_FORMAT_R8G8_SSCALED , plain, 1, 1, ss8 , ss8 , , , xy01, rgb
22 VK_FORMAT_R8G8_UINT , plain, 1, 1, up8 , up8 , , , xy01, rgb
23 VK_FORMAT_R8G8_SINT , plain, 1, 1, sp8 , sp8 , , , xy01, rgb
24 VK_FORMAT_R8G8_SRGB , plain, 1, 1, un8 , un8 , , , xy01, srgb
25 VK_FORMAT_R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , , xyz1, rgb
26 VK_FORMAT_R8G8B8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , , xyz1, rgb
27 VK_FORMAT_R8G8B8_USCALED , plain, 1, 1, us8 , us8 , us8 , , xyz1, rgb
28 VK_FORMAT_R8G8B8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , , xyz1, rgb
29 VK_FORMAT_R8G8B8_UINT , plain, 1, 1, up8 , up8 , up8 , , xyz1, rgb
30 VK_FORMAT_R8G8B8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , , xyz1, rgb
31 VK_FORMAT_R8G8B8_SRGB , plain, 1, 1, un8 , un8 , un8 , , xyz1, srgb
32 VK_FORMAT_B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , , zyx1, rgb
33 VK_FORMAT_B8G8R8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , , zyx1, rgb
34 VK_FORMAT_B8G8R8_USCALED , plain, 1, 1, us8 , us8 , us8 , , zyx1, rgb
35 VK_FORMAT_B8G8R8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , , zyx1, rgb
36 VK_FORMAT_B8G8R8_UINT , plain, 1, 1, up8 , up8 , up8 , , zyx1, rgb
37 VK_FORMAT_B8G8R8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , , zyx1, rgb
38 VK_FORMAT_B8G8R8_SRGB , plain, 1, 1, un8 , un8 , un8 , , zyx1, srgb
39 VK_FORMAT_R8G8B8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb
40 VK_FORMAT_R8G8B8A8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
41 VK_FORMAT_R8G8B8A8_USCALED , plain, 1, 1, us8 , us8 , us8 , us8 , xyzw, rgb
42 VK_FORMAT_R8G8B8A8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , ss8 , xyzw, rgb
43 VK_FORMAT_R8G8B8A8_UINT , plain, 1, 1, up8 , up8 , up8 , up8 , xyzw, rgb
44 VK_FORMAT_R8G8B8A8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , sp8 , xyzw, rgb
45 VK_FORMAT_R8G8B8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, srgb
46 VK_FORMAT_B8G8R8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, rgb
47 VK_FORMAT_B8G8R8A8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , zyxw, rgb
48 VK_FORMAT_B8G8R8A8_USCALED , plain, 1, 1, us8 , us8 , us8 , us8 , zyxw, rgb
49 VK_FORMAT_B8G8R8A8_SSCALED , plain, 1, 1, ss8 , ss8 , ss8 , ss8 , zyxw, rgb
50 VK_FORMAT_B8G8R8A8_UINT , plain, 1, 1, up8 , up8 , up8 , up8 , zyxw, rgb
51 VK_FORMAT_B8G8R8A8_SINT , plain, 1, 1, sp8 , sp8 , sp8 , sp8 , zyxw, rgb
52 VK_FORMAT_B8G8R8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, srgb
53 VK_FORMAT_A8B8G8R8_UNORM_PACK32 , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb
54 VK_FORMAT_A8B8G8R8_SNORM_PACK32 , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
55 VK_FORMAT_A8B8G8R8_USCALED_PACK32 , plain, 1, 1, us8 , us8 , us8 , us8 , xyzw, rgb
56 VK_FORMAT_A8B8G8R8_SSCALED_PACK32 , plain, 1, 1, ss8 , ss8 , ss8 , ss8 , xyzw, rgb
57 VK_FORMAT_A8B8G8R8_UINT_PACK32 , plain, 1, 1, up8 , up8 , up8 , up8 , xyzw, rgb
58 VK_FORMAT_A8B8G8R8_SINT_PACK32 , plain, 1, 1, sp8 , sp8 , sp8 , sp8 , xyzw, rgb
59 VK_FORMAT_A8B8G8R8_SRGB_PACK32 , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, srgb
60 VK_FORMAT_A2R10G10B10_UNORM_PACK32 , plain, 1, 1, un10, un10, un10, un2 , zyxw, rgb
61 VK_FORMAT_A2R10G10B10_SNORM_PACK32 , plain, 1, 1, sn10, sn10, sn10, sn2 , zyxw, rgb
62 VK_FORMAT_A2R10G10B10_USCALED_PACK32 , plain, 1, 1, us10, us10, us10, us2 , zyxw, rgb
63 VK_FORMAT_A2R10G10B10_SSCALED_PACK32 , plain, 1, 1, ss10, ss10, ss10, ss2 , zyxw, rgb
64 VK_FORMAT_A2R10G10B10_UINT_PACK32 , plain, 1, 1, up10, up10, up10, up2 , zyxw, rgb
65 VK_FORMAT_A2R10G10B10_SINT_PACK32 , plain, 1, 1, sp10, sp10, sp10, sp2 , zyxw, rgb
66 VK_FORMAT_A2B10G10R10_UNORM_PACK32 , plain, 1, 1, un10, un10, un10, un2 , xyzw, rgb
67 VK_FORMAT_A2B10G10R10_SNORM_PACK32 , plain, 1, 1, sn10, sn10, sn10, sn2 , xyzw, rgb
68 VK_FORMAT_A2B10G10R10_USCALED_PACK32 , plain, 1, 1, us10, us10, us10, us2 , xyzw, rgb
69 VK_FORMAT_A2B10G10R10_SSCALED_PACK32 , plain, 1, 1, ss10, ss10, ss10, ss2 , xyzw, rgb
70 VK_FORMAT_A2B10G10R10_UINT_PACK32 , plain, 1, 1, up10, up10, up10, up2 , xyzw, rgb
71 VK_FORMAT_A2B10G10R10_SINT_PACK32 , plain, 1, 1, sp10, sp10, sp10, sp2 , xyzw, rgb
72 VK_FORMAT_R16_UNORM , plain, 1, 1, un16, , , , x001, rgb
73 VK_FORMAT_R16_SNORM , plain, 1, 1, sn16, , , , x001, rgb
74 VK_FORMAT_R16_USCALED , plain, 1, 1, us16, , , , x001, rgb
75 VK_FORMAT_R16_SSCALED , plain, 1, 1, ss16, , , , x001, rgb
76 VK_FORMAT_R16_UINT , plain, 1, 1, up16, , , , x001, rgb
77 VK_FORMAT_R16_SINT , plain, 1, 1, sp16, , , , x001, rgb
78 VK_FORMAT_R16_SFLOAT , plain, 1, 1, f16 , , , , x001, rgb
79 VK_FORMAT_R16G16_UNORM , plain, 1, 1, un16, un16, , , xy01, rgb
80 VK_FORMAT_R16G16_SNORM , plain, 1, 1, sn16, sn16, , , xy01, rgb
81 VK_FORMAT_R16G16_USCALED , plain, 1, 1, us16, us16, , , xy01, rgb
82 VK_FORMAT_R16G16_SSCALED , plain, 1, 1, ss16, ss16, , , xy01, rgb
83 VK_FORMAT_R16G16_UINT , plain, 1, 1, up16, up16, , , xy01, rgb
84 VK_FORMAT_R16G16_SINT , plain, 1, 1, sp16, sp16, , , xy01, rgb
85 VK_FORMAT_R16G16_SFLOAT , plain, 1, 1, f16 , f16 , , , xy01, rgb
86 VK_FORMAT_R16G16B16_UNORM , plain, 1, 1, un16, un16, un16, , xyz1, rgb
87 VK_FORMAT_R16G16B16_SNORM , plain, 1, 1, sn16, sn16, sn16, , xyz1, rgb
88 VK_FORMAT_R16G16B16_USCALED , plain, 1, 1, us16, us16, us16, , xyz1, rgb
89 VK_FORMAT_R16G16B16_SSCALED , plain, 1, 1, ss16, ss16, ss16, , xyz1, rgb
90 VK_FORMAT_R16G16B16_UINT , plain, 1, 1, up16, up16, up16, , xyz1, rgb
91 VK_FORMAT_R16G16B16_SINT , plain, 1, 1, sp16, sp16, sp16, , xyz1, rgb
92 VK_FORMAT_R16G16B16_SFLOAT , plain, 1, 1, f16 , f16 , f16 , , xyz1, rgb
93 VK_FORMAT_R16G16B16A16_UNORM , plain, 1, 1, un16, un16, un16, un16, xyzw, rgb
94 VK_FORMAT_R16G16B16A16_SNORM , plain, 1, 1, sn16, sn16, sn16, sn16, xyzw, rgb
95 VK_FORMAT_R16G16B16A16_USCALED , plain, 1, 1, us16, us16, us16, us16, xyzw, rgb
96 VK_FORMAT_R16G16B16A16_SSCALED , plain, 1, 1, ss16, ss16, ss16, ss16, xyzw, rgb
97 VK_FORMAT_R16G16B16A16_UINT , plain, 1, 1, up16, up16, up16, up16, xyzw, rgb
98 VK_FORMAT_R16G16B16A16_SINT , plain, 1, 1, sp16, sp16, sp16, sp16, xyzw, rgb
99 VK_FORMAT_R16G16B16A16_SFLOAT , plain, 1, 1, f16 , f16 , f16 , f16 , xyzw, rgb
100 VK_FORMAT_R32_UINT , plain, 1, 1, up32, , , , x001, rgb
101 VK_FORMAT_R32_SINT , plain, 1, 1, sp32, , , , x001, rgb
102 VK_FORMAT_R32_SFLOAT , plain, 1, 1, f32 , , , , x001, rgb
103 VK_FORMAT_R32G32_UINT , plain, 1, 1, up32, up32, , , xy01, rgb
104 VK_FORMAT_R32G32_SINT , plain, 1, 1, sp32, sp32, , , xy01, rgb
105 VK_FORMAT_R32G32_SFLOAT , plain, 1, 1, f32 , f32 , , , xy01, rgb
106 VK_FORMAT_R32G32B32_UINT , plain, 1, 1, up32, up32, up32, , xyz1, rgb
107 VK_FORMAT_R32G32B32_SINT , plain, 1, 1, sp32, sp32, sp32, , xyz1, rgb
108 VK_FORMAT_R32G32B32_SFLOAT , plain, 1, 1, f32 , f32 , f32 , , xyz1, rgb
109 VK_FORMAT_R32G32B32A32_UINT , plain, 1, 1, up32, up32, up32, up32, xyzw, rgb
110 VK_FORMAT_R32G32B32A32_SINT , plain, 1, 1, sp32, sp32, sp32, sp32, xyzw, rgb
111 VK_FORMAT_R32G32B32A32_SFLOAT , plain, 1, 1, f32 , f32 , f32 , f32 , xyzw, rgb
112 VK_FORMAT_R64_UINT , plain, 1, 1, up64, , , , x001, rgb
113 VK_FORMAT_R64_SINT , plain, 1, 1, sp64, , , , x001, rgb
114 VK_FORMAT_R64_SFLOAT , plain, 1, 1, f64 , , , , x001, rgb
115 VK_FORMAT_R64G64_UINT , plain, 1, 1, up64, up64, , , xy01, rgb
116 VK_FORMAT_R64G64_SINT , plain, 1, 1, sp64, sp64, , , xy01, rgb
117 VK_FORMAT_R64G64_SFLOAT , plain, 1, 1, f64 , f64 , , , xy01, rgb
118 VK_FORMAT_R64G64B64_UINT , plain, 1, 1, up64, up64, up64, , xyz1, rgb
119 VK_FORMAT_R64G64B64_SINT , plain, 1, 1, sp64, sp64, sp64, , xyz1, rgb
120 VK_FORMAT_R64G64B64_SFLOAT , plain, 1, 1, f64 , f64 , f64 , , xyz1, rgb
121 VK_FORMAT_R64G64B64A64_UINT , plain, 1, 1, up64, up64, up64, up64, xyzw, rgb
122 VK_FORMAT_R64G64B64A64_SINT , plain, 1, 1, sp64, sp64, sp64, sp64, xyzw, rgb
123 VK_FORMAT_R64G64B64A64_SFLOAT , plain, 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
124 VK_FORMAT_B10G11R11_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb
125 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 , other, 1, 1, x32 , , , , xyz1, rgb
126 VK_FORMAT_D16_UNORM , plain, 1, 1, un16, , , , x___, zs
127 VK_FORMAT_X8_D24_UNORM_PACK32 , plain, 1, 1, un24, x8 , , , x___, zs
128 VK_FORMAT_D32_SFLOAT , plain, 1, 1, f32 , , , , x___, zs
129 VK_FORMAT_S8_UINT , plain, 1, 1, up8 , , , , _x__, zs
130 VK_FORMAT_D16_UNORM_S8_UINT , plain, 1, 1, un16, up8 , , , xy__, zs
131 VK_FORMAT_D24_UNORM_S8_UINT , plain, 1, 1, un24, up8 , , , xy__, zs
132 VK_FORMAT_D32_SFLOAT_S8_UINT , plain, 1, 1, f32 , up8 , , , xy__, zs
133 VK_FORMAT_BC1_RGB_UNORM_BLOCK , s3tc, 4, 4, x64 , , , , xyz1, rgb
134 VK_FORMAT_BC1_RGB_SRGB_BLOCK , s3tc, 4, 4, x64 , , , , xyz1, srgb
135 VK_FORMAT_BC1_RGBA_UNORM_BLOCK , s3tc, 4, 4, x64 , , , , xyzw, rgb
136 VK_FORMAT_BC1_RGBA_SRGB_BLOCK , s3tc, 4, 4, x64 , , , , xyzw, srgb
137 VK_FORMAT_BC2_UNORM_BLOCK , s3tc, 4, 4, x128, , , , xyzw, rgb
138 VK_FORMAT_BC2_SRGB_BLOCK , s3tc, 4, 4, x128, , , , xyzw, srgb
139 VK_FORMAT_BC3_UNORM_BLOCK , s3tc, 4, 4, x128, , , , xyzw, rgb
140 VK_FORMAT_BC3_SRGB_BLOCK , s3tc, 4, 4, x128, , , , xyzw, srgb
141 VK_FORMAT_BC4_UNORM_BLOCK , rgtc, 4, 4, x64, , , , x001, rgb
142 VK_FORMAT_BC4_SNORM_BLOCK , rgtc, 4, 4, x64, , , , x001, rgb
143 VK_FORMAT_BC5_UNORM_BLOCK , rgtc, 4, 4, x128, , , , xy01, rgb
144 VK_FORMAT_BC5_SNORM_BLOCK , rgtc, 4, 4, x128, , , , xy01, rgb
145 VK_FORMAT_BC6H_UFLOAT_BLOCK , bptc, 4, 4, x128, , , , xyz1, rgb
146 VK_FORMAT_BC6H_SFLOAT_BLOCK , bptc, 4, 4, x128, , , , xyz1, rgb
147 VK_FORMAT_BC7_UNORM_BLOCK , bptc, 4, 4, x128, , , , xyzw, rgb
148 VK_FORMAT_BC7_SRGB_BLOCK , bptc, 4, 4, x128, , , , xyzw, srgb
149 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK , etc, 4, 4, x64, , , , xyz1, rgb
150 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK , etc, 4, 4, x64, , , , xyz1, srgb
151 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK , etc, 4, 4, x64, , , , xyzw, rgb
152 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK , etc, 4, 4, x64, , , , xyzw, srgb
153 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK , etc, 4, 4, x128, , , , xyzw, rgb
154 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK , etc, 4, 4, x128, , , , xyzw, srgb
155 VK_FORMAT_EAC_R11_UNORM_BLOCK , etc, 4, 4, x64, , , , x001, rgb
156 VK_FORMAT_EAC_R11_SNORM_BLOCK , etc, 4, 4, x64, , , , x001, rgb
157 VK_FORMAT_EAC_R11G11_UNORM_BLOCK , etc, 4, 4, x128, , , , xy01, rgb
158 VK_FORMAT_EAC_R11G11_SNORM_BLOCK , etc, 4, 4, x128, , , , xy01, rgb
159 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
160 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
161 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
162 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
163 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
164 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
165 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
166 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
167 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
168 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
169 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
170 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
171 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
172 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
173 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
174 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
175 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
176 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
177 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
178 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
179 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
180 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
181 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
182 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
183 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
184 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
185 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
186 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,

View File

@ -0,0 +1,388 @@
'''
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* 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, sub license, 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 (including the
* next paragraph) 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 NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
*
**************************************************************************/
'''
VOID, UNSIGNED, SIGNED, FIXED, FLOAT = range(5)
SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE, = range(7)
PLAIN = 'plain'
SCALED = 'scaled'
RGB = 'rgb'
SRGB = 'srgb'
YUV = 'yuv'
ZS = 'zs'
def is_pot(x):
return (x & (x - 1)) == 0
VERY_LARGE = 99999999999999999999999
class Channel:
'''Describe the channel of a color channel.'''
def __init__(self, type, norm, pure, scaled, size, name = ''):
self.type = type
self.norm = norm
self.pure = pure
self.size = size
self.scaled = scaled
self.sign = type in (SIGNED, FIXED, FLOAT)
self.name = name
def __str__(self):
s = str(self.type)
if self.norm:
s += 'n'
if self.pure:
s += 'p'
if self.scaled:
s += 's'
s += str(self.size)
return s
def __eq__(self, other):
return (other is not None and
self.type == other.type and
self.norm == other.norm and
self.pure == other.pure and
self.size == other.size and
self.scaled == other.scaled)
def max(self):
'''Maximum representable number.'''
if self.type == FLOAT:
return VERY_LARGE
if self.type == FIXED:
return (1 << (self.size/2)) - 1
if self.norm:
return 1
if self.type == UNSIGNED:
return (1 << self.size) - 1
if self.type == SIGNED:
return (1 << (self.size - 1)) - 1
assert False
def min(self):
'''Minimum representable number.'''
if self.type == FLOAT:
return -VERY_LARGE
if self.type == FIXED:
return -(1 << (self.size/2))
if self.type == UNSIGNED:
return 0
if self.norm:
return -1
if self.type == SIGNED:
return -(1 << (self.size - 1))
assert False
class Format:
'''Describe a pixel format.'''
def __init__(self, name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace):
self.name = name
self.layout = layout
self.block_width = block_width
self.block_height = block_height
self.le_channels = le_channels
self.le_swizzles = le_swizzles
self.be_channels = be_channels
self.be_swizzles = be_swizzles
self.name = name
self.colorspace = colorspace
def __str__(self):
return self.name
def short_name(self):
'''Make up a short norm for a format, suitable to be used as suffix in
function names.'''
name = self.name
if name.startswith('VK_FORMAT_'):
name = name[len('VK_FORMAT_'):]
name = name.lower()
return name
def block_size(self):
size = 0
for channel in self.le_channels:
size += channel.size
return size
def nr_channels(self):
nr_channels = 0
for channel in self.le_channels:
if channel.size:
nr_channels += 1
return nr_channels
def array_element(self):
if self.layout != PLAIN:
return None
ref_channel = self.le_channels[0]
if ref_channel.type == VOID:
ref_channel = self.le_channels[1]
for channel in self.le_channels:
if channel.size and (channel.size != ref_channel.size or channel.size % 8):
return None
if channel.type != VOID:
if channel.type != ref_channel.type:
return None
if channel.norm != ref_channel.norm:
return None
if channel.pure != ref_channel.pure:
return None
if channel.scaled != ref_channel.scaled:
return None
return ref_channel
def is_array(self):
return self.array_element() != None
def is_mixed(self):
if self.layout != PLAIN:
return False
ref_channel = self.le_channels[0]
if ref_channel.type == VOID:
ref_channel = self.le_channels[1]
for channel in self.le_channels[1:]:
if channel.type != VOID:
if channel.type != ref_channel.type:
return True
if channel.norm != ref_channel.norm:
return True
if channel.pure != ref_channel.pure:
return True
if channel.scaled != ref_channel.scaled:
return True
return False
def is_pot(self):
return is_pot(self.block_size())
def is_int(self):
if self.layout != PLAIN:
return False
for channel in self.le_channels:
if channel.type not in (VOID, UNSIGNED, SIGNED):
return False
return True
def is_float(self):
if self.layout != PLAIN:
return False
for channel in self.le_channels:
if channel.type not in (VOID, FLOAT):
return False
return True
def is_bitmask(self):
if self.layout != PLAIN:
return False
if self.block_size() not in (8, 16, 32):
return False
for channel in self.le_channels:
if channel.type not in (VOID, UNSIGNED, SIGNED):
return False
return True
def is_pure_color(self):
if self.layout != PLAIN or self.colorspace == ZS:
return False
pures = [channel.pure
for channel in self.le_channels
if channel.type != VOID]
for x in pures:
assert x == pures[0]
return pures[0]
def channel_type(self):
types = [channel.type
for channel in self.le_channels
if channel.type != VOID]
for x in types:
assert x == types[0]
return types[0]
def is_pure_signed(self):
return self.is_pure_color() and self.channel_type() == SIGNED
def is_pure_unsigned(self):
return self.is_pure_color() and self.channel_type() == UNSIGNED
def has_channel(self, id):
return self.le_swizzles[id] != SWIZZLE_NONE
def has_depth(self):
return self.colorspace == ZS and self.has_channel(0)
def has_stencil(self):
return self.colorspace == ZS and self.has_channel(1)
def stride(self):
return self.block_size()/8
_type_parse_map = {
'': VOID,
'x': VOID,
'u': UNSIGNED,
's': SIGNED,
'h': FIXED,
'f': FLOAT,
}
_swizzle_parse_map = {
'x': SWIZZLE_X,
'y': SWIZZLE_Y,
'z': SWIZZLE_Z,
'w': SWIZZLE_W,
'0': SWIZZLE_0,
'1': SWIZZLE_1,
'_': SWIZZLE_NONE,
}
def _parse_channels(fields, layout, colorspace, swizzles):
if layout == PLAIN:
names = ['']*4
if colorspace in (RGB, SRGB):
for i in range(4):
swizzle = swizzles[i]
if swizzle < 4:
names[swizzle] += 'rgba'[i]
elif colorspace == ZS:
for i in range(4):
swizzle = swizzles[i]
if swizzle < 4:
names[swizzle] += 'zs'[i]
else:
assert False
for i in range(4):
if names[i] == '':
names[i] = 'x'
else:
names = ['x', 'y', 'z', 'w']
channels = []
for i in range(0, 4):
field = fields[i]
if field:
type = _type_parse_map[field[0]]
if field[1] == 'n':
norm = True
pure = False
scaled = False
size = int(field[2:])
elif field[1] == 'p':
pure = True
norm = False
scaled = False
size = int(field[2:])
elif field[1] == 's':
pure = False
norm = False
scaled = True
size = int(field[2:])
else:
norm = False
pure = False
scaled = False
size = int(field[1:])
else:
type = VOID
norm = False
pure = False
scaled = False
size = 0
channel = Channel(type, norm, pure, scaled, size, names[i])
channels.append(channel)
return channels
def parse(filename):
'''Parse the format description in CSV format in terms of the
Channel and Format classes above.'''
stream = open(filename)
formats = []
for line in stream:
try:
comment = line.index('#')
except ValueError:
pass
else:
line = line[:comment]
line = line.strip()
if not line:
continue
fields = [field.strip() for field in line.split(',')]
if len (fields) < 10:
continue
if len (fields) == 10:
fields += fields[4:9]
assert len (fields) == 15
name = fields[0]
layout = fields[1]
block_width, block_height = map(int, fields[2:4])
colorspace = fields[9]
le_swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]]
le_channels = _parse_channels(fields[4:8], layout, colorspace, le_swizzles)
be_swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[14]]
be_channels = _parse_channels(fields[10:14], layout, colorspace, be_swizzles)
le_shift = 0
for channel in le_channels:
channel.shift = le_shift
le_shift += channel.size
be_shift = 0
for channel in be_channels[3::-1]:
channel.shift = be_shift
be_shift += channel.size
assert le_shift == be_shift
for i in range(4):
assert (le_swizzles[i] != SWIZZLE_NONE) == (be_swizzles[i] != SWIZZLE_NONE)
format = Format(name, layout, block_width, block_height, le_channels, le_swizzles, be_channels, be_swizzles, colorspace)
formats.append(format)
return formats

View File

@ -0,0 +1,173 @@
from __future__ import print_function
CopyRight = '''
/**************************************************************************
*
* Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* 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, sub license, 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 (including the
* next paragraph) 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 NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
*
**************************************************************************/
'''
import sys
from vk_format_parse import *
def layout_map(layout):
return 'VK_FORMAT_LAYOUT_' + str(layout).upper()
def colorspace_map(colorspace):
return 'VK_FORMAT_COLORSPACE_' + str(colorspace).upper()
colorspace_channels_map = {
'rgb': ['r', 'g', 'b', 'a'],
'srgb': ['sr', 'sg', 'sb', 'a'],
'zs': ['z', 's'],
'yuv': ['y', 'u', 'v'],
}
type_map = {
VOID: "VK_FORMAT_TYPE_VOID",
UNSIGNED: "VK_FORMAT_TYPE_UNSIGNED",
SIGNED: "VK_FORMAT_TYPE_SIGNED",
FIXED: "VK_FORMAT_TYPE_FIXED",
FLOAT: "VK_FORMAT_TYPE_FLOAT",
}
def bool_map(value):
if value:
return "true"
else:
return "false"
swizzle_map = {
SWIZZLE_X: "VK_SWIZZLE_X",
SWIZZLE_Y: "VK_SWIZZLE_Y",
SWIZZLE_Z: "VK_SWIZZLE_Z",
SWIZZLE_W: "VK_SWIZZLE_W",
SWIZZLE_0: "VK_SWIZZLE_0",
SWIZZLE_1: "VK_SWIZZLE_1",
SWIZZLE_NONE: "VK_SWIZZLE_NONE",
}
def print_channels(format, func):
if format.nr_channels() <= 1:
func(format.le_channels, format.le_swizzles)
else:
print('#ifdef PIPE_ARCH_BIG_ENDIAN')
func(format.be_channels, format.be_swizzles)
print('#else')
func(format.le_channels, format.le_swizzles)
print('#endif')
def write_format_table(formats):
print('/* This file is autogenerated by vk_format_table.py from vk_format_layout.csv. Do not edit directly. */')
print()
# This will print the copyright message on the top of this file
print(CopyRight.strip())
print()
print('#include "stdbool.h"')
print('#include "vk_format.h"')
print()
def do_channel_array(channels, swizzles):
print(" {")
for i in range(4):
channel = channels[i]
if i < 3:
sep = ","
else:
sep = ""
if channel.size:
print(" {%s, %s, %s, %s, %u, %u}%s\t/* %s = %s */" % (type_map[channel.type], bool_map(channel.norm), bool_map(channel.pure), bool_map(channel.scaled), channel.size, channel.shift, sep, "xyzw"[i], channel.name))
else:
print(" {0, 0, 0, 0, 0}%s" % (sep,))
print(" },")
def do_swizzle_array(channels, swizzles):
print(" {")
for i in range(4):
swizzle = swizzles[i]
if i < 3:
sep = ","
else:
sep = ""
try:
comment = colorspace_channels_map[format.colorspace][i]
except (KeyError, IndexError):
comment = 'ignored'
print(" %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment))
print(" },")
for format in formats:
print('static const struct vk_format_description')
print('vk_format_%s_description = {' % (format.short_name(),))
print(" %s," % (format.name,))
print(" \"%s\"," % (format.name,))
print(" \"%s\"," % (format.short_name(),))
print(" {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size()))
print(" %s," % (layout_map(format.layout),))
print(" %u,\t/* nr_channels */" % (format.nr_channels(),))
print(" %s,\t/* is_array */" % (bool_map(format.is_array()),))
print(" %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),))
print(" %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),))
print_channels(format, do_channel_array)
print_channels(format, do_swizzle_array)
print(" %s," % (colorspace_map(format.colorspace),))
print("};")
print()
print("const struct vk_format_description *")
print("vk_format_description(VkFormat format)")
print("{")
print(" if (format > VK_FORMAT_END_RANGE) {")
print(" return NULL;")
print(" }")
print()
print(" switch (format) {")
for format in formats:
print(" case %s:" % format.name)
print(" return &vk_format_%s_description;" % (format.short_name(),))
print(" default:")
print(" return NULL;")
print(" }")
print("}")
print()
def main():
formats = []
for arg in sys.argv[1:]:
formats.extend(parse(arg))
write_format_table(formats)
if __name__ == '__main__':
main()

View File

@ -64,7 +64,7 @@ endif
if with_gallium_vc4 or with_gallium_v3d
subdir('broadcom')
endif
if with_gallium_freedreno
if with_gallium_freedreno or with_freedreno_vk
subdir('freedreno')
endif
if with_dri_i965 or with_intel_vk or with_gallium_iris