This commit is contained in:
2026-06-14 19:09:18 +01:00
parent 14bd1a9271
commit 13fa90a0e9
3958 changed files with 999286 additions and 4 deletions
+8
View File
@@ -0,0 +1,8 @@
# Copyright 2019-2020 The Khronos Group Inc.
# SPDX-License-Identifier: Apache-2.0
# Build output
out
# User generated project files.
build
+12
View File
@@ -0,0 +1,12 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/KhronosGroup/dfdutils.git
branch = main
commit = 854792a6ced4cb7cce64f26bf297bf7ea294a9b6
parent = 928612a718eaaf0a47e8ae6e5b74b13ac16637b1
method = merge
cmdver = 0.4.3
+7
View File
@@ -0,0 +1,7 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: dfdutils
Source: https://github.com/KhronosGroup/dfdutils
Files: vulkan/*.h
Copyright: 2014-2020 The Khronos Group Inc.
License: Apache-2.0
+78
View File
@@ -0,0 +1,78 @@
# Copyright 2019-2020 The Khronos Group Inc.
# SPDX-License-Identifier: Apache-2.0
# CI build script for Travis.
# See https://docs.travis-ci.com/user/multi-os/ for more info.
language: cpp
matrix:
include:
- os: linux
addons:
dist: focal
env:
- VULKAN_SDK_VER="1.2.176"
compiler: gcc # clang is tested by macOS build
- os: osx
env:
- VULKAN_SDK_VER="1.2.176.1"
- VULKAN_INSTALL_DIR="$HOME/build/vulkansdk-macos-$VULKAN_SDK_VER"
- VULKAN_SDK="$VULKAN_INSTALL_DIR/macOS"
compiler: clang
osx_image: xcode13.2
#env:
#global:
# Phase 1: Git clone - done automatically.
# Phase 2: Install apt addons.
# Phase 3: Install cache components - Currently not using a cache
# then the following phases:
before_install:
install:
- |
case "${TRAVIS_OS_NAME:-linux}" in
linux)
# No need to install git-lfs. It is part of Travis's Ubuntu environment.
sudo apt-get -qq update &&
sudo apt-get -qq install doxygen &&
pip3 install reuse
;;
osx)
brew install doxygen
;;
esac
#- pushd ../..
#- git clone https://github.com/msc-/gyp
#- cd gyp && sudo ./setup.py install && cd ..
#- popd
before_script:
script:
- |
case "${TRAVIS_OS_NAME:-linux}" in
linux)
reuse lint &&
make
;;
osx)
make
;;
esac
# Errors in something run in after_success: don't cause the build to fail so don't use.
deploy:
provider: pages
edge: true # Use bleeding edge (dplv2)
github-token: $GITHUB_TOKEN # Set in the settings page of your repository, as a secure variable
local-dir: out/doc/html
on:
branch: master
condition: $TRAVIS_OS_NAME = osx
#tags: true
# vim:ai:ts=4:sts=2:sw=2:expandtab
+11
View File
@@ -0,0 +1,11 @@
// Copyright (c) 2018-2020 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0
= Code of Conduct
A reminder that this issue tracker is managed by the Khronos Group.
Interactions here should follow the
https://www.khronos.org/developers/code-of-conduct[Khronos Code of Conduct],
which prohibits aggressive or derogatory language. Please keep the
discussion friendly and civil.
+654
View File
@@ -0,0 +1,654 @@
/* The Khronos Data Format Specification (version 1.4.0) */
/*
** Copyright 2015-2025 The Khronos Group Inc.
** SPDX-License-Identifier: Apache-2.0
*/
/* This header defines a structure that can describe the layout of image
formats in memory. This means that the data format is transparent to
the application, and the expectation is that this should be used when
the layout is defined external to the API. Many Khronos APIs deliberately
keep the internal layout of images opaque, to allow proprietary layouts
and optimisations. This structure is not appropriate for describing
opaque layouts. */
/* We stick to standard C89 constructs for simplicity and portability. */
#ifndef _KHR_DATA_FORMAT_H_
#define _KHR_DATA_FORMAT_H_
/* Accessors */
typedef enum _khr_word_e {
KHR_DF_WORD_VENDORID = 0U,
KHR_DF_WORD_DESCRIPTORTYPE = 0U,
KHR_DF_WORD_VERSIONNUMBER = 1U,
KHR_DF_WORD_DESCRIPTORBLOCKSIZE = 1U,
KHR_DF_WORD_MODEL = 2U,
KHR_DF_WORD_PRIMARIES = 2U,
KHR_DF_WORD_TRANSFER = 2U,
KHR_DF_WORD_FLAGS = 2U,
KHR_DF_WORD_TEXELBLOCKDIMENSION0 = 3U,
KHR_DF_WORD_TEXELBLOCKDIMENSION1 = 3U,
KHR_DF_WORD_TEXELBLOCKDIMENSION2 = 3U,
KHR_DF_WORD_TEXELBLOCKDIMENSION3 = 3U,
KHR_DF_WORD_BYTESPLANE0 = 4U,
KHR_DF_WORD_BYTESPLANE1 = 4U,
KHR_DF_WORD_BYTESPLANE2 = 4U,
KHR_DF_WORD_BYTESPLANE3 = 4U,
KHR_DF_WORD_BYTESPLANE4 = 5U,
KHR_DF_WORD_BYTESPLANE5 = 5U,
KHR_DF_WORD_BYTESPLANE6 = 5U,
KHR_DF_WORD_BYTESPLANE7 = 5U,
KHR_DF_WORD_SAMPLESTART = 6U,
KHR_DF_WORD_SAMPLEWORDS = 4U
} khr_df_word_e;
typedef enum _khr_df_shift_e {
KHR_DF_SHIFT_VENDORID = 0U,
KHR_DF_SHIFT_DESCRIPTORTYPE = 17U,
KHR_DF_SHIFT_VERSIONNUMBER = 0U,
KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE = 16U,
KHR_DF_SHIFT_MODEL = 0U,
KHR_DF_SHIFT_PRIMARIES = 8U,
KHR_DF_SHIFT_TRANSFER = 16U,
KHR_DF_SHIFT_FLAGS = 24U,
KHR_DF_SHIFT_TEXELBLOCKDIMENSION0 = 0U,
KHR_DF_SHIFT_TEXELBLOCKDIMENSION1 = 8U,
KHR_DF_SHIFT_TEXELBLOCKDIMENSION2 = 16U,
KHR_DF_SHIFT_TEXELBLOCKDIMENSION3 = 24U,
KHR_DF_SHIFT_BYTESPLANE0 = 0U,
KHR_DF_SHIFT_BYTESPLANE1 = 8U,
KHR_DF_SHIFT_BYTESPLANE2 = 16U,
KHR_DF_SHIFT_BYTESPLANE3 = 24U,
KHR_DF_SHIFT_BYTESPLANE4 = 0U,
KHR_DF_SHIFT_BYTESPLANE5 = 8U,
KHR_DF_SHIFT_BYTESPLANE6 = 16U,
KHR_DF_SHIFT_BYTESPLANE7 = 24U
} khr_df_shift_e;
typedef enum _khr_df_mask_e {
KHR_DF_MASK_VENDORID = 0x1FFFFU,
KHR_DF_MASK_DESCRIPTORTYPE = 0x7FFFU,
KHR_DF_MASK_VERSIONNUMBER = 0xFFFFU,
KHR_DF_MASK_DESCRIPTORBLOCKSIZE = 0xFFFFU,
KHR_DF_MASK_MODEL = 0xFFU,
KHR_DF_MASK_PRIMARIES = 0xFFU,
KHR_DF_MASK_TRANSFER = 0xFFU,
KHR_DF_MASK_FLAGS = 0xFFU,
KHR_DF_MASK_TEXELBLOCKDIMENSION0 = 0xFFU,
KHR_DF_MASK_TEXELBLOCKDIMENSION1 = 0xFFU,
KHR_DF_MASK_TEXELBLOCKDIMENSION2 = 0xFFU,
KHR_DF_MASK_TEXELBLOCKDIMENSION3 = 0xFFU,
KHR_DF_MASK_BYTESPLANE0 = 0xFFU,
KHR_DF_MASK_BYTESPLANE1 = 0xFFU,
KHR_DF_MASK_BYTESPLANE2 = 0xFFU,
KHR_DF_MASK_BYTESPLANE3 = 0xFFU,
KHR_DF_MASK_BYTESPLANE4 = 0xFFU,
KHR_DF_MASK_BYTESPLANE5 = 0xFFU,
KHR_DF_MASK_BYTESPLANE6 = 0xFFU,
KHR_DF_MASK_BYTESPLANE7 = 0xFFU
} khr_df_mask_e;
/* Helper macro:
Extract field X from basic descriptor block BDB */
#define KHR_DFDVAL(BDB, X) \
(((BDB)[KHR_DF_WORD_ ## X] >> (KHR_DF_SHIFT_ ## X)) \
& (KHR_DF_MASK_ ## X))
/* Helper macro:
Set field X of basic descriptor block BDB */
#define KHR_DFDSETVAL(BDB, X, val) \
((BDB)[KHR_DF_WORD_ ## X] = \
((BDB)[KHR_DF_WORD_ ## X] & \
~((KHR_DF_MASK_ ## X) << (KHR_DF_SHIFT_ ## X))) | \
(((uint32_t)(val) & (KHR_DF_MASK_ ## X)) << (KHR_DF_SHIFT_ ## X)))
/* Offsets relative to the start of a sample */
typedef enum _khr_df_sampleword_e {
KHR_DF_SAMPLEWORD_BITOFFSET = 0U,
KHR_DF_SAMPLEWORD_BITLENGTH = 0U,
KHR_DF_SAMPLEWORD_CHANNELID = 0U,
KHR_DF_SAMPLEWORD_QUALIFIERS = 0U,
KHR_DF_SAMPLEWORD_SAMPLEPOSITION0 = 1U,
KHR_DF_SAMPLEWORD_SAMPLEPOSITION1 = 1U,
KHR_DF_SAMPLEWORD_SAMPLEPOSITION2 = 1U,
KHR_DF_SAMPLEWORD_SAMPLEPOSITION3 = 1U,
KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL = 1U,
KHR_DF_SAMPLEWORD_SAMPLELOWER = 2U,
KHR_DF_SAMPLEWORD_SAMPLEUPPER = 3U
} khr_df_sampleword_e;
typedef enum _khr_df_sampleshift_e {
KHR_DF_SAMPLESHIFT_BITOFFSET = 0U,
KHR_DF_SAMPLESHIFT_BITLENGTH = 16U,
KHR_DF_SAMPLESHIFT_CHANNELID = 24U,
/* N.B. Qualifiers are defined as an offset into a byte */
KHR_DF_SAMPLESHIFT_QUALIFIERS = 24U,
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION0 = 0U,
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION1 = 8U,
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION2 = 16U,
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION3 = 24U,
KHR_DF_SAMPLESHIFT_SAMPLEPOSITION_ALL = 0U,
KHR_DF_SAMPLESHIFT_SAMPLELOWER = 0U,
KHR_DF_SAMPLESHIFT_SAMPLEUPPER = 0U
} khr_df_sampleshift_e;
typedef enum _khr_df_samplemask_e {
KHR_DF_SAMPLEMASK_BITOFFSET = 0xFFFFU,
KHR_DF_SAMPLEMASK_BITLENGTH = 0xFFU,
KHR_DF_SAMPLEMASK_CHANNELID = 0xFU,
/* N.B. Qualifiers are defined as an offset into a byte */
KHR_DF_SAMPLEMASK_QUALIFIERS = 0xF0U,
KHR_DF_SAMPLEMASK_SAMPLEPOSITION0 = 0xFFU,
KHR_DF_SAMPLEMASK_SAMPLEPOSITION1 = 0xFFU,
KHR_DF_SAMPLEMASK_SAMPLEPOSITION2 = 0xFFU,
KHR_DF_SAMPLEMASK_SAMPLEPOSITION3 = 0xFFU,
/* ISO C restricts enum values to range of int hence the
cast. We do it verbosely instead of using -1 to ensure
it is a 32-bit value even if int is 64 bits. */
KHR_DF_SAMPLEMASK_SAMPLEPOSITION_ALL = (int) 0xFFFFFFFFU,
KHR_DF_SAMPLEMASK_SAMPLELOWER = (int) 0xFFFFFFFFU,
KHR_DF_SAMPLEMASK_SAMPLEUPPER = (int) 0xFFFFFFFFU
} khr_df_samplemask_e;
/* Helper macro:
Extract field X of sample S from basic descriptor block BDB */
#define KHR_DFDSVAL(BDB, S, X) \
(((BDB)[KHR_DF_WORD_SAMPLESTART + \
((S) * KHR_DF_WORD_SAMPLEWORDS) + \
KHR_DF_SAMPLEWORD_ ## X] >> (KHR_DF_SAMPLESHIFT_ ## X)) \
& (KHR_DF_SAMPLEMASK_ ## X))
/* Helper macro:
Set field X of sample S of basic descriptor block BDB */
#define KHR_DFDSETSVAL(BDB, S, X, val) \
((BDB)[KHR_DF_WORD_SAMPLESTART + \
((S) * KHR_DF_WORD_SAMPLEWORDS) + \
KHR_DF_SAMPLEWORD_ ## X] = \
((BDB)[KHR_DF_WORD_SAMPLESTART + \
((S) * KHR_DF_WORD_SAMPLEWORDS) + \
KHR_DF_SAMPLEWORD_ ## X] & \
~((uint32_t)(KHR_DF_SAMPLEMASK_ ## X) << (KHR_DF_SAMPLESHIFT_ ## X))) | \
(((uint32_t)(val) & (uint32_t)(KHR_DF_SAMPLEMASK_ ## X)) << (KHR_DF_SAMPLESHIFT_ ## X)))
/* Helper macro:
Number of samples in basic descriptor block BDB */
#define KHR_DFDSAMPLECOUNT(BDB) \
(((KHR_DFDVAL(BDB, DESCRIPTORBLOCKSIZE) >> 2) - \
KHR_DF_WORD_SAMPLESTART) \
/ KHR_DF_WORD_SAMPLEWORDS)
/* Helper macro:
Size in words of basic descriptor block for S samples */
#define KHR_DFDSIZEWORDS(S) \
(KHR_DF_WORD_SAMPLESTART + \
(S) * KHR_DF_WORD_SAMPLEWORDS)
/* Vendor ids */
typedef enum _khr_df_vendorid_e {
/* Standard Khronos descriptor */
KHR_DF_VENDORID_KHRONOS = 0U,
KHR_DF_VENDORID_MAX = 0x1FFFFU
} khr_df_vendorid_e;
/* Descriptor types */
typedef enum _khr_df_khr_descriptortype_e {
/* Default Khronos basic descriptor block */
KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT = 0U,
/* Extension descriptor block for additional planes */
KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_PLANES = 0x6001U,
/* Extension descriptor block for additional dimensions */
KHR_DF_KHR_DESCRIPTORTYPE_ADDITIONAL_DIMENSIONS = 0x6002U,
/* Bit indicates modifying requires understanding this extension */
KHR_DF_KHR_DESCRIPTORTYPE_NEEDED_FOR_WRITE_BIT = 0x2000U,
/* Bit indicates processing requires understanding this extension */
KHR_DF_KHR_DESCRIPTORTYPE_NEEDED_FOR_DECODE_BIT = 0x4000U,
KHR_DF_KHR_DESCRIPTORTYPE_MAX = 0x7FFFU
} khr_df_khr_descriptortype_e;
/* Descriptor block version */
typedef enum _khr_df_versionnumber_e {
/* Standard Khronos descriptor */
KHR_DF_VERSIONNUMBER_1_0 = 0U, /* Version 1.0 of the specification */
KHR_DF_VERSIONNUMBER_1_1 = 0U, /* Version 1.1 did not bump the version number */
KHR_DF_VERSIONNUMBER_1_2 = 1U, /* Version 1.2 increased the version number */
KHR_DF_VERSIONNUMBER_1_3 = 2U, /* Version 1.3 increased the version number */
KHR_DF_VERSIONNUMBER_1_4 = 2U, /* Version 1.4.0 did not bump the block version number */
KHR_DF_VERSIONNUMBER_LATEST = KHR_DF_VERSIONNUMBER_1_4,
KHR_DF_VERSIONNUMBER_MAX = 0xFFFFU
} khr_df_versionnumber_e;
/* Model in which the color coordinate space is defined.
There is no requirement that a color format use all the
channel types that are defined in the color model. */
typedef enum _khr_df_model_e {
/* No interpretation of color channels defined */
KHR_DF_MODEL_UNSPECIFIED = 0U,
/* Color primaries (red, green, blue) + alpha, depth and stencil */
KHR_DF_MODEL_RGBSDA = 1U,
/* Color differences (Y', Cb, Cr) + alpha, depth and stencil */
KHR_DF_MODEL_YUVSDA = 2U,
/* Color differences (Y', I, Q) + alpha, depth and stencil */
KHR_DF_MODEL_YIQSDA = 3U,
/* Perceptual color (CIE L*a*b*) + alpha, depth and stencil */
KHR_DF_MODEL_LABSDA = 4U,
/* Subtractive colors (cyan, magenta, yellow, black) + alpha */
KHR_DF_MODEL_CMYKA = 5U,
/* Non-color coordinate data (X, Y, Z, W) */
KHR_DF_MODEL_XYZW = 6U,
/* Hue, saturation, value, hue angle on color circle, plus alpha */
KHR_DF_MODEL_HSVA_ANG = 7U,
/* Hue, saturation, lightness, hue angle on color circle, plus alpha */
KHR_DF_MODEL_HSLA_ANG = 8U,
/* Hue, saturation, value, hue on color hexagon, plus alpha */
KHR_DF_MODEL_HSVA_HEX = 9U,
/* Hue, saturation, lightness, hue on color hexagon, plus alpha */
KHR_DF_MODEL_HSLA_HEX = 10U,
/* Lightweight approximate color difference (luma, orange, green) */
KHR_DF_MODEL_YCGCOA = 11U,
/* ITU BT.2020 constant luminance YcCbcCrc */
KHR_DF_MODEL_YCCBCCRC = 12U,
/* ITU BT.2100 constant intensity ICtCp */
KHR_DF_MODEL_ICTCP = 13U,
/* CIE 1931 XYZ color coordinates (X, Y, Z) */
KHR_DF_MODEL_CIEXYZ = 14U,
/* CIE 1931 xyY color coordinates (X, Y, Y) */
KHR_DF_MODEL_CIEXYY = 15U,
/* Compressed formats start at 128. */
/* These compressed formats should generally have a single sample,
sited at the 0,0 position of the texel block. Where multiple
channels are used to distinguish formats, these should be cosited. */
/* Direct3D (and S3) compressed formats */
/* Note that premultiplied status is recorded separately */
/* DXT1 "channels" are RGB (0), Alpha (1) */
/* DXT1/BC1 with one channel is opaque */
/* DXT1/BC1 with a cosited alpha sample is transparent */
KHR_DF_MODEL_DXT1A = 128U,
KHR_DF_MODEL_BC1A = 128U,
/* DXT2/DXT3/BC2, with explicit 4-bit alpha */
KHR_DF_MODEL_DXT2 = 129U,
KHR_DF_MODEL_DXT3 = 129U,
KHR_DF_MODEL_BC2 = 129U,
/* DXT4/DXT5/BC3, with interpolated alpha */
KHR_DF_MODEL_DXT4 = 130U,
KHR_DF_MODEL_DXT5 = 130U,
KHR_DF_MODEL_BC3 = 130U,
/* ATI1n/DXT5A/BC4 - single channel interpolated 8-bit data */
/* (The UNORM/SNORM variation is recorded in the channel data) */
KHR_DF_MODEL_ATI1N = 131U,
KHR_DF_MODEL_DXT5A = 131U,
KHR_DF_MODEL_BC4 = 131U,
/* ATI2n_XY/DXN/BC5 - two channel interpolated 8-bit data */
/* (The UNORM/SNORM variation is recorded in the channel data) */
KHR_DF_MODEL_ATI2N_XY = 132U,
KHR_DF_MODEL_DXN = 132U,
KHR_DF_MODEL_BC5 = 132U,
/* BC6H - DX11 format for 16-bit float channels */
KHR_DF_MODEL_BC6H = 133U,
/* BC7 - DX11 format */
KHR_DF_MODEL_BC7 = 134U,
/* Gap left for future desktop expansion */
/* Mobile compressed formats follow */
/* A format of ETC1 indicates that the format shall be decodable
by an ETC1-compliant decoder and not rely on ETC2 features */
KHR_DF_MODEL_ETC1 = 160U,
/* A format of ETC2 is permitted to use ETC2 encodings on top of
the baseline ETC1 specification */
/* The ETC2 format has channels "red", "green", "RGB" and "alpha",
which should be cosited samples */
/* Punch-through alpha can be distinguished from full alpha by
the plane size in bytes required for the texel block */
KHR_DF_MODEL_ETC2 = 161U,
/* Adaptive Scalable Texture Compression */
/* ASTC HDR vs LDR is determined by the float flag in the channel */
/* ASTC block size can be distinguished by texel block size */
KHR_DF_MODEL_ASTC = 162U,
/* ETC1S is a simplified subset of ETC1 */
KHR_DF_MODEL_ETC1S = 163U,
/* PowerVR Texture Compression */
KHR_DF_MODEL_PVRTC = 164U,
KHR_DF_MODEL_PVRTC2 = 165U,
KHR_DF_MODEL_UASTC = 166U,
/* Proprietary formats (ATITC, etc.) should follow */
KHR_DF_MODEL_MAX = 0xFFU
} khr_df_model_e;
/* Definition of channel names for each color model */
typedef enum _khr_df_model_channels_e {
/* Unspecified format with nominal channel numbering */
KHR_DF_CHANNEL_UNSPECIFIED_0 = 0U,
KHR_DF_CHANNEL_UNSPECIFIED_1 = 1U,
KHR_DF_CHANNEL_UNSPECIFIED_2 = 2U,
KHR_DF_CHANNEL_UNSPECIFIED_3 = 3U,
KHR_DF_CHANNEL_UNSPECIFIED_4 = 4U,
KHR_DF_CHANNEL_UNSPECIFIED_5 = 5U,
KHR_DF_CHANNEL_UNSPECIFIED_6 = 6U,
KHR_DF_CHANNEL_UNSPECIFIED_7 = 7U,
KHR_DF_CHANNEL_UNSPECIFIED_8 = 8U,
KHR_DF_CHANNEL_UNSPECIFIED_9 = 9U,
KHR_DF_CHANNEL_UNSPECIFIED_10 = 10U,
KHR_DF_CHANNEL_UNSPECIFIED_11 = 11U,
KHR_DF_CHANNEL_UNSPECIFIED_12 = 12U,
KHR_DF_CHANNEL_UNSPECIFIED_13 = 13U,
KHR_DF_CHANNEL_UNSPECIFIED_14 = 14U,
KHR_DF_CHANNEL_UNSPECIFIED_15 = 15U,
/* MODEL_RGBSDA - red, green, blue, stencil, depth, alpha */
KHR_DF_CHANNEL_RGBSDA_RED = 0U,
KHR_DF_CHANNEL_RGBSDA_R = 0U,
KHR_DF_CHANNEL_RGBSDA_GREEN = 1U,
KHR_DF_CHANNEL_RGBSDA_G = 1U,
KHR_DF_CHANNEL_RGBSDA_BLUE = 2U,
KHR_DF_CHANNEL_RGBSDA_B = 2U,
KHR_DF_CHANNEL_RGBSDA_STENCIL = 13U,
KHR_DF_CHANNEL_RGBSDA_S = 13U,
KHR_DF_CHANNEL_RGBSDA_DEPTH = 14U,
KHR_DF_CHANNEL_RGBSDA_D = 14U,
KHR_DF_CHANNEL_RGBSDA_ALPHA = 15U,
KHR_DF_CHANNEL_RGBSDA_A = 15U,
/* MODEL_YUVSDA - luma, Cb, Cr, stencil, depth, alpha */
KHR_DF_CHANNEL_YUVSDA_Y = 0U,
KHR_DF_CHANNEL_YUVSDA_CB = 1U,
KHR_DF_CHANNEL_YUVSDA_U = 1U,
KHR_DF_CHANNEL_YUVSDA_CR = 2U,
KHR_DF_CHANNEL_YUVSDA_V = 2U,
KHR_DF_CHANNEL_YUVSDA_STENCIL = 13U,
KHR_DF_CHANNEL_YUVSDA_S = 13U,
KHR_DF_CHANNEL_YUVSDA_DEPTH = 14U,
KHR_DF_CHANNEL_YUVSDA_D = 14U,
KHR_DF_CHANNEL_YUVSDA_ALPHA = 15U,
KHR_DF_CHANNEL_YUVSDA_A = 15U,
/* MODEL_YIQSDA - luma, in-phase, quadrature, stencil, depth, alpha */
KHR_DF_CHANNEL_YIQSDA_Y = 0U,
KHR_DF_CHANNEL_YIQSDA_I = 1U,
KHR_DF_CHANNEL_YIQSDA_Q = 2U,
KHR_DF_CHANNEL_YIQSDA_STENCIL = 13U,
KHR_DF_CHANNEL_YIQSDA_S = 13U,
KHR_DF_CHANNEL_YIQSDA_DEPTH = 14U,
KHR_DF_CHANNEL_YIQSDA_D = 14U,
KHR_DF_CHANNEL_YIQSDA_ALPHA = 15U,
KHR_DF_CHANNEL_YIQSDA_A = 15U,
/* MODEL_LABSDA - CIELAB/L*a*b* luma, red-green, blue-yellow, stencil, depth, alpha */
KHR_DF_CHANNEL_LABSDA_L = 0U,
KHR_DF_CHANNEL_LABSDA_A = 1U,
KHR_DF_CHANNEL_LABSDA_B = 2U,
KHR_DF_CHANNEL_LABSDA_STENCIL = 13U,
KHR_DF_CHANNEL_LABSDA_S = 13U,
KHR_DF_CHANNEL_LABSDA_DEPTH = 14U,
KHR_DF_CHANNEL_LABSDA_D = 14U,
KHR_DF_CHANNEL_LABSDA_ALPHA = 15U,
/* NOTE: KHR_DF_CHANNEL_LABSDA_A is not a synonym for alpha! */
/* MODEL_CMYKA - cyan, magenta, yellow, key/blacK, alpha */
KHR_DF_CHANNEL_CMYKSDA_CYAN = 0U,
KHR_DF_CHANNEL_CMYKSDA_C = 0U,
KHR_DF_CHANNEL_CMYKSDA_MAGENTA = 1U,
KHR_DF_CHANNEL_CMYKSDA_M = 1U,
KHR_DF_CHANNEL_CMYKSDA_YELLOW = 2U,
KHR_DF_CHANNEL_CMYKSDA_Y = 2U,
KHR_DF_CHANNEL_CMYKSDA_KEY = 3U,
KHR_DF_CHANNEL_CMYKSDA_BLACK = 3U,
KHR_DF_CHANNEL_CMYKSDA_K = 3U,
KHR_DF_CHANNEL_CMYKSDA_ALPHA = 15U,
KHR_DF_CHANNEL_CMYKSDA_A = 15U,
/* MODEL_XYZW - coordinates x, y, z, w */
KHR_DF_CHANNEL_XYZW_X = 0U,
KHR_DF_CHANNEL_XYZW_Y = 1U,
KHR_DF_CHANNEL_XYZW_Z = 2U,
KHR_DF_CHANNEL_XYZW_W = 3U,
/* MODEL_HSVA_ANG - value (luma), saturation, hue, alpha, angular projection, conical space */
KHR_DF_CHANNEL_HSVA_ANG_VALUE = 0U,
KHR_DF_CHANNEL_HSVA_ANG_V = 0U,
KHR_DF_CHANNEL_HSVA_ANG_SATURATION = 1U,
KHR_DF_CHANNEL_HSVA_ANG_S = 1U,
KHR_DF_CHANNEL_HSVA_ANG_HUE = 2U,
KHR_DF_CHANNEL_HSVA_ANG_H = 2U,
KHR_DF_CHANNEL_HSVA_ANG_ALPHA = 15U,
KHR_DF_CHANNEL_HSVA_ANG_A = 15U,
/* MODEL_HSLA_ANG - lightness (luma), saturation, hue, alpha, angular projection, double conical space */
KHR_DF_CHANNEL_HSLA_ANG_LIGHTNESS = 0U,
KHR_DF_CHANNEL_HSLA_ANG_L = 0U,
KHR_DF_CHANNEL_HSLA_ANG_SATURATION = 1U,
KHR_DF_CHANNEL_HSLA_ANG_S = 1U,
KHR_DF_CHANNEL_HSLA_ANG_HUE = 2U,
KHR_DF_CHANNEL_HSLA_ANG_H = 2U,
KHR_DF_CHANNEL_HSLA_ANG_ALPHA = 15U,
KHR_DF_CHANNEL_HSLA_ANG_A = 15U,
/* MODEL_HSVA_HEX - value (luma), saturation, hue, alpha, hexagonal projection, conical space */
KHR_DF_CHANNEL_HSVA_HEX_VALUE = 0U,
KHR_DF_CHANNEL_HSVA_HEX_V = 0U,
KHR_DF_CHANNEL_HSVA_HEX_SATURATION = 1U,
KHR_DF_CHANNEL_HSVA_HEX_S = 1U,
KHR_DF_CHANNEL_HSVA_HEX_HUE = 2U,
KHR_DF_CHANNEL_HSVA_HEX_H = 2U,
KHR_DF_CHANNEL_HSVA_HEX_ALPHA = 15U,
KHR_DF_CHANNEL_HSVA_HEX_A = 15U,
/* MODEL_HSLA_HEX - lightness (luma), saturation, hue, alpha, hexagonal projection, double conical space */
KHR_DF_CHANNEL_HSLA_HEX_LIGHTNESS = 0U,
KHR_DF_CHANNEL_HSLA_HEX_L = 0U,
KHR_DF_CHANNEL_HSLA_HEX_SATURATION = 1U,
KHR_DF_CHANNEL_HSLA_HEX_S = 1U,
KHR_DF_CHANNEL_HSLA_HEX_HUE = 2U,
KHR_DF_CHANNEL_HSLA_HEX_H = 2U,
KHR_DF_CHANNEL_HSLA_HEX_ALPHA = 15U,
KHR_DF_CHANNEL_HSLA_HEX_A = 15U,
/* MODEL_YCGCOA - luma, green delta, orange delta, alpha */
KHR_DF_CHANNEL_YCGCOA_Y = 0U,
KHR_DF_CHANNEL_YCGCOA_CG = 1U,
KHR_DF_CHANNEL_YCGCOA_CO = 2U,
KHR_DF_CHANNEL_YCGCOA_ALPHA = 15U,
KHR_DF_CHANNEL_YCGCOA_A = 15U,
/* MODEL_CIEXYZ - CIE 1931 X, Y, Z */
KHR_DF_CHANNEL_CIEXYZ_X = 0U,
KHR_DF_CHANNEL_CIEXYZ_Y = 1U,
KHR_DF_CHANNEL_CIEXYZ_Z = 2U,
/* MODEL_CIEXYY - CIE 1931 x, y, Y */
KHR_DF_CHANNEL_CIEXYY_X = 0U,
KHR_DF_CHANNEL_CIEXYY_YCHROMA = 1U,
KHR_DF_CHANNEL_CIEXYY_YLUMA = 2U,
/* Compressed formats */
/* MODEL_DXT1A/MODEL_BC1A */
KHR_DF_CHANNEL_DXT1A_COLOR = 0U,
KHR_DF_CHANNEL_BC1A_COLOR = 0U,
KHR_DF_CHANNEL_DXT1A_ALPHAPRESENT = 1U,
KHR_DF_CHANNEL_DXT1A_ALPHA = 1U,
KHR_DF_CHANNEL_BC1A_ALPHAPRESENT = 1U,
KHR_DF_CHANNEL_BC1A_ALPHA = 1U,
/* MODEL_DXT2/3/MODEL_BC2 */
KHR_DF_CHANNEL_DXT2_COLOR = 0U,
KHR_DF_CHANNEL_DXT3_COLOR = 0U,
KHR_DF_CHANNEL_BC2_COLOR = 0U,
KHR_DF_CHANNEL_DXT2_ALPHA = 15U,
KHR_DF_CHANNEL_DXT3_ALPHA = 15U,
KHR_DF_CHANNEL_BC2_ALPHA = 15U,
/* MODEL_DXT4/5/MODEL_BC3 */
KHR_DF_CHANNEL_DXT4_COLOR = 0U,
KHR_DF_CHANNEL_DXT5_COLOR = 0U,
KHR_DF_CHANNEL_BC3_COLOR = 0U,
KHR_DF_CHANNEL_DXT4_ALPHA = 15U,
KHR_DF_CHANNEL_DXT5_ALPHA = 15U,
KHR_DF_CHANNEL_BC3_ALPHA = 15U,
/* MODEL_BC4 */
KHR_DF_CHANNEL_BC4_DATA = 0U,
/* MODEL_BC5 */
KHR_DF_CHANNEL_BC5_RED = 0U,
KHR_DF_CHANNEL_BC5_R = 0U,
KHR_DF_CHANNEL_BC5_GREEN = 1U,
KHR_DF_CHANNEL_BC5_G = 1U,
/* MODEL_BC6H */
KHR_DF_CHANNEL_BC6H_COLOR = 0U,
KHR_DF_CHANNEL_BC6H_DATA = 0U,
/* MODEL_BC7 */
KHR_DF_CHANNEL_BC7_DATA = 0U,
KHR_DF_CHANNEL_BC7_COLOR = 0U,
/* MODEL_ETC1 */
KHR_DF_CHANNEL_ETC1_DATA = 0U,
KHR_DF_CHANNEL_ETC1_COLOR = 0U,
/* MODEL_ETC2 */
KHR_DF_CHANNEL_ETC2_RED = 0U,
KHR_DF_CHANNEL_ETC2_R = 0U,
KHR_DF_CHANNEL_ETC2_GREEN = 1U,
KHR_DF_CHANNEL_ETC2_G = 1U,
KHR_DF_CHANNEL_ETC2_COLOR = 2U,
KHR_DF_CHANNEL_ETC2_ALPHA = 15U,
KHR_DF_CHANNEL_ETC2_A = 15U,
/* MODEL_ASTC */
KHR_DF_CHANNEL_ASTC_DATA = 0U,
/* MODEL_ETC1S */
KHR_DF_CHANNEL_ETC1S_RGB = 0U,
KHR_DF_CHANNEL_ETC1S_RRR = 3U,
KHR_DF_CHANNEL_ETC1S_GGG = 4U,
KHR_DF_CHANNEL_ETC1S_AAA = 15U,
/* MODEL_PVRTC */
KHR_DF_CHANNEL_PVRTC_DATA = 0U,
KHR_DF_CHANNEL_PVRTC_COLOR = 0U,
/* MODEL_PVRTC2 */
KHR_DF_CHANNEL_PVRTC2_DATA = 0U,
KHR_DF_CHANNEL_PVRTC2_COLOR = 0U,
/* MODEL UASTC */
KHR_DF_CHANNEL_UASTC_RGB = 0U,
KHR_DF_CHANNEL_UASTC_RGBA = 3U,
KHR_DF_CHANNEL_UASTC_RRR = 4U,
KHR_DF_CHANNEL_UASTC_RRRG = 5U,
KHR_DF_CHANNEL_UASTC_RG = 6U,
/* Common channel names shared by multiple formats */
KHR_DF_CHANNEL_COMMON_LUMA = 0U,
KHR_DF_CHANNEL_COMMON_L = 0U,
KHR_DF_CHANNEL_COMMON_STENCIL = 13U,
KHR_DF_CHANNEL_COMMON_S = 13U,
KHR_DF_CHANNEL_COMMON_DEPTH = 14U,
KHR_DF_CHANNEL_COMMON_D = 14U,
KHR_DF_CHANNEL_COMMON_ALPHA = 15U,
KHR_DF_CHANNEL_COMMON_A = 15U
} khr_df_model_channels_e;
/* Definition of the primary colors in color coordinates.
This is implicitly responsible for defining the conversion
between RGB an YUV color spaces.
LAB and related absolute color models should use
KHR_DF_PRIMARIES_CIEXYZ. */
typedef enum _khr_df_primaries_e {
/* No color primaries defined */
KHR_DF_PRIMARIES_UNSPECIFIED = 0U,
/* Color primaries of ITU-R BT.709 and sRGB */
KHR_DF_PRIMARIES_BT709 = 1U,
/* Synonym for KHR_DF_PRIMARIES_BT709 */
KHR_DF_PRIMARIES_SRGB = 1U,
/* Color primaries of ITU-R BT.601 (625-line EBU variant) */
KHR_DF_PRIMARIES_BT601_EBU = 2U,
/* Color primaries of ITU-R BT.601 (525-line SMPTE C variant) */
KHR_DF_PRIMARIES_BT601_SMPTE = 3U,
/* Color primaries of ITU-R BT.2020 */
KHR_DF_PRIMARIES_BT2020 = 4U,
/* ITU-R BT.2100 uses the same primaries as BT.2020 */
KHR_DF_PRIMARIES_BT2100 = 4U,
/* CIE theoretical color coordinate space */
KHR_DF_PRIMARIES_CIEXYZ = 5U,
/* Academy Color Encoding System primaries */
KHR_DF_PRIMARIES_ACES = 6U,
/* Color primaries of ACEScc */
KHR_DF_PRIMARIES_ACESCC = 7U,
/* Legacy NTSC 1953 primaries */
KHR_DF_PRIMARIES_NTSC1953 = 8U,
/* Legacy PAL 525-line primaries */
KHR_DF_PRIMARIES_PAL525 = 9U,
/* Color primaries of Display P3 */
KHR_DF_PRIMARIES_DISPLAYP3 = 10U,
/* Color primaries of Adobe RGB (1998) */
KHR_DF_PRIMARIES_ADOBERGB = 11U,
KHR_DF_PRIMARIES_MAX = 0xFFU
} khr_df_primaries_e;
/* Definition of the optical to digital transfer function
("gamma correction"). Most transfer functions are not a pure
power function and also include a linear element.
LAB and related absolute color representations should use
KHR_DF_TRANSFER_UNSPECIFIED.
These encodings indicate that the representation has had
the corresponding transfer function applied relative to a
linear representation; hence to process the linear intensity
represented by the value, a corresponding inverse transform
must be applied. */
typedef enum _khr_df_transfer_e {
/* No transfer function defined */
KHR_DF_TRANSFER_UNSPECIFIED = 0U,
/* Linear transfer function (value proportional to intensity) */
KHR_DF_TRANSFER_LINEAR = 1U,
/* Perceptually-linear transfer function of sRGB (~2.2); also used for scRGB */
KHR_DF_TRANSFER_SRGB = 2U,
KHR_DF_TRANSFER_SRGB_EOTF = 2U,
KHR_DF_TRANSFER_SCRGB = 2U,
KHR_DF_TRANSFER_SCRGB_EOTF = 2U,
/* Perceptually-linear transfer function of ITU BT.601, BT.709 and BT.2020 (~1/.45) */
KHR_DF_TRANSFER_ITU = 3U,
KHR_DF_TRANSFER_ITU_OETF = 3U,
KHR_DF_TRANSFER_BT601 = 3U,
KHR_DF_TRANSFER_BT601_OETF = 3U,
KHR_DF_TRANSFER_BT709 = 3U,
KHR_DF_TRANSFER_BT709_OETF = 3U,
KHR_DF_TRANSFER_BT2020 = 3U,
KHR_DF_TRANSFER_BT2020_OETF = 3U,
/* SMTPE170M (digital NTSC) defines an alias for the ITU transfer function (~1/.45) and a linear OOTF */
KHR_DF_TRANSFER_SMTPE170M = 3U,
KHR_DF_TRANSFER_SMTPE170M_OETF = 3U,
KHR_DF_TRANSFER_SMTPE170M_EOTF = 3U,
/* Perceptually-linear gamma function of original NTSC (simple 2.2 gamma) */
KHR_DF_TRANSFER_NTSC = 4U,
KHR_DF_TRANSFER_NTSC_EOTF = 4U,
/* Sony S-log used by Sony video cameras */
KHR_DF_TRANSFER_SLOG = 5U,
KHR_DF_TRANSFER_SLOG_OETF = 5U,
/* Sony S-log 2 used by Sony video cameras */
KHR_DF_TRANSFER_SLOG2 = 6U,
KHR_DF_TRANSFER_SLOG2_OETF = 6U,
/* ITU BT.1886 EOTF */
KHR_DF_TRANSFER_BT1886 = 7U,
KHR_DF_TRANSFER_BT1886_EOTF = 7U,
/* ITU BT.2100 HLG OETF (typical scene-referred content), linear light normalized 0..1 */
KHR_DF_TRANSFER_HLG_OETF = 8U,
/* ITU BT.2100 HLG EOTF (nominal HDR display of HLG content), linear light normalized 0..1 */
KHR_DF_TRANSFER_HLG_EOTF = 9U,
/* ITU BT.2100 PQ EOTF (typical HDR display-referred PQ content) */
KHR_DF_TRANSFER_PQ_EOTF = 10U,
/* ITU BT.2100 PQ OETF (nominal scene described by PQ HDR content) */
KHR_DF_TRANSFER_PQ_OETF = 11U,
/* DCI P3 transfer function */
KHR_DF_TRANSFER_DCIP3 = 12U,
KHR_DF_TRANSFER_DCIP3_EOTF = 12U,
/* Legacy PAL OETF */
KHR_DF_TRANSFER_PAL_OETF = 13U,
/* Legacy PAL 625-line EOTF */
KHR_DF_TRANSFER_PAL625_EOTF = 14U,
/* Legacy ST240 transfer function */
KHR_DF_TRANSFER_ST240 = 15U,
KHR_DF_TRANSFER_ST240_OETF = 15U,
KHR_DF_TRANSFER_ST240_EOTF = 15U,
/* ACEScc transfer function */
KHR_DF_TRANSFER_ACESCC = 16U,
KHR_DF_TRANSFER_ACESCC_OETF = 16U,
/* ACEScct transfer function */
KHR_DF_TRANSFER_ACESCCT = 17U,
KHR_DF_TRANSFER_ACESCCT_OETF = 17U,
/* Adobe RGB (1998) transfer function */
KHR_DF_TRANSFER_ADOBERGB = 18U,
KHR_DF_TRANSFER_ADOBERGB_EOTF = 18U,
/* Legacy ITU BT.2100 HLG OETF (typical scene-referred content), linear light normalized 0..12 */
KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF = 19U,
KHR_DF_TRANSFER_MAX = 0xFFU
} khr_df_transfer_e;
typedef enum _khr_df_flags_e {
KHR_DF_FLAG_ALPHA_STRAIGHT = 0U,
KHR_DF_FLAG_ALPHA_PREMULTIPLIED = 1U
} khr_df_flags_e;
typedef enum _khr_df_sample_datatype_qualifiers_e {
KHR_DF_SAMPLE_DATATYPE_LINEAR = 1U << 4U,
KHR_DF_SAMPLE_DATATYPE_EXPONENT = 1U << 5U,
KHR_DF_SAMPLE_DATATYPE_SIGNED = 1U << 6U,
KHR_DF_SAMPLE_DATATYPE_FLOAT = 1U << 7U
} khr_df_sample_datatype_qualifiers_e;
#endif
+10
View File
@@ -0,0 +1,10 @@
= LICENSE file for the KhronosGroup/dfdutils project
Files in this repository fall under this license:
* SPDX license identifier: "`Apache-2.0`"
** Apache License 2.0
Full license text is available at:
* Apache-2.0: https://opensource.org/licenses/Apache-2.0
+208
View File
@@ -0,0 +1,208 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution
as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct
or indirect, to cause the direction or management of such entity, whether
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled object
code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that
is included in or attached to the work (an example is provided in the Appendix
below).
"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative
Works shall not include works that remain separable from, or merely link (or
bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative
Works thereof, that is intentionally submitted to Licensor for inclusion in
the Work by the copyright owner or by an individual or Legal Entity authorized
to submit on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication
sent to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor
for the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently incorporated
within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License,
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section) patent
license to make, have made, use, offer to sell, sell, import, and otherwise
transfer the Work, where such license applies only to those patent claims
licensable by such Contributor that are necessarily infringed by their Contribution(s)
alone or by combination of their Contribution(s) with the Work to which such
Contribution(s) was submitted. If You institute patent litigation against
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
that the Work or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses granted to You
under this License for that Work shall terminate as of the date such litigation
is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and
in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy
of this License; and
(b) You must cause any modified files to carry prominent notices stating that
You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source
form of the Work, excluding those notices that do not pertain to any part
of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable copy
of the attribution notices contained within such NOTICE file, excluding those
notices that do not pertain to any part of the Derivative Works, in at least
one of the following places: within a NOTICE text file distributed as part
of the Derivative Works; within the Source form or documentation, if provided
along with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works
that You distribute, alongside or as an addendum to the NOTICE text from the
Work, provided that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction,
or distribution of Your modifications, or for any such Derivative Works as
a whole, provided Your use, reproduction, and distribution of the Work otherwise
complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to the
Licensor shall be under the terms and conditions of this License, without
any additional terms or conditions. Notwithstanding the above, nothing herein
shall supersede or modify the terms of any separate license agreement you
may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names,
trademarks, service marks, or product names of the Licensor, except as required
for reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
in writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any warranties
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
of using or redistributing the Work and assume any risks associated with Your
exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether
in tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to
in writing, shall any Contributor be liable to You for damages, including
any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or inability
to use the Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all other commercial
damages or losses), even if such Contributor has been advised of the possibility
of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work
or Derivative Works thereof, You may choose to offer, and charge a fee for,
acceptance of support, warranty, indemnity, or other liability obligations
and/or rights consistent with this License. However, in accepting such obligations,
You may act only on Your own behalf and on Your sole responsibility, not on
behalf of any other Contributor, and only if You agree to indemnify, defend,
and hold each Contributor harmless for any liability incurred by, or claims
asserted against, such Contributor by reason of your accepting any such warranty
or additional liability. END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
information. (Don't include the brackets!) The text should be enclosed in
the appropriate comment syntax for the file format. We also recommend that
a file or class name and description of purpose be included on the same "printed
page" as the copyright notice for easier identification within third-party
archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+60
View File
@@ -0,0 +1,60 @@
# Copyright 2019-2020 The Khronos Group Inc.
# SPDX-License-Identifier: Apache-2.0
out := out
targets := testcreatedfd testinterpretdfd testbidirectionalmapping doc
all: $(addprefix out/,${targets})
CFLAGS=-I.
# Note. Currently we use an unreleased version of vulkan_core.h with enums
# for ASTC 3D. Since this is temporary, the sources still use <angled>
# includes. The -I. causes our local copy to be found while the VULKAN_SDK
# part keeps compilers from warning that the file was not found with
# <angled> include.
$(out)/testcreatedfd: createdfd.c createdfdtest.c printdfd.c vk2dfd.c vk2dfd.inl KHR/khr_df.h dfd.h | out
gcc createdfdtest.c createdfd.c printdfd.c -I. $(if $(VULKAN_SDK),-I$(VULKAN_SDK)/include) -o $@ -std=c99 -W -Wall -pedantic -O2 -Wno-strict-aliasing -Wno-unused-parameter
$(out)/testinterpretdfd: createdfd.c interpretdfd.c interpretdfdtest.c printdfd.c KHR/khr_df.h dfd.h | out
gcc interpretdfd.c createdfd.c interpretdfdtest.c printdfd.c -o $@ -I. $(if $(VULKAN_SDK),-I$(VULKAN_SDK)/include) -O -W -Wall -std=c99 -pedantic -Wno-unused-parameter
$(out)/testbidirectionalmapping: testbidirectionalmapping.c interpretdfd.c createdfd.c dfd2vk.c dfd2vk.inl vk2dfd.c vk2dfd.inl KHR/khr_df.h dfd.h | out
gcc testbidirectionalmapping.c interpretdfd.c createdfd.c -o $@ -I. $(if $(VULKAN_SDK),-I$(VULKAN_SDK)/include) -g -W -Wall -std=c99 -pedantic -Wno-unused-parameter
$(out)/doc: colourspaces.c createdfd.c createdfdtest.c printdfd.c queries.c KHR/khr_df.h dfd.h | out
doxygen dfdutils.doxy
build out:
mkdir -p $@
clean:
rm -rf $(out)/dfd2vk.o $(out)/vk2dfd.o
clobber: clean
rm -rf $(addprefix out/,${targets})
doc: $(out)/doc
# Generate the switch bodies and test build the including code.
switches: dfd2vk.inl $(out)/dfd2vk.o vk2dfd.inl $(out)/vk2dfd.o
dfd2vk.inl: vulkan/vulkan_core.h makedfd2vk.pl
./makedfd2vk.pl $< $@
vk2dfd.inl: vulkan/vulkan_core.h makevk2dfd.pl
./makevk2dfd.pl $< $@
$(out)/vk2dfd.o: vk2dfd.c | $(out)
cc -c -o $@ -I . $<
$(out)/dfd2vk.o: dfd2vk.c | $(out)
cc -c -o $@ -I . $<
# For those who wish to generate a project from the gyp file so
# as to use xcode for debugging.
xcodeproj: build/project.pbxproj
build/project.pbxproj: dfdutils.gyp | build
gyp -f xcode -DOS=mac --generator-output=build --depth=.
+81
View File
@@ -0,0 +1,81 @@
// Copyright 2019-2020 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0
Khronos^®^ Data Format Descriptor Utilities
===========================================
This directory contains helper utilities for creating and
interpreting data format descriptors as specified in Part 1 of the
https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html[Khronos
Data Format Specification 1.3] (KDFS). KDFS Part 1 is referred to by the
http://github.khronos.org/KTX-Specification/[KTX File Format
Specification Version 2] and data format descriptors are embedded
in `.ktx2` files. The OpenGL^®^, OpenGL ES^™️^ and Vulkan^®^
specifications refer to other parts of KDFS that specify color
transforms and block-compressed texture formats.
These utilities are provided as examples rather than being intended for
use in production code (they are not robust to all possible
input, even for legal data format descriptors) and no warranty
is provided. They should however work with the subset of data format
descriptors needed in `.ktx2` files.
`colorspaces.c` contains a helper function for finding a mapping from a
set of color primarie values to a KDFS primaries enum.
`createdfd.c` contains helpers for converting from Vulkan format
enums to data format descriptors.
`interpretdfd.c` provides the ability to interpret a data format
descriptor for simple formats, and provides a simplified
interface for this case.
`printdfd.c` produces a (fairly) human-readable description of
the fields of a data format descriptor, intended to assist with
debugging.
`queries.c` contains functions to query the component information
of a descriptor for an unpacked format and the number of components
in the described format. It also contains a utility function to
recreate the `bytesPlane0` value of a DFD for data that is being
inflated from supercomoression.
`vk2dfd.c` creates a DFD describing a `VkFormat` and `dfd2vk.c`
returns the VkFormat matching a DFD.
API documentation can be found http://github.khronos.org/dfdutils/[here].
makevk2dfd.pl and makedfd2vk.pl generate the code used by
`vk2dfd.c` and `dfd2vk.c` to convert from Vulkan enums to data
format descriptors and back again; these should be run with the
Vulkan header (or the format enum subset of it) as input, since
they heuristically support formats named in the header rather than
being hard-wired. As the resulting code depends highly on
heuristics to identify existing format mappings, it is not robust
against descriptors which did not originate as a Vulkan format.
NOTE: Only common color formats and depth formats are
supported; there's no support for multi-planar formats, for
example.
The commands` syntax is
[source,sh]
----
makevk2dfd.pl [<vulkan header>] [<output_file>]
makedfd2vk.pl [<vulkan_header>] [<output_file>]
----
With no arguments they read from `stdin` and write to `stdout`.
With 1 argument they read the first argument file and write to
`stdout`. With 2 arguments they read the first argument file and
write to the second.
[NOTE]
====
These utilities require access to vulkan_core.h for access to
VkFormat. A version is provided in this repo as a temporary measure
until the Vulkan extension for ASTC 3D formats is released and
those enums appear in the standard vulkan_core.h.
====
// vim: filetype=asciidoc ai expandtab tw=72 ts=4 sts=2 sw=2
+71
View File
@@ -0,0 +1,71 @@
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @~English
* @brief Helper functions for colourspaces.
*/
#include <KHR/khr_df.h>
#include "dfd.h"
typedef struct s_PrimaryMapping {
khr_df_primaries_e dfPrimaryEnum;
Primaries primaries;
} sPrimaryMapping;
sPrimaryMapping primaryMap[] = {
{ KHR_DF_PRIMARIES_BT709, { 0.640f,0.330f, 0.300f,0.600f, 0.150f,0.060f, 0.3127f,0.3290f}},
{ KHR_DF_PRIMARIES_BT601_EBU, { 0.640f,0.330f, 0.290f,0.600f, 0.150f,0.060f, 0.3127f,0.3290f}},
{ KHR_DF_PRIMARIES_BT601_SMPTE, { 0.630f,0.340f, 0.310f,0.595f, 0.155f,0.070f, 0.3127f,0.3290f}},
{ KHR_DF_PRIMARIES_BT2020, { 0.708f,0.292f, 0.170f,0.797f, 0.131f,0.046f, 0.3127f,0.3290f}},
{ KHR_DF_PRIMARIES_CIEXYZ, { 1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f}},
{ KHR_DF_PRIMARIES_ACES, { 0.7347f,0.2653f, 0.0f,1.0f, 0.0001f,-0.077f, 0.32168f,0.33767f}},
{ KHR_DF_PRIMARIES_ACESCC, { 0.713f,0.293f, 0.165f,0.830f, 0.128f,0.044f, 0.32168f,0.33767f}},
{ KHR_DF_PRIMARIES_NTSC1953, { 0.67f,0.33f, 0.21f,0.71f, 0.14f,0.08f, 0.310f,0.316f}},
{ KHR_DF_PRIMARIES_PAL525, { 0.630f,0.340f, 0.310f,0.595f, 0.155f,0.070f, 0.3101f,0.3162f}},
{ KHR_DF_PRIMARIES_DISPLAYP3, { 0.6800f,0.3200f, 0.2650f,0.69f, 0.1500f,0.0600f, 0.3127f,0.3290f}},
{ KHR_DF_PRIMARIES_ADOBERGB, { 0.6400f,0.3300f, 0.2100f,0.71f, 0.1500f,0.0600f, 0.3127f,0.3290f}}};
/**
* @brief Map a set of primaries to a KDFS primaries enum.
*
* @param[in] p pointer to a Primaries struct filled in with the primary values.
* @param[in] latitude tolerance to use while matching. A suitable value might be 0.002
* but it depends on the application.
*/
khr_df_primaries_e findMapping(const Primaries *p, float latitude) {
unsigned int i;
for (i = 0; i < sizeof(primaryMap)/sizeof(sPrimaryMapping); ++i) {
if (primaryMap[i].primaries.Rx - p->Rx <= latitude && p->Rx - primaryMap[i].primaries.Rx <= latitude &&
primaryMap[i].primaries.Gx - p->Gx <= latitude && p->Gx - primaryMap[i].primaries.Gx <= latitude &&
primaryMap[i].primaries.Bx - p->Bx <= latitude && p->Bx - primaryMap[i].primaries.Bx <= latitude &&
primaryMap[i].primaries.Wx - p->Wx <= latitude && p->Wx - primaryMap[i].primaries.Wx <= latitude) {
return primaryMap[i].dfPrimaryEnum;
}
}
/* No match */
return KHR_DF_PRIMARIES_UNSPECIFIED;
}
/**
* @brief Get the primaries corresponding to a KDFS primaries enum.
*
* @param[in] primaries the enum identifying the KDFS primaries.
* @param[out] p pointer to a Primaries struct that will
* be filled with the primary values.
*/
bool getPrimaries(khr_df_primaries_e primaries, Primaries *p) {
unsigned int i;
for (i = 0; i < sizeof(primaryMap)/sizeof(sPrimaryMapping); ++i) {
if (primaryMap[i].dfPrimaryEnum == primaries) {
*p = primaryMap[i].primaries;
return true;
}
}
/* No match */
return false;
}
+809
View File
@@ -0,0 +1,809 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @~English
* @brief Utilities for creating data format descriptors.
*/
/*
* Author: Andrew Garrard
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <KHR/khr_df.h>
#include "dfd.h"
typedef enum { i_COLOR, i_NON_COLOR } channels_infotype;
static uint32_t *writeHeader(int numSamples, int bytes, int suffix,
channels_infotype infotype)
{
uint32_t *DFD = (uint32_t *) malloc(sizeof(uint32_t) *
(1 + KHR_DF_WORD_SAMPLESTART +
numSamples * KHR_DF_WORD_SAMPLEWORDS));
uint32_t* BDFD = DFD+1;
DFD[0] = sizeof(uint32_t) *
(1 + KHR_DF_WORD_SAMPLESTART +
numSamples * KHR_DF_WORD_SAMPLEWORDS);
BDFD[KHR_DF_WORD_VENDORID] =
(KHR_DF_VENDORID_KHRONOS << KHR_DF_SHIFT_VENDORID) |
(KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT << KHR_DF_SHIFT_DESCRIPTORTYPE);
BDFD[KHR_DF_WORD_VERSIONNUMBER] =
(KHR_DF_VERSIONNUMBER_LATEST << KHR_DF_SHIFT_VERSIONNUMBER) |
(((uint32_t)sizeof(uint32_t) *
(KHR_DF_WORD_SAMPLESTART +
numSamples * KHR_DF_WORD_SAMPLEWORDS)
<< KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE));
BDFD[KHR_DF_WORD_MODEL] =
((KHR_DF_MODEL_RGBSDA << KHR_DF_SHIFT_MODEL) | /* Only supported model */
(KHR_DF_FLAG_ALPHA_STRAIGHT << KHR_DF_SHIFT_FLAGS));
if (infotype == i_COLOR) {
BDFD[KHR_DF_WORD_PRIMARIES] |= KHR_DF_PRIMARIES_BT709 << KHR_DF_SHIFT_PRIMARIES; /* Assumed */
} else {
BDFD[KHR_DF_WORD_PRIMARIES] |= KHR_DF_PRIMARIES_UNSPECIFIED << KHR_DF_SHIFT_PRIMARIES;
}
if (suffix == s_SRGB) {
BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_SRGB << KHR_DF_SHIFT_TRANSFER;
} else {
BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_LINEAR << KHR_DF_SHIFT_TRANSFER;
}
BDFD[KHR_DF_WORD_TEXELBLOCKDIMENSION0] = 0; /* Only 1x1x1x1 texel blocks supported */
BDFD[KHR_DF_WORD_BYTESPLANE0] = bytes; /* bytesPlane0 = bytes, bytesPlane3..1 = 0 */
BDFD[KHR_DF_WORD_BYTESPLANE4] = 0; /* bytesPlane7..5 = 0 */
return DFD;
}
static uint32_t setChannelFlags(uint32_t channel, enum VkSuffix suffix)
{
switch (suffix) {
case s_UNORM: break;
case s_SNORM:
channel |=
KHR_DF_SAMPLE_DATATYPE_SIGNED;
break;
case s_USCALED: break;
case s_SSCALED:
channel |=
KHR_DF_SAMPLE_DATATYPE_SIGNED;
break;
case s_UINT: break;
case s_SINT:
channel |=
KHR_DF_SAMPLE_DATATYPE_SIGNED;
break;
case s_SFLOAT:
channel |=
KHR_DF_SAMPLE_DATATYPE_FLOAT |
KHR_DF_SAMPLE_DATATYPE_SIGNED;
break;
case s_UFLOAT:
channel |=
KHR_DF_SAMPLE_DATATYPE_FLOAT;
break;
case s_SRGB:
if (channel == KHR_DF_CHANNEL_RGBSDA_ALPHA) {
channel |= KHR_DF_SAMPLE_DATATYPE_LINEAR;
}
break;
case s_SFIXED5:
channel |=
KHR_DF_SAMPLE_DATATYPE_SIGNED;
break;
}
return channel;
}
static void writeSample(uint32_t *DFD, int sampleNo, int channel,
int bits, int offset,
int topSample, int bottomSample, enum VkSuffix suffix)
{
// Use this to avoid type-punning complaints from the gcc optimizer
// with -Wall.
union {
uint32_t i;
float f;
} lower, upper;
uint32_t *sample = DFD + 1 + KHR_DF_WORD_SAMPLESTART + sampleNo * KHR_DF_WORD_SAMPLEWORDS;
if (channel == 3) channel = KHR_DF_CHANNEL_RGBSDA_ALPHA;
channel = setChannelFlags(channel, suffix);
sample[KHR_DF_SAMPLEWORD_BITOFFSET] =
(offset << KHR_DF_SAMPLESHIFT_BITOFFSET) |
((bits - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) |
(channel << KHR_DF_SAMPLESHIFT_CHANNELID);
sample[KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL] = 0;
switch (suffix) {
case s_UNORM:
case s_SRGB:
default:
if (bits > 32) {
upper.i = 0xFFFFFFFFU;
} else {
upper.i = (uint32_t)((1U << bits) - 1U);
}
lower.i = 0U;
break;
case s_SNORM:
if (bits > 32) {
upper.i = 0x7FFFFFFF;
} else {
upper.i = topSample ? (1U << (bits - 1)) - 1 : (1U << bits) - 1;
}
lower.i = ~upper.i;
if (bottomSample) lower.i += 1;
break;
case s_USCALED:
case s_UINT:
upper.i = bottomSample ? 1U : 0U;
lower.i = 0U;
break;
case s_SSCALED:
case s_SINT:
upper.i = bottomSample ? 1U : 0U;
lower.i = ~0U;
break;
case s_SFLOAT:
upper.f = 1.0f;
lower.f = -1.0f;
break;
case s_UFLOAT:
upper.f = 1.0f;
lower.f = 0.0f;
break;
case s_SFIXED5:
assert(bits == 16 && "Format with this suffix must be 16 bits per channel.");
upper.i = 32;
lower.i = ~upper.i + 1; // -32
}
sample[KHR_DF_SAMPLEWORD_SAMPLELOWER] = lower.i;
sample[KHR_DF_SAMPLEWORD_SAMPLEUPPER] = upper.i;
}
/**
* @~English
* @brief Create a Data Format Descriptor for an unpacked format.
*
* @param bigEndian Set to 1 for big-endian byte ordering and
0 for little-endian byte ordering.
* @param numChannels The number of color channels.
* @param bytes The number of bytes per channel.
* @param redBlueSwap Normally channels appear in consecutive R, G, B, A order
* in memory; redBlueSwap inverts red and blue, allowing
* B, G, R, A.
* @param suffix Indicates the format suffix for the type.
*
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
int redBlueSwap, enum VkSuffix suffix)
{
uint32_t *DFD;
if (bigEndian) {
int channelCounter, channelByte;
/* Number of samples = number of channels * bytes per channel */
DFD = writeHeader(numChannels * bytes, numChannels * bytes, suffix, i_COLOR);
/* First loop over the channels */
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
int channel = channelCounter;
if (redBlueSwap && (channel == 0 || channel == 2)) {
channel ^= 2;
}
/* Loop over the bytes that constitute a channel */
for (channelByte = 0; channelByte < bytes; ++channelByte) {
writeSample(DFD, channelCounter * bytes + channelByte, channel,
8, 8 * (channelCounter * bytes + bytes - channelByte - 1),
channelByte == bytes-1, channelByte == 0, suffix);
}
}
} else { /* Little-endian */
int sampleCounter;
/* One sample per channel */
DFD = writeHeader(numChannels, numChannels * bytes, suffix, i_COLOR);
for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
int channel = sampleCounter;
if (redBlueSwap && (channel == 0 || channel == 2)) {
channel ^= 2;
}
writeSample(DFD, sampleCounter, channel,
8 * bytes, 8 * sampleCounter * bytes,
1, 1, suffix);
}
}
return DFD;
}
/**
* @~English
* @brief Create a Data Format Descriptor for a packed format.
*
* @param bigEndian Big-endian flag: Set to 1 for big-endian byte ordering and
* 0 for little-endian byte ordering.
* @param numChannels The number of color channels.
* @param bits[] An array of length numChannels.
* Each entry is the number of bits composing the channel, in
* order starting at bit 0 of the packed type.
* @param shiftBits[] An array of length numChannels.
* Each entry is the number of bits each channel is shifted
* and thus padded with insignificant bits.
* @param channels[] An array of length numChannels.
* Each entry enumerates the channel type: 0 = red, 1 = green,
* 2 = blue, 15 = alpha, in order starting at bit 0 of the
* packed type. These values match channel IDs for RGBSDA in
* the Khronos Data Format header. To simplify iteration
* through channels, channel id 3 is a synonym for alpha.
* @param suffix Indicates the format suffix for the type.
*
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDPackedShifted(int bigEndian, int numChannels,
int bits[], int shiftBits[], int channels[],
enum VkSuffix suffix)
{
uint32_t *DFD = 0;
if (numChannels == 6) {
/* Special case E5B9G9R9 */
DFD = writeHeader(numChannels, 4, s_UFLOAT, i_COLOR);
writeSample(DFD, 0, 0,
9, 0,
1, 1, s_UNORM);
KHR_DFDSETSVAL((DFD+1), 0, SAMPLEUPPER, 8448);
writeSample(DFD, 1, 0 | KHR_DF_SAMPLE_DATATYPE_EXPONENT,
5, 27,
1, 1, s_UNORM);
KHR_DFDSETSVAL((DFD+1), 1, SAMPLELOWER, 15);
KHR_DFDSETSVAL((DFD+1), 1, SAMPLEUPPER, 31);
writeSample(DFD, 2, 1,
9, 9,
1, 1, s_UNORM);
KHR_DFDSETSVAL((DFD+1), 2, SAMPLEUPPER, 8448);
writeSample(DFD, 3, 1 | KHR_DF_SAMPLE_DATATYPE_EXPONENT,
5, 27,
1, 1, s_UNORM);
KHR_DFDSETSVAL((DFD+1), 3, SAMPLELOWER, 15);
KHR_DFDSETSVAL((DFD+1), 3, SAMPLEUPPER, 31);
writeSample(DFD, 4, 2,
9, 18,
1, 1, s_UNORM);
KHR_DFDSETSVAL((DFD+1), 4, SAMPLEUPPER, 8448);
writeSample(DFD, 5, 2 | KHR_DF_SAMPLE_DATATYPE_EXPONENT,
5, 27,
1, 1, s_UNORM);
KHR_DFDSETSVAL((DFD+1), 5, SAMPLELOWER, 15);
KHR_DFDSETSVAL((DFD+1), 5, SAMPLEUPPER, 31);
} else if (bigEndian) {
/* No packed format is larger than 32 bits. */
/* No packed channel crosses more than two bytes. */
int totalBits = 0;
int bitChannel[32];
int beChannelStart[4];
int channelCounter;
int bitOffset = 0;
int BEMask;
int numSamples = numChannels;
int sampleCounter;
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
beChannelStart[channelCounter] = totalBits;
totalBits += shiftBits[channelCounter] + bits[channelCounter];
}
BEMask = (totalBits - 1) & 0x18;
for (channelCounter = 0; channelCounter < numChannels; ++channelCounter) {
bitOffset += shiftBits[channelCounter];
bitChannel[bitOffset ^ BEMask] = channelCounter;
if (((bitOffset + bits[channelCounter] - 1) & ~7) != (bitOffset & ~7)) {
/* Continuation sample */
bitChannel[((bitOffset + bits[channelCounter] - 1) & ~7) ^ BEMask] = channelCounter;
numSamples++;
}
bitOffset += bits[channelCounter];
}
DFD = writeHeader(numSamples, totalBits >> 3, suffix, i_COLOR);
sampleCounter = 0;
for (bitOffset = 0; bitOffset < totalBits;) {
if (bitChannel[bitOffset] == -1) {
/* Done this bit, so this is the lower half of something. */
/* We must therefore jump to the end of the byte and continue. */
bitOffset = (bitOffset + 8) & ~7;
} else {
/* Start of a channel? */
int thisChannel = bitChannel[bitOffset];
if ((beChannelStart[thisChannel] ^ BEMask) == bitOffset) {
/* Must be just one sample if we hit it first. */
writeSample(DFD, sampleCounter++, channels[thisChannel],
bits[thisChannel], bitOffset,
1, 1, suffix);
bitOffset += bits[thisChannel];
} else {
/* Two samples. Move to the end of the first one we hit when we're done. */
int firstSampleBits = 8 - (beChannelStart[thisChannel] & 0x7); /* Rest of the byte */
int secondSampleBits = bits[thisChannel] - firstSampleBits; /* Rest of the bits */
writeSample(DFD, sampleCounter++, channels[thisChannel],
firstSampleBits, beChannelStart[thisChannel] ^ BEMask,
0, 1, suffix);
/* Mark that we've already handled this sample */
bitChannel[beChannelStart[thisChannel] ^ BEMask] = -1;
writeSample(DFD, sampleCounter++, channels[thisChannel],
secondSampleBits, bitOffset,
1, 0, suffix);
bitOffset += secondSampleBits;
}
}
}
} else { /* Little-endian */
int sampleCounter;
int totalBits = 0;
int bitOffset = 0;
for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
totalBits += shiftBits[sampleCounter] + bits[sampleCounter];
}
/* One sample per channel */
DFD = writeHeader(numChannels, totalBits >> 3, suffix, i_COLOR);
for (sampleCounter = 0; sampleCounter < numChannels; ++sampleCounter) {
bitOffset += shiftBits[sampleCounter];
writeSample(DFD, sampleCounter, channels[sampleCounter],
bits[sampleCounter], bitOffset,
1, 1, suffix);
bitOffset += bits[sampleCounter];
}
}
return DFD;
}
/**
* @~English
* @brief Create a Data Format Descriptor for a packed format.
*
* @param bigEndian Big-endian flag: Set to 1 for big-endian byte ordering and
* 0 for little-endian byte ordering.
* @param numChannels The number of color channels.
* @param bits[] An array of length numChannels.
* Each entry is the number of bits composing the channel, in
* order starting at bit 0 of the packed type.
* @param channels[] An array of length numChannels.
* Each entry enumerates the channel type: 0 = red, 1 = green,
* 2 = blue, 15 = alpha, in order starting at bit 0 of the
* packed type. These values match channel IDs for RGBSDA in
* the Khronos Data Format header. To simplify iteration
* through channels, channel id 3 is a synonym for alpha.
* @param suffix Indicates the format suffix for the type.
*
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDPacked(int bigEndian, int numChannels,
int bits[], int channels[],
enum VkSuffix suffix) {
assert(numChannels <= 6);
int shiftBits[] = {0, 0, 0, 0, 0, 0};
return createDFDPackedShifted(bigEndian, numChannels, bits, shiftBits, channels, suffix);
}
uint32_t *createDFD422(int bigEndian, int numSamples,
int bits[], int shiftBits[], int channels[],
int position_xs[], int position_ys[],
enum VkSuffix suffix) {
assert(!bigEndian); (void) bigEndian;
assert(suffix == s_UNORM); (void) suffix;
int totalBits = 0;
for (int i = 0; i < numSamples; ++i)
totalBits += shiftBits[i] + bits[i];
assert(totalBits % 8 == 0);
uint32_t BDFDSize = sizeof(uint32_t) * (KHR_DF_WORD_SAMPLESTART + numSamples * KHR_DF_WORD_SAMPLEWORDS);
uint32_t DFDSize = sizeof(uint32_t) + BDFDSize;
uint32_t *DFD = (uint32_t *) malloc(DFDSize);
memset(DFD, 0, DFDSize);
DFD[0] = DFDSize;
uint32_t *BDFD = DFD + 1;
KHR_DFDSETVAL(BDFD, VENDORID, KHR_DF_VENDORID_KHRONOS);
KHR_DFDSETVAL(BDFD, DESCRIPTORTYPE, KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT);
KHR_DFDSETVAL(BDFD, VERSIONNUMBER, KHR_DF_VERSIONNUMBER_LATEST);
KHR_DFDSETVAL(BDFD, DESCRIPTORBLOCKSIZE, BDFDSize);
KHR_DFDSETVAL(BDFD, MODEL, KHR_DF_MODEL_YUVSDA);
KHR_DFDSETVAL(BDFD, PRIMARIES, KHR_DF_PRIMARIES_UNSPECIFIED);
KHR_DFDSETVAL(BDFD, TRANSFER, KHR_DF_TRANSFER_LINEAR);
KHR_DFDSETVAL(BDFD, FLAGS, KHR_DF_FLAG_ALPHA_STRAIGHT);
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION0, 2 - 1); // 422 contains 2 x 1 blocks
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION1, 1 - 1);
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION2, 1 - 1);
KHR_DFDSETVAL(BDFD, TEXELBLOCKDIMENSION3, 1 - 1);
KHR_DFDSETVAL(BDFD, BYTESPLANE0, totalBits / 8);
KHR_DFDSETVAL(BDFD, BYTESPLANE1, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE2, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE3, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE4, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE5, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE6, 0);
KHR_DFDSETVAL(BDFD, BYTESPLANE7, 0);
int bitOffset = 0;
for (int i = 0; i < numSamples; ++i) {
bitOffset += shiftBits[i];
KHR_DFDSETSVAL(BDFD, i, BITOFFSET, bitOffset);
KHR_DFDSETSVAL(BDFD, i, BITLENGTH, bits[i] - 1);
KHR_DFDSETSVAL(BDFD, i, CHANNELID, channels[i]);
KHR_DFDSETSVAL(BDFD, i, QUALIFIERS, 0); // None of: FLOAT, SIGNED, EXPONENT, LINEAR
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION0, position_xs[i]);
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION1, position_ys[i]);
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION2, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLEPOSITION3, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLELOWER, 0);
KHR_DFDSETSVAL(BDFD, i, SAMPLEUPPER, (1u << bits[i]) - 1u);
bitOffset += bits[i];
}
return DFD;
}
static khr_df_model_e compModelMapping[] = {
KHR_DF_MODEL_BC1A, /*!< BC1, aka DXT1, no alpha. */
KHR_DF_MODEL_BC1A, /*!< BC1, aka DXT1, punch-through alpha. */
KHR_DF_MODEL_BC2, /*!< BC2, aka DXT2 and DXT3. */
KHR_DF_MODEL_BC3, /*!< BC3, aka DXT4 and DXT5. */
KHR_DF_MODEL_BC4, /*!< BC4. */
KHR_DF_MODEL_BC5, /*!< BC5. */
KHR_DF_MODEL_BC6H, /*!< BC6h HDR format. */
KHR_DF_MODEL_BC7, /*!< BC7. */
KHR_DF_MODEL_ETC2, /*!< ETC2 no alpha. */
KHR_DF_MODEL_ETC2, /*!< ETC2 punch-through alpha. */
KHR_DF_MODEL_ETC2, /*!< ETC2 independent alpha. */
KHR_DF_MODEL_ETC2, /*!< R11 ETC2 single-channel. */
KHR_DF_MODEL_ETC2, /*!< R11G11 ETC2 dual-channel. */
KHR_DF_MODEL_ASTC, /*!< ASTC. */
KHR_DF_MODEL_ETC1S, /*!< ETC1S. */
KHR_DF_MODEL_PVRTC, /*!< PVRTC(1). */
KHR_DF_MODEL_PVRTC2 /*!< PVRTC2. */
};
static uint32_t compSampleCount[] = {
1U, /*!< BC1, aka DXT1, no alpha. */
1U, /*!< BC1, aka DXT1, punch-through alpha. */
2U, /*!< BC2, aka DXT2 and DXT3. */
2U, /*!< BC3, aka DXT4 and DXT5. */
1U, /*!< BC4. */
2U, /*!< BC5. */
1U, /*!< BC6h HDR format. */
1U, /*!< BC7. */
1U, /*!< ETC2 no alpha. */
2U, /*!< ETC2 punch-through alpha. */
2U, /*!< ETC2 independent alpha. */
1U, /*!< R11 ETC2 single-channel. */
2U, /*!< R11G11 ETC2 dual-channel. */
1U, /*!< ASTC. */
1U, /*!< ETC1S. */
1U, /*!< PVRTC. */
1U /*!< PVRTC2. */
};
static khr_df_model_channels_e compFirstChannel[] = {
KHR_DF_CHANNEL_BC1A_COLOR, /*!< BC1, aka DXT1, no alpha. */
KHR_DF_CHANNEL_BC1A_ALPHAPRESENT, /*!< BC1, aka DXT1, punch-through alpha. */
KHR_DF_CHANNEL_BC2_ALPHA, /*!< BC2, aka DXT2 and DXT3. */
KHR_DF_CHANNEL_BC3_ALPHA, /*!< BC3, aka DXT4 and DXT5. */
KHR_DF_CHANNEL_BC4_DATA, /*!< BC4. */
KHR_DF_CHANNEL_BC5_RED, /*!< BC5. */
KHR_DF_CHANNEL_BC6H_COLOR, /*!< BC6h HDR format. */
KHR_DF_CHANNEL_BC7_COLOR, /*!< BC7. */
KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 no alpha. */
KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 punch-through alpha. */
KHR_DF_CHANNEL_ETC2_ALPHA, /*!< ETC2 independent alpha. */
KHR_DF_CHANNEL_ETC2_RED, /*!< R11 ETC2 single-channel. */
KHR_DF_CHANNEL_ETC2_RED, /*!< R11G11 ETC2 dual-channel. */
KHR_DF_CHANNEL_ASTC_DATA, /*!< ASTC. */
KHR_DF_CHANNEL_ETC1S_RGB, /*!< ETC1S. */
KHR_DF_CHANNEL_PVRTC_COLOR, /*!< PVRTC. */
KHR_DF_CHANNEL_PVRTC2_COLOR /*!< PVRTC2. */
};
static khr_df_model_channels_e compSecondChannel[] = {
KHR_DF_CHANNEL_BC1A_COLOR, /*!< BC1, aka DXT1, no alpha. */
KHR_DF_CHANNEL_BC1A_ALPHAPRESENT, /*!< BC1, aka DXT1, punch-through alpha. */
KHR_DF_CHANNEL_BC2_COLOR, /*!< BC2, aka DXT2 and DXT3. */
KHR_DF_CHANNEL_BC3_COLOR, /*!< BC3, aka DXT4 and DXT5. */
KHR_DF_CHANNEL_BC4_DATA, /*!< BC4. */
KHR_DF_CHANNEL_BC5_GREEN, /*!< BC5. */
KHR_DF_CHANNEL_BC6H_COLOR, /*!< BC6h HDR format. */
KHR_DF_CHANNEL_BC7_COLOR, /*!< BC7. */
KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 no alpha. */
KHR_DF_CHANNEL_ETC2_ALPHA, /*!< ETC2 punch-through alpha. */
KHR_DF_CHANNEL_ETC2_COLOR, /*!< ETC2 independent alpha. */
KHR_DF_CHANNEL_ETC2_RED, /*!< R11 ETC2 single-channel. */
KHR_DF_CHANNEL_ETC2_GREEN, /*!< R11G11 ETC2 dual-channel. */
KHR_DF_CHANNEL_ASTC_DATA, /*!< ASTC. */
KHR_DF_CHANNEL_ETC1S_RGB, /*!< ETC1S. */
KHR_DF_CHANNEL_PVRTC_COLOR, /*!< PVRTC. */
KHR_DF_CHANNEL_PVRTC2_COLOR /*!< PVRTC2. */
};
static uint32_t compSecondChannelOffset[] = {
0U, /*!< BC1, aka DXT1, no alpha. */
0U, /*!< BC1, aka DXT1, punch-through alpha. */
64U, /*!< BC2, aka DXT2 and DXT3. */
64U, /*!< BC3, aka DXT4 and DXT5. */
0U, /*!< BC4. */
64U, /*!< BC5. */
0U, /*!< BC6h HDR format. */
0U, /*!< BC7. */
0U, /*!< ETC2 no alpha. */
0U, /*!< ETC2 punch-through alpha. */
64U, /*!< ETC2 independent alpha. */
0U, /*!< R11 ETC2 single-channel. */
64U, /*!< R11G11 ETC2 dual-channel. */
0U, /*!< ASTC. */
0U, /*!< ETC1S. */
0U, /*!< PVRTC. */
0U /*!< PVRTC2. */
};
static uint32_t compChannelBits[] = {
64U, /*!< BC1, aka DXT1, no alpha. */
64U, /*!< BC1, aka DXT1, punch-through alpha. */
64U, /*!< BC2, aka DXT2 and DXT3. */
64U, /*!< BC3, aka DXT4 and DXT5. */
64U, /*!< BC4. */
64U, /*!< BC5. */
128U, /*!< BC6h HDR format. */
128U, /*!< BC7. */
64U, /*!< ETC2 no alpha. */
64U, /*!< ETC2 punch-through alpha. */
64U, /*!< ETC2 independent alpha. */
64U, /*!< R11 ETC2 single-channel. */
64U, /*!< R11G11 ETC2 dual-channel. */
128U, /*!< ASTC. */
64U, /*!< ETC1S. */
64U, /*!< PVRTC. */
64U /*!< PVRTC2. */
};
static uint32_t compBytes[] = {
8U, /*!< BC1, aka DXT1, no alpha. */
8U, /*!< BC1, aka DXT1, punch-through alpha. */
16U, /*!< BC2, aka DXT2 and DXT3. */
16U, /*!< BC3, aka DXT4 and DXT5. */
8U, /*!< BC4. */
16U, /*!< BC5. */
16U, /*!< BC6h HDR format. */
16U, /*!< BC7. */
8U, /*!< ETC2 no alpha. */
8U, /*!< ETC2 punch-through alpha. */
16U, /*!< ETC2 independent alpha. */
8U, /*!< R11 ETC2 single-channel. */
16U, /*!< R11G11 ETC2 dual-channel. */
16U, /*!< ASTC. */
8U, /*!< ETC1S. */
8U, /*!< PVRTC. */
8U /*!< PVRTC2. */
};
/**
* @~English
* @brief Create a Data Format Descriptor for a compressed format.
*
* @param compScheme Vulkan-style compression scheme enumeration.
* @param bwidth Block width in texel coordinates.
* @param bheight Block height in texel coordinates.
* @param bdepth Block depth in texel coordinates.
* @author Mark Callow, github.com/MarkCallow.
* @param suffix Indicates the format suffix for the type.
*
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDCompressed(enum VkCompScheme compScheme, int bwidth, int bheight, int bdepth,
enum VkSuffix suffix)
{
uint32_t *DFD = 0;
uint32_t numSamples = compSampleCount[compScheme];
uint32_t* BDFD;
uint32_t *sample;
uint32_t channel;
// Use union to avoid type-punning complaints from gcc optimizer
// with -Wall.
union {
uint32_t i;
float f;
} lower, upper;
DFD = (uint32_t *) malloc(sizeof(uint32_t) *
(1 + KHR_DF_WORD_SAMPLESTART +
numSamples * KHR_DF_WORD_SAMPLEWORDS));
BDFD = DFD+1;
DFD[0] = sizeof(uint32_t) *
(1 + KHR_DF_WORD_SAMPLESTART +
numSamples * KHR_DF_WORD_SAMPLEWORDS);
BDFD[KHR_DF_WORD_VENDORID] =
(KHR_DF_VENDORID_KHRONOS << KHR_DF_SHIFT_VENDORID) |
(KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT << KHR_DF_SHIFT_DESCRIPTORTYPE);
BDFD[KHR_DF_WORD_VERSIONNUMBER] =
(KHR_DF_VERSIONNUMBER_LATEST << KHR_DF_SHIFT_VERSIONNUMBER) |
(((uint32_t)sizeof(uint32_t) *
(KHR_DF_WORD_SAMPLESTART +
numSamples * KHR_DF_WORD_SAMPLEWORDS)
<< KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE));
BDFD[KHR_DF_WORD_MODEL] =
((compModelMapping[compScheme] << KHR_DF_SHIFT_MODEL) |
(KHR_DF_PRIMARIES_BT709 << KHR_DF_SHIFT_PRIMARIES) | /* Assumed */
(KHR_DF_FLAG_ALPHA_STRAIGHT << KHR_DF_SHIFT_FLAGS));
if (suffix == s_SRGB) {
BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_SRGB << KHR_DF_SHIFT_TRANSFER;
} else {
BDFD[KHR_DF_WORD_TRANSFER] |= KHR_DF_TRANSFER_LINEAR << KHR_DF_SHIFT_TRANSFER;
}
BDFD[KHR_DF_WORD_TEXELBLOCKDIMENSION0] =
(bwidth - 1) | ((bheight - 1) << KHR_DF_SHIFT_TEXELBLOCKDIMENSION1) | ((bdepth - 1) << KHR_DF_SHIFT_TEXELBLOCKDIMENSION2);
/* bytesPlane0 = bytes, bytesPlane3..1 = 0 */
BDFD[KHR_DF_WORD_BYTESPLANE0] = compBytes[compScheme];
BDFD[KHR_DF_WORD_BYTESPLANE4] = 0; /* bytesPlane7..5 = 0 */
sample = BDFD + KHR_DF_WORD_SAMPLESTART;
channel = compFirstChannel[compScheme];
channel = setChannelFlags(channel, suffix);
sample[KHR_DF_SAMPLEWORD_BITOFFSET] =
(0 << KHR_DF_SAMPLESHIFT_BITOFFSET) |
((compChannelBits[compScheme] - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) |
(channel << KHR_DF_SAMPLESHIFT_CHANNELID);
sample[KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL] = 0;
switch (suffix) {
case s_UNORM:
case s_SRGB:
default:
upper.i = 0xFFFFFFFFU;
lower.i = 0U;
break;
case s_SNORM:
upper.i = 0x7FFFFFFF;
lower.i = ~upper.i;
break;
case s_USCALED:
case s_UINT:
upper.i = 1U;
lower.i = 0U;
break;
case s_SSCALED:
case s_SINT:
upper.i = 1U;
lower.i = ~0U;
break;
case s_SFLOAT:
upper.f = 1.0f;
lower.f = -1.0f;
break;
case s_UFLOAT:
upper.f = 1.0f;
lower.f = 0.0f;
break;
}
sample[KHR_DF_SAMPLEWORD_SAMPLELOWER] = lower.i;
sample[KHR_DF_SAMPLEWORD_SAMPLEUPPER] = upper.i;
if (compSampleCount[compScheme] > 1) {
sample += KHR_DF_WORD_SAMPLEWORDS;
channel = compSecondChannel[compScheme];
channel = setChannelFlags(channel, suffix);
sample[KHR_DF_SAMPLEWORD_BITOFFSET] =
(compSecondChannelOffset[compScheme] << KHR_DF_SAMPLESHIFT_BITOFFSET) |
((compChannelBits[compScheme] - 1) << KHR_DF_SAMPLESHIFT_BITLENGTH) |
(channel << KHR_DF_SAMPLESHIFT_CHANNELID);
sample[KHR_DF_SAMPLEWORD_SAMPLEPOSITION_ALL] = 0;
sample[KHR_DF_SAMPLEWORD_SAMPLELOWER] = lower.i;
sample[KHR_DF_SAMPLEWORD_SAMPLEUPPER] = upper.i;
}
return DFD;
}
/**
* @~English
* @brief Create a Data Format Descriptor for a depth-stencil format.
*
* @param depthBits The numeber of bits in the depth channel.
* @param stencilBits The numeber of bits in the stencil channel.
* @param sizeBytes The total byte size of the texel.
*
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDDepthStencil(int depthBits,
int stencilBits,
int sizeBytes)
{
/* N.B. Little-endian is assumed. */
uint32_t *DFD = 0;
DFD = writeHeader((depthBits > 0) + (stencilBits > 0),
sizeBytes, s_UNORM, i_NON_COLOR);
/* Handle the special case of D24_UNORM_S8_UINT where the order of the
channels is flipped by putting stencil in the LSBs. */
if (depthBits == 24 && stencilBits == 8) {
writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_STENCIL,
8, 0,
1, 1, s_UINT);
writeSample(DFD, 1, KHR_DF_CHANNEL_RGBSDA_DEPTH,
24, 8,
1, 1, s_UNORM);
return DFD;
}
if (depthBits == 32) {
writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_DEPTH,
32, 0,
1, 1, s_SFLOAT);
} else if (depthBits > 0) {
writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_DEPTH,
depthBits, 0,
1, 1, s_UNORM);
}
if (stencilBits > 0) {
if (depthBits > 0) {
writeSample(DFD, 1, KHR_DF_CHANNEL_RGBSDA_STENCIL,
stencilBits, depthBits,
1, 1, s_UINT);
} else {
writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_STENCIL,
stencilBits, 0,
1, 1, s_UINT);
}
}
return DFD;
}
/**
* @~English
* @brief Create a Data Format Descriptor for an alpha-only format.
*
* @param bigEndian Set to 1 for big-endian byte ordering and
0 for little-endian byte ordering.
* @param bytes The number of bytes per channel.
* @param suffix Indicates the format suffix for the type.
*
* @return A data format descriptor in malloc'd data. The caller is responsible
* for freeing the descriptor.
**/
uint32_t *createDFDAlpha(int bigEndian, int bytes,
enum VkSuffix suffix) {
uint32_t *DFD;
int channel = 3; /* alpha channel */
if (bigEndian) {
int channelByte;
/* Number of samples = number of channels * bytes per channel */
DFD = writeHeader(bytes, bytes, suffix, i_COLOR);
/* Loop over the bytes that constitute a channel */
for (channelByte = 0; channelByte < bytes; ++channelByte) {
writeSample(DFD, channelByte, channel,
8, 8 * (bytes - channelByte - 1),
channelByte == bytes-1, channelByte == 0, suffix);
}
} else { /* Little-endian */
/* One sample per channel */
DFD = writeHeader(1, bytes, suffix, i_COLOR);
writeSample(DFD, 0, channel,
8 * bytes, 0,
1, 1, suffix);
}
return DFD;
}
+42
View File
@@ -0,0 +1,42 @@
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "dfd.h"
#define TESTRGB565 1
int main(int argc, char** argv)
{
#ifdef TESTRGBA8888
uint32_t *DFD = createDFDUnpacked(0, 4, 1, 1, s_UNORM);
#endif
#ifdef TESTRG16
uint32_t *DFD = createDFDUnpacked(1, 2, 2, 0, s_UNORM);
#endif
#ifdef TESTRG64
uint32_t *DFD = createDFDUnpacked(0, 2, 8, 0, s_UNORM);
#endif
#ifdef TESTRGBA4444
int bits[] = {4,4,4,4};
int channels[] = {3,2,1,0};
uint32_t *DFD = createDFDPacked(1, 2, bits, channels, s_UNORM);
#endif
#ifdef TESTRGBA1010102
int bits[] = {10,10,10,2};
int channels[] = {0,1,2,3};
/* 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 */
/* A1 A0 B9 B8 B7 B6 B5 B4 | B3 B2 B1 B0 G9 G8 G7 G6 | G5 G4 G3 G2 G1 G0 R9 R8 | R7 R6 R5 R4 R3 R2 R1 R0 */
/* 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 */
uint32_t *DFD = createDFDPacked(0, 4, bits, channels, s_UNORM);
#endif
#ifdef TESTRGB565
int bits[] = {5,6,5};
int channels[] = {0,1,2};
uint32_t *DFD = createDFDPacked(1, 3, bits, channels, s_UNORM);
#endif
printDFD(DFD, *DFD);
return 0;
}
+236
View File
@@ -0,0 +1,236 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @~English
* @brief Header file defining the data format descriptor utilities API.
*/
/*
* Author: Andrew Garrard
*/
#ifndef _DFD_H_
#define _DFD_H_
#include <KHR/khr_df.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Qualifier suffix to the format, in Vulkan terms. */
enum VkSuffix {
s_UNORM, /*!< Unsigned normalized format. */
s_SNORM, /*!< Signed normalized format. */
s_USCALED, /*!< Unsigned scaled format. */
s_SSCALED, /*!< Signed scaled format. */
s_UINT, /*!< Unsigned integer format. */
s_SINT, /*!< Signed integer format. */
s_SFLOAT, /*!< Signed float format. */
s_UFLOAT, /*!< Unsigned float format. */
s_SRGB, /*!< sRGB normalized format. */
s_SFIXED5 /*!< 2's complement fixed-point; 5 fractional bits. */
};
/** Compression scheme, in Vulkan terms. */
enum VkCompScheme {
c_BC1_RGB, /*!< BC1, aka DXT1, no alpha. */
c_BC1_RGBA, /*!< BC1, aka DXT1, punch-through alpha. */
c_BC2, /*!< BC2, aka DXT2 and DXT3. */
c_BC3, /*!< BC3, aka DXT4 and DXT5. */
c_BC4, /*!< BC4. */
c_BC5, /*!< BC5. */
c_BC6H, /*!< BC6h HDR format. */
c_BC7, /*!< BC7. */
c_ETC2_R8G8B8, /*!< ETC2 no alpha. */
c_ETC2_R8G8B8A1, /*!< ETC2 punch-through alpha. */
c_ETC2_R8G8B8A8, /*!< ETC2 independent alpha. */
c_EAC_R11, /*!< R11 ETC2 single-channel. */
c_EAC_R11G11, /*!< R11G11 ETC2 dual-channel. */
c_ASTC, /*!< ASTC. */
c_ETC1S, /*!< ETC1S. */
c_PVRTC, /*!< PVRTC(1). */
c_PVRTC2 /*!< PVRTC2. */
};
typedef unsigned int uint32_t;
#if !defined(LIBKTX)
#include <vulkan/vulkan_core.h>
#else
#include "../../lib/vkformat_enum.h"
#endif
uint32_t* vk2dfd(enum VkFormat format);
enum VkFormat dfd2vk(uint32_t* dfd);
/* Create a Data Format Descriptor for an unpacked format. */
uint32_t *createDFDUnpacked(int bigEndian, int numChannels, int bytes,
int redBlueSwap, enum VkSuffix suffix);
/* Create a Data Format Descriptor for a packed padded format. */
uint32_t *createDFDPackedShifted(int bigEndian, int numChannels,
int bits[], int shiftBits[],
int channels[], enum VkSuffix suffix);
/* Create a Data Format Descriptor for a packed format. */
uint32_t *createDFDPacked(int bigEndian, int numChannels,
int bits[], int channels[],
enum VkSuffix suffix);
/* Create a Data Format Descriptor for a 4:2:2 format. */
uint32_t *createDFD422(int bigEndian, int numChannels,
int bits[], int shiftBits[], int channels[],
int position_xs[], int position_ys[],
enum VkSuffix suffix);
/* Create a Data Format Descriptor for a compressed format. */
uint32_t *createDFDCompressed(enum VkCompScheme compScheme,
int bwidth, int bheight, int bdepth,
enum VkSuffix suffix);
/* Create a Data Format Descriptor for a depth/stencil format. */
uint32_t *createDFDDepthStencil(int depthBits,
int stencilBits,
int sizeBytes);
/* Create a Data Format Descriptor for an alpha-only format */
uint32_t *createDFDAlpha(int bigEndian, int bytes,
enum VkSuffix suffix);
/** @brief Result of interpreting the data format descriptor. */
enum InterpretDFDResult {
i_LITTLE_ENDIAN_FORMAT_BIT = 0, /*!< Confirmed little-endian (default for 8bpc). */
i_BIG_ENDIAN_FORMAT_BIT = 1u << 0u, /*!< Confirmed big-endian. */
i_PACKED_FORMAT_BIT = 1u << 1u, /*!< Packed format. */
i_SRGB_FORMAT_BIT = 1u << 2u, /*!< sRGB transfer function. */
i_NORMALIZED_FORMAT_BIT = 1u << 3u, /*!< Normalized (UNORM or SNORM). */
i_SIGNED_FORMAT_BIT = 1u << 4u, /*!< Format is signed. */
i_FIXED_FORMAT_BIT = 1u << 5u, /*!< Format is a fixed-point representation. */
i_FLOAT_FORMAT_BIT = 1u << 6u, /*!< Format is floating point. */
i_COMPRESSED_FORMAT_BIT = 1u << 7u, /*!< Format is block compressed (422). */
i_YUVSDA_FORMAT_BIT = 1u << 8u, /*!< Color model is YUVSDA. */
i_UNSUPPORTED_ERROR_BIT = 1u << 9u, /*!< Format not successfully interpreted. */
/** "NONTRIVIAL_ENDIANNESS" means not big-endian, not little-endian
* (a channel has bits that are not consecutive in either order). **/
i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS = i_UNSUPPORTED_ERROR_BIT,
/** "MULTIPLE_SAMPLE_LOCATIONS" is an error because only single-sample
* texel blocks (with coordinates 0,0,0,0 for all samples) are supported. **/
i_UNSUPPORTED_MULTIPLE_SAMPLE_LOCATIONS = i_UNSUPPORTED_ERROR_BIT + 1,
/** "MULTIPLE_PLANES" is an error because only contiguous data is supported. */
i_UNSUPPORTED_MULTIPLE_PLANES = i_UNSUPPORTED_ERROR_BIT + 2,
/** Only channels R, G, B and A are supported. */
i_UNSUPPORTED_CHANNEL_TYPES = i_UNSUPPORTED_ERROR_BIT + 3,
/** Only channels with the same flags are supported
* (e.g. we don't support float red with integer green). */
i_UNSUPPORTED_MIXED_CHANNELS = i_UNSUPPORTED_ERROR_BIT + 4,
/** Only 2x1 block is supported for YUVSDA model. */
i_UNSUPPORTED_BLOCK_DIMENSIONS = i_UNSUPPORTED_ERROR_BIT + 5,
};
/** @brief Interpretation of a channel from the data format descriptor. */
typedef struct _InterpretedDFDChannel {
uint32_t offset; /*!< Offset in bits for packed, bytes for unpacked. */
uint32_t size; /*!< Size in bits for packed, bytes for unpacked. */
} InterpretedDFDChannel;
/* Interpret a Data Format Descriptor. */
enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
InterpretedDFDChannel *R,
InterpretedDFDChannel *G,
InterpretedDFDChannel *B,
InterpretedDFDChannel *A,
uint32_t *wordBytes);
/* Returns the string representation.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringVendorID(khr_df_vendorid_e value);
/* Returns the string representation.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringDescriptorType(khr_df_khr_descriptortype_e value);
/* Returns the string representation.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringVersionNumber(khr_df_versionnumber_e value);
/* Returns the string representation of a bit in a khr_df_flags_e.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringFlagsBit(uint32_t bit_index, bool bit_value);
/* Returns the string representation.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringTransferFunction(khr_df_transfer_e value);
/* Returns the string representation.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringColorPrimaries(khr_df_primaries_e value);
/* Returns the string representation.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringColorModel(khr_df_model_e value);
/* Returns the string representation of a bit in a khr_df_sample_datatype_qualifiers_e.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringSampleDatatypeQualifiersBit(uint32_t bit_index, bool bit_value);
/* Returns the string representation.
* If there is no direct match or the value is invalid returns NULL */
const char* dfdToStringChannelId(khr_df_model_e model, khr_df_model_channels_e value);
/* Print a human-readable interpretation of a data format descriptor. */
void printDFD(uint32_t *DFD, uint32_t dataSize);
/* Print a JSON interpretation of a data format descriptor. */
void printDFDJSON(uint32_t *DFD, uint32_t dataSize, uint32_t base_indent, uint32_t indent_width, bool minified);
/* Get the number of components & component size from a DFD for an
* unpacked format.
*/
void getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents,
uint32_t* componentByteLength);
/* Return the number of components described by a DFD. */
uint32_t getDFDNumComponents(const uint32_t* DFD);
/* Reconstruct and update the bytesPlane[0-4] fields of an unsized DFD to what
* they were before supercompression.
*/
void reconstructDFDBytesPlanesFromSamples(uint32_t* DFD);
/* Deprecated. For backward compatibility. */
uint32_t reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD);
/* Deprecated. For backward compatibility. */
void recreateBytesPlane0FromSampleInfo(const uint32_t* DFD,
uint32_t* bytesPlane0);
/** @brief Colourspace primaries information.
*
* Structure to store the 1931 CIE x,y chromaticities of the red, green, and blue
* display primaries and the reference white point of a colourspace.
*/
typedef struct _Primaries {
float Rx; /*!< Red x. */
float Ry; /*!< Red y. */
float Gx; /*!< Green x. */
float Gy; /*!< Green y. */
float Bx; /*!< Blue x. */
float By; /*!< Blue y. */
float Wx; /*!< White x. */
float Wy; /*!< White y. */
} Primaries;
khr_df_primaries_e findMapping(const Primaries *p, float latitude);
bool getPrimaries(khr_df_primaries_e primaries, Primaries *p);
#ifdef __cplusplus
}
#endif
#endif /* _DFD_H_ */
+30
View File
@@ -0,0 +1,30 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/* Copyright 2019-2020 Mark Callow
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @~English
* @brief Find the VkFormat matching a DFD.
*/
#include <KHR/khr_df.h>
#include "dfd.h"
/**
* @~English
* @brief Return a VkFormat matching a DFD.
*
* @param[in] dfd Pointer to the DFD.
*
* @return The matching VkFormat enum or VK_FORMAT_UNDEFINED if not
* matched.
*/
enum VkFormat dfd2vk(uint32_t *dfd)
{
#include "dfd2vk.inl"
}
+663
View File
@@ -0,0 +1,663 @@
/* Copyright 2019-2020 The Khronos Group Inc. */
/* SPDX-License-Identifier: Apache-2.0 */
/***************************** Do not edit. *****************************
Automatically generated by makedfd2vk.pl.
*************************************************************************/
if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA || KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_YUVSDA) {
enum InterpretDFDResult r;
InterpretedDFDChannel R = {0,0};
InterpretedDFDChannel G = {0,0};
InterpretedDFDChannel B = {0,0};
InterpretedDFDChannel A = {0,0};
/* interpretDFD channel overloadings for YUVSDA formats. These are
* different from the mapping used by Vulkan. */
#define Y1 R
#define Y2 A
#define CB G
#define U G
#define CR B
#define V B
uint32_t wordBytes;
/* Special case exponent format */
if (KHR_DFDSAMPLECOUNT(dfd + 1) == 6 &&
((KHR_DFDSVAL((dfd + 1), 1, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_EXPONENT) > 0)) {
/* The only format we expect to be encoded like this. */
return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
}
/* Special case depth formats (assumed little-endian) */
if (KHR_DFDSVAL((dfd + 1), 0, CHANNELID) == KHR_DF_CHANNEL_RGBSDA_DEPTH) {
if (KHR_DFDSAMPLECOUNT((dfd + 1)) == 1) {
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 16-1) return VK_FORMAT_D16_UNORM;
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 24-1) return VK_FORMAT_X8_D24_UNORM_PACK32;
return VK_FORMAT_D32_SFLOAT;
} else {
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 16-1) return VK_FORMAT_D16_UNORM_S8_UINT;
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 24-1) return VK_FORMAT_D24_UNORM_S8_UINT;
return VK_FORMAT_D32_SFLOAT_S8_UINT;
}
}
if (KHR_DFDSVAL((dfd + 1), 0, CHANNELID) == KHR_DF_CHANNEL_RGBSDA_STENCIL) {
if (KHR_DFDSAMPLECOUNT((dfd + 1)) == 1) {
return VK_FORMAT_S8_UINT;
} else {
// The KTX 2.0 specification defines D24_UNORM_S8_UINT with S8 in the LSBs
return VK_FORMAT_D24_UNORM_S8_UINT;
}
}
r = interpretDFD(dfd, &R, &G, &B, &A, &wordBytes);
if (r & i_UNSUPPORTED_ERROR_BIT) return VK_FORMAT_UNDEFINED;
if (r & i_PACKED_FORMAT_BIT) {
if (wordBytes == 1) return VK_FORMAT_R4G4_UNORM_PACK8;
else if (wordBytes == 2) { /* PACK16 */
if (A.size == 4) {
if (R.offset == 12) return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
else if (B.offset == 12) return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
else if (A.offset == 12) {
if (R.offset == 8) return VK_FORMAT_A4R4G4B4_UNORM_PACK16;
else return VK_FORMAT_A4B4G4R4_UNORM_PACK16;
}
} else if (G.size == 0 && B.size == 0 && A.size == 0) { /* One channel */
if (R.size == 10)
return VK_FORMAT_R10X6_UNORM_PACK16;
else if (R.size ==12)
return VK_FORMAT_R12X4_UNORM_PACK16;
} else if (A.size == 0) { /* Three channels */
if (B.offset == 0) return VK_FORMAT_R5G6B5_UNORM_PACK16;
else return VK_FORMAT_B5G6R5_UNORM_PACK16;
} else { /* Four channels, one-bit alpha */
if (B.offset == 0) return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
if (B.offset == 1) return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
if (B.offset == 10) return VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR;
return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
}
} else if (wordBytes == 4) { /* PACK32 or 2PACK16 */
if (A.size == 8) {
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_A8B8G8R8_SRGB_PACK32;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A8B8G8R8_SNORM_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A8B8G8R8_UINT_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A8B8G8R8_SINT_PACK32;
} else if (A.size == 2 && B.offset == 0) {
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2R10G10B10_SNORM_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2R10G10B10_UINT_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2R10G10B10_SINT_PACK32;
} else if (A.size == 2 && R.offset == 0) {
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2B10G10R10_UINT_PACK32;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_A2B10G10R10_SINT_PACK32;
} else if (R.size == 11) {
return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
} else if (R.size == 10 && G.size == 10 && B.size == 0) {
return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
} else if (R.size == 12 && G.size == 12 && B.size == 0) {
return VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
}
} else if (wordBytes == 8) { /* 4PACK16 */
if (r & i_YUVSDA_FORMAT_BIT) {
/* In Vulkan G = Y, R = Cr, B = Cb. */
if (Y1.size == 10 && Y1.offset == 6 && Y2.size == 10 && Y2.offset == 38)
return VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16;
if (Y1.size == 10 && Y1.offset == 22 && Y2.size == 10 && Y2.offset == 54)
return VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16;
if (Y1.size == 12 && Y1.offset == 4 && Y2.size == 12 && Y2.offset == 36)
return VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16;
if (Y1.size == 12 && Y1.offset == 20 && Y2.size == 12 && Y2.offset == 52)
return VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16;
} else {
if (R.size == 10)
return VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16;
else if (R.size == 12)
return VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16;
}
}
} else { /* Not a packed format */
if (r & i_YUVSDA_FORMAT_BIT) {
/* In Vulkan G = Y, R = Cr, B = Cb. */
if (Y1.size == 1 && Y1.offset == 0 && Y2.size == 1 && Y2.offset == 2)
return VK_FORMAT_G8B8G8R8_422_UNORM;
else if (Y1.size == 1 && Y1.offset == 1 && Y2.size == 1 && Y2.offset == 3)
return VK_FORMAT_B8G8R8G8_422_UNORM;
else if (Y1.size == 2 && Y1.offset == 0 && Y2.size == 2 && Y2.offset == 4)
return VK_FORMAT_G16B16G16R16_422_UNORM;
else if (Y1.size == 2 && Y1.offset == 2 && Y2.size == 2 && Y2.offset == 6)
return VK_FORMAT_B16G16R16G16_422_UNORM;
else
return VK_FORMAT_UNDEFINED; // Until support added.
} else { /* Not YUV */
if (wordBytes == 1) {
if (A.size == 1 && R.size == 0 && G.size == 0 && B.size == 0 && (r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) {
return VK_FORMAT_A8_UNORM_KHR;
}
if (A.size > 0) { /* 4 channels */
if (R.offset == 0) { /* RGBA */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8A8_SINT;
} else { /* BGRA */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8A8_SINT;
}
} else if (B.size > 0) { /* 3 channels */
if (R.offset == 0) { /* RGB */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8B8_SINT;
} else { /* BGR */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_B8G8R8_SINT;
}
} else if (G.size > 0) { /* 2 channels */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8G8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8G8_SINT;
} else { /* 1 channel */
if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_R8_SRGB;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_SINT;
}
} else if (wordBytes == 2) {
if ((r & i_FIXED_FORMAT_BIT) && R.size == 2 && G.size == 2) return VK_FORMAT_R16G16_SFIXED5_NV;
if (A.size > 0) { /* 4 channels */
if (R.offset == 0) { /* RGBA */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SFLOAT;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SINT;
} else { /* BGRA */
}
} else if (B.size > 0) { /* 3 channels */
if (R.offset == 0) { /* RGB */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SFLOAT;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16B16_SINT;
} else { /* BGR */
}
} else if (G.size > 0) { /* 2 channels */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16_SFLOAT;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16G16_SINT;
} else { /* 1 channel */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16_SFLOAT;
if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_UNORM;
if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_SNORM;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R16_SINT;
}
} else if (wordBytes == 4) {
if (A.size > 0) { /* 4 channels */
if (R.offset == 0) { /* RGBA */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32A32_SINT;
} else { /* BGRA */
}
} else if (B.size > 0) { /* 3 channels */
if (R.offset == 0) { /* RGB */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32B32_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32B32_SINT;
} else { /* BGR */
}
} else if (G.size > 0) { /* 2 channels */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32G32_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32G32_SINT;
} else { /* 1 channel */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R32_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R32_SINT;
}
} else if (wordBytes == 8) {
if (A.size > 0) { /* 4 channels */
if (R.offset == 0) { /* RGBA */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64A64_SINT;
} else { /* BGRA */
}
} else if (B.size > 0) { /* 3 channels */
if (R.offset == 0) { /* RGB */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64B64_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64B64_SINT;
} else { /* BGR */
}
} else if (G.size > 0) { /* 2 channels */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64G64_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64G64_SINT;
} else { /* 1 channel */
if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R64_SFLOAT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64_UINT;
if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R64_SINT;
}
}
}
}
} else if (KHR_DFDVAL((dfd + 1), MODEL) >= 128) {
const uint32_t *bdb = dfd + 1;
switch (KHR_DFDVAL(bdb, MODEL)) {
case KHR_DF_MODEL_BC1A:
if (KHR_DFDSVAL(bdb, 0, CHANNELID) == KHR_DF_CHANNEL_BC1A_COLOR) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
} else {
return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
} else {
return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
}
}
case KHR_DF_MODEL_BC2:
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC2_UNORM_BLOCK;
} else {
return VK_FORMAT_BC2_SRGB_BLOCK;
}
case KHR_DF_MODEL_BC3:
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC3_UNORM_BLOCK;
} else {
return VK_FORMAT_BC3_SRGB_BLOCK;
}
case KHR_DF_MODEL_BC4:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_BC4_UNORM_BLOCK;
} else {
return VK_FORMAT_BC4_SNORM_BLOCK;
}
case KHR_DF_MODEL_BC5:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_BC5_UNORM_BLOCK;
} else {
return VK_FORMAT_BC5_SNORM_BLOCK;
}
case KHR_DF_MODEL_BC6H:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_BC6H_UFLOAT_BLOCK;
} else {
return VK_FORMAT_BC6H_SFLOAT_BLOCK;
}
case KHR_DF_MODEL_BC7:
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC7_UNORM_BLOCK;
} else {
return VK_FORMAT_BC7_SRGB_BLOCK;
}
case KHR_DF_MODEL_ETC2:
if (KHR_DFDSVAL(bdb, 0, CHANNELID) == KHR_DF_CHANNEL_ETC2_COLOR) {
if (KHR_DFDVAL(bdb, DESCRIPTORBLOCKSIZE) == 40) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
} else {
return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
} else {
return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
}
}
} else if (KHR_DFDSVAL(bdb, 0, CHANNELID) == KHR_DF_CHANNEL_ETC2_ALPHA) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
} else {
return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
}
} else if (KHR_DFDVAL(bdb, DESCRIPTORBLOCKSIZE) == 40) {
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_EAC_R11_UNORM_BLOCK;
} else {
return VK_FORMAT_EAC_R11_SNORM_BLOCK;
}
} else {
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
} else {
return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
}
}
case KHR_DF_MODEL_ASTC:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_FLOAT)) {
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 0) {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 11)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
}
}
} else {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT;
}
}
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT;
}
}
}
} else {
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 0) {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
return VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
return VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
return VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
return VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
return VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
return VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
return VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
return VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
return VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 11)) {
return VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT;
}
} else {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
return VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
return VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
return VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
return VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
return VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
return VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 5)) {
return VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT;
}
}
}
break;
case KHR_DF_MODEL_PVRTC:
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG;
}
}
case KHR_DF_MODEL_PVRTC2:
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG;
}
}
default:
;
}
}
return VK_FORMAT_UNDEFINED; /* Drop-through for unmatched formats. */
File diff suppressed because it is too large Load Diff
+316
View File
@@ -0,0 +1,316 @@
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <khr_df.h>
uint32_t *endSwapDFD(const uint32_t *DFD, size_t wordByteSize)
{
/* Provides a DFD for what the buffer described by BDFD would be if it were end-swapped. */
/* The DFD itself is described in uint32_t terms, so you're on your own for that. */
/* This does assume that there's only a single location for each channel, and a single plane. */
/* Build a representation of the bits of each channel in order, recording whence they came. */
/* Then end-swap the locations and write a DFD for the result. */
/* Worst case channel size is the number of bytes in the plane. */
const uint32_t *BDFD = DFD+1;
const uint32_t worstCaseBits = 8 * KHR_DFDVAL(BDFD, BYTESPLANE0);
/* Treat each channel and flag separately. */
uint32_t *virtualSampleBitLocations[256] = {};
uint32_t numBitsPerVirtualSample[256] = {};
uint32_t *lowerValues[256] = {};
uint32_t *upperValues[256] = {};
uint32_t lowerSign[256] = {};
uint32_t upperSign[256] = {};
uint32_t *samplesPerBit[4] = {};
uint32_t sampleCounter;
uint32_t previousChannel = 0x100; /* Impossible value */
uint32_t channelOffset = 0;
uint32_t swapMask = ((1U << wordByteSize) - 1U) << 3;
uint32_t previousSampleStart = 0;
uint32_t *outdfd;
uint32_t *outbdb;
/* Note: We assume that all samples of the same channel
are the same virtual sample; to be fully general-purpose
we should extend this to support distinguishing virtual
samples by qualifier and position. */
for (sampleCounter = 0; sampleCounter < KHR_DFDSAMPLECOUNT(BDFD); ++sampleCounter) {
uint32_t thisSampleChannelId =
KHR_DFDSVAL(BDFD, sampleCounter, CHANNELID) |
KHR_DFDSVAL(BDFD, sampleCounter, QUALIFIERS);
uint32_t bitCounter;
uint32_t sampleBitBase = KHR_DFDSVAL(BDFD, sampleCounter, BITOFFSET);
if (numBitsPerVirtualSample[thiSampleChannelId] == 0) {
/* Need to allocate storage for this virtual sample */
}
switch (thisChannel) {
case KHR_DF_CHANNEL_RGBSDA_RED:
targetChannelArray = channelR;
targetBitCount = &channelRBits;
targetLower = lowerR;
targetLowerSign = &lowerRSign;
targetUpper = upperR;
targetUpperSign = &upperRSign;
/* Assume all qualifiers are the same. */
/* N.B. This will break for, e.g., explicit exponent formats. */
redQualifiers = KHR_DFDSVAL(BDFD, sampleCounter, QUALIFIERS);
break;
case KHR_DF_CHANNEL_RGBSDA_GREEN:
targetChannelArray = channelG;
targetBitCount = &channelGBits;
targetLower = lowerG;
targetLowerSign = &lowerGSign;
targetUpper = upperG;
targetUpperSign = &upperGSign;
/* Assume all qualifiers are the same. */
/* N.B. This will break for, e.g., explicit exponent formats. */
greenQualifiers = KHR_DFDSVAL(BDFD, sampleCounter, QUALIFIERS);
break;
case KHR_DF_CHANNEL_RGBSDA_BLUE:
targetChannelArray = channelB;
targetBitCount = &channelBBits;
targetLower = lowerB;
targetLowerSign = &lowerBSign;
targetUpper = upperB;
targetUpperSign = &upperBSign;
/* Assume all qualifiers are the same. */
/* N.B. This will break for, e.g., explicit exponent formats. */
blueQualifiers = KHR_DFDSVAL(BDFD, sampleCounter, QUALIFIERS);
break;
case KHR_DF_CHANNEL_RGBSDA_ALPHA:
targetChannelArray = channelA;
targetBitCount = &channelABits;
targetLower = lowerA;
targetLowerSign = &lowerASign;
targetUpper = upperA;
targetUpperSign = &upperASign;
/* Assume all qualifiers are the same. */
/* N.B. This will break for, e.g., explicit exponent formats. */
alphaQualifiers = KHR_DFDSVAL(BDFD, sampleCounter, QUALIFIERS);
break;
default: return 0; /* Unknown/unexpected channel */
}
*targetBitCount += KHR_DFDSVAL(BDFD, sampleCounter, BITLENGTH) + 1;
if (thisChannel != previousChannel) channelOffset = 0;
for (bitCounter = 0; bitCounter < *targetBitCount; ++bitCounter, ++channelOffset) {
/* Record the bit offset whence this came */
targetChannelArray[channelOffset] = sampleBitBase + bitCounter;
/* Also need to build up min and max values. */
targetLower[channelOffset >> 5] |= (1U << (channelOffset & 0x1F)) * ((KHR_DFDSVAL(BDFD, sampleCounter, SAMPLELOWER) & (1 << bitCounter)) != 0U);
targetUpper[channelOffset >> 5] |= (1U << (channelOffset & 0x1F)) * ((KHR_DFDSVAL(BDFD, sampleCounter, SAMPLEUPPER) & (1 << bitCounter)) != 0U);
}
/* The last sample of a channel ends with any sign bit. */
/* Note: this does not properly handle exponents. */
if (KHR_DFDSVAL(BDFD, sampleCounter, QUALIFIERS) & KHR_DF_DATATYPE_SIGNED) {
*targetLowerSign = ((KHR_DFDSVAL(BDFD, sampleCounter, SAMPLELOWER) & (1 << *targetBitCount-1)) != 0U);
*targetUpperSign = ((KHR_DFDSVAL(BDFD, sampleCounter, SAMPLEUPPER) & (1 << *targetBitCount-1)) != 0U);
}
}
/* Now we have the target bit corresponding to each channel bit. */
/* Do a big-endian swap on them and fill in bitChannels. */
sampleCounter = 0;
for (previousSampleStart = 0, channelOffset = 0; channelOffset < channelRBits; ++channelOffset) {
channelR[channelOffset] ^= swapMask;
bitChannels[channelR[channelOffset]] |= 1;
/* We're going to need another sample. */
if (((channelOffset - previousSampleStart) & 0x1F) == 0 || channelR[channelOffset] != channelR[channelOffset-1] + 1) {
++sampleCounter;
previousSampleStart = channelOffset;
}
}
for (channelOffset = 0; channelOffset < channelGBits; ++channelOffset) {
channelG[channelOffset] ^= swapMask;
bitChannels[channelG[channelOffset]] |= 2;
/* We're going to need another sample. */
if (((channelOffset - previousSampleStart) & 0x1F) == 0 || channelG[channelOffset] != channelG[channelOffset-1] + 1) {
++sampleCounter;
previousSampleStart = channelOffset;
}
}
for (channelOffset = 0; channelOffset < channelBBits; ++channelOffset) {
channelB[channelOffset] ^= swapMask;
bitChannels[channelB[channelOffset]] |= 4;
/* We're going to need another sample. */
if (((channelOffset - previousSampleStart) & 0x1F) == 0 || channelB[channelOffset] != channelB[channelOffset-1] + 1) {
++sampleCounter;
previousSampleStart = channelOffset;
}
}
for (channelOffset = 0; channelOffset < channelABits; ++channelOffset) {
channelA[channelOffset] ^= swapMask;
bitChannels[channelA[channelOffset]] |= 8;
/* We're going to need another sample. */
if (((channelOffset - previousSampleStart) & 0x1F) == 0 || channelA[channelOffset] != channelA[channelOffset-1] + 1) {
++sampleCounter;
previousSampleStart = channelOffset;
}
}
/* Now we can create the DFD and populate its header. */
outdfd = (uint32_t *)malloc(sizeof(uint32_t) * (1 + KHR_DFDSIZEWORDS(sampleCounter)));
outbdb = outdfd + 1;
*dfd = sizeof(uint32_t) * (1 + KHR_DFDSIZEWORDS(sampleCounter));
/* Note that this is a fairly inefficient way of doing things unless */
/* the compiler is really good at removing redundant bit masking, */
/* but in the interests of readability it probably doesn't matter. */
KHR_DFDSETVAL(outbdb, VENDORID, KHR_DF_VENDORID_KHRONOS);
KHR_DFDSETVAL(outbdb, DESCRIPTORTYPE, KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT);
KHR_DFDSETVAL(outbdb, VERSIONNUMBER, KHR_DF_VERSIONNUMBER_1_3);
KHR_DFDSETVAL(outbdb, DESCRIPTORBLOCKSIZE, (sizeof(uint32_t) * KHR_DFDSIZEWORDS(sampleCounter)));
KHR_DFDSETVAL(outbdb, MODEL, KHR_DF_MODEL_RGBSDA); /* Or this function won't work. */
KHR_DFDSETVAL(outbdb, PRIMARIES, KHR_DFDVAL(BDFD, PRIMARIES));
KHR_DFDSETVAL(outbdb, TRANSFER, KHR_DFDVAL(BDFD, TRANSFER));
KHR_DFDSETVAL(outbdb, FLAGS, KHR_DFDVAL(BDFD, FLAGS));
outbdb[KHR_DF_WORD_TEXELBLOCKDIMENSION0] = KHR_DFDVAL(BDFD, TEXELBLOCKDIMENSION0);
outbdb[KHR_DF_WORD_BYTESPLANE0] = KHR_DFDVAL(BDFD, BYTESPLANE0);
outbdb[KHR_DF_WORD_BYTESPLANE4] = 0;
/* Now iterate through bitChannels, outputting the bits of that channel in order. */
{
uint32_t bitCounter;
sampleCounter = 0;
for (bitCounter = 0; bitCounter < worstCase; ++bitCounter) {
/* Note: This is a simplification assuming no overlapping channels. */
/* Ideally we should determine which channel has the lowes unique bit */
/* and output that first, rather than relying on channel id. */
if ((bitChannels[bitCounter] & 1) && channelRBits) {
/* Output channel R in order */
uint32_t redBit = 0;
uint32_t sampleBit = 0;
while (redBit < channelRBits) {
if (sampleBit == 0) {
KHR_DFDSETSVAL(outbdb, sampleCounter, BITOFFSET, channelR[0]);
/* Come back to BITLENGTH */
KHR_DFDSETSVAL(outbdb, sampleCounter, CHANNELID, KHR_DF_CHANNEL_RGBSDA_RED);
KHR_DFDSETSVAL(outbdb, sampleCounter, QUALIFIERS, redQualifiers);
KHR_DFDSETSVAL(outbdb, sampleCounter, SAMPLEPOSITION_ALL, 0);
KHR_DFDSETSVAL(outbdb, sampleCounter, SAMPLELOWER, 0);
KHR_DFDSETSVAL(outbdb, sampleCounter, SAMPLEUPPER, 0);
inSample = 1;
}
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLELOWER] |=
((lowerR[redBit >> 5] & (1U << (redBit & 0x1F))) != 0) << sampleBit;
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLEUPPER] |=
((upperR[redBit >> 5] & (1U << (redBit & 0x1F))) != 0) << sampleBit;
sampleBit += 1;
/* End of sample? */
/* This over-simplifies large samples: */
/* If a sample is greater than 32 bits and we can describe the lower
and upper values in fewer samples using the rules for extension,
we should do so. */
if (redBit == channelRBits - 1 ||
channelR[redBit] != channelR[redBit+1] - 1 ||
sampleBit == 32) {
KHR_DFDSETSVAL(outbdb, sampleCounter, BITLENGTH, sampleBit - 1);
if (sampleBit < 32 && (redQualifiers & KHR_DF_DATATYPE_SIGNED)) {
/* Sign extend lower and upper */
uint32_t lowerSign = lowerR[channelRBits >> 5] & 1U << (channelRBits & 0x1F);
(KHR_DFDSVAL(outbdb, sampleCounter, SAMPLELOWER) & 0x80000000U) != 0;
uint32_t upperSign =
(KHR_DFDSVAL(outbdb, sampleCounter, SAMPLEUPPER) & 0x80000000U) != 0;
if (lowerSign) lowerSign = ~((1U << sampleBit) - 1);
if (upperSign) upperSign = ~((1U << sampleBit) - 1);
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLELOWER] |=
lowerSign;
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLEUPPER] |=
upperSign;
}
sampleBit = 0;
sampleCounter += 1;
}
redBit += 1;
}
/* Don't do this channel again */
channelRBits = 0;
}
if ((bitChannels[bitCounter] & 2) && channelGBits) {
/* Output channel G in order */
uint32_t greenBit = 0;
uint32_t sampleBit = 0;
while (greenBit < channelGBits) {
if (sampleBit == 0) {
KHR_DFDSETSVAL(outbdb, sampleCounter, BITOFFSET, channelR[0]);
/* Come back to BITLENGTH */
KHR_DFDSETSVAL(outbdb, sampleCounter, CHANNELID, KHR_DF_CHANNEL_RGBSDA_RED);
KHR_DFDSETSVAL(outbdb, sampleCounter, QUALIFIERS, greenQualifiers);
KHR_DFDSETSVAL(outbdb, sampleCounter, SAMPLEPOSITION_ALL, 0);
KHR_DFDSETSVAL(outbdb, sampleCounter, SAMPLELOWER, 0);
KHR_DFDSETSVAL(outbdb, sampleCounter, SAMPLEUPPER, 0);
inSample = 1;
}
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLELOWER] |=
((lowerG[redBit >> 5] & (1U << (redBit & 0x1F))) != 0) << sampleBit;
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLEUPPER] |=
((upperG[redBit >> 5] & (1U << (redBit & 0x1F))) != 0) << sampleBit;
sampleBit += 1;
/* End of sample? */
/* This over-simplifies large samples: */
/* If a sample is greater than 32 bits and we can describe the lower
and upper values in fewer samples using the rules for extension,
we should do so. */
if (greenBit == channelGBits - 1 ||
channelG[greenBit] != channelG[greenBit+1] - 1 ||
sampleBit == 32) {
KHR_DFDSETSVAL(outbdb, sampleCounter, BITLENGTH, sampleBit - 1);
if (sampleBit < 32 && (greenQualifiers & KHR_DF_DATATYPE_SIGNED)) {
/* Sign extend lower and upper */
uint32_t lowerSign =
(KHR_DFDSVAL(outbdb, sampleCounter, SAMPLELOWER) & 0x80000000U) != 0;
uint32_t upperSign =
(KHR_DFDSVAL(outbdb, sampleCounter, SAMPLEUPPER) & 0x80000000U) != 0;
if (lowerSign) lowerSign = ~((1U << sampleBit) - 1);
if (upperSign) upperSign = ~((1U << sampleBit) - 1);
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLELOWER] |=
lowerSign;
outbdb[KHR_DF_WORD_SAMPLESTART +
sampleCounter * KHR_DF_WORD_SAMPLEWORDS +
KHR_DF_SAMPLEWORD_SAMPLEUPPER] |=
upperSign;
}
sampleBit = 0;
sampleCounter += 1;
}
redBit += 1;
}
/* Don't do this channel again */
channelGBits = 0;
}
if ((bitChannels[bitCounter] & 4) && channelBBits) {
/* Output channel B in order */
channelBBits = 0;
}
if ((bitChannels[bitCounter] & 8) && channelABits) {
/* Output channel A in order */
channelABits = 0;
}
}
}
/* Clean up allocations */
free(channelR);
free(channelG);
free(channelB);
free(channelA);
free(lowerR);
free(upperR);
free(lowerG);
free(upperG);
free(lowerB);
free(upperB);
free(lowerA);
free(upperA);
free(bitChannels);
return dfd;
}
+460
View File
@@ -0,0 +1,460 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @~English
* @brief Utility for interpreting a data format descriptor.
* @author Andrew Garrard
*/
#include <stdint.h>
#include <stdio.h>
#include <KHR/khr_df.h>
#include "dfd.h"
static uint32_t bit_ceil(uint32_t x) {
x -= 1;
for (uint32_t i = 0; i < sizeof(x) * 8; ++i)
if (1u << i > x)
return 1u << i;
return 0;
}
/**
* @~English
* @brief Interpret a Data Format Descriptor for a simple format.
*
* Handles "simple" cases that can be translated to things a GPU can access.
* For simplicity, it ignores the compressed formats, which are generally a
* single sample (and I believe are all defined to be little-endian in their
* in-memory layout, even if some documentation confuses this). Focuses on
* the layout and ignores sRGB except for reporting if that is the transfer
* function by way of a bit in the returned value.
*
* @param[in] DFD Pointer to a Data Format Descriptor to interpret,
* described as 32-bit words in native endianness.
* Note that this is the whole descriptor, not just
* the basic descriptor block.
* @param R[in,out] Pointer to struct to receive information about the decoded
* red channel, the Y channel, if YUV, or the depth channel,
* if any.
* @param G[in,out] Pointer to struct to receive information about the decoded
* green channel, the U (Cb) channel, if YUV, or the stencil
* channel, if any.
* @param B[in,out] Pointer to struct to receive information about the decoded
* blue channel, if any or the V (Cr) channel, if YUV.
* @param A[in,out] Pointer to struct to receive information about the decoded
* alpha channel, if any or the second Y channel, if YUV and
* any.
* @param wordBytes[in,out] Pointer to a uint32_t to receive the byte size of
* the channels (unpacked) or total size (packed).
*
* @return An enumerant describing the decoded value,
* or an error code in case of failure.
*
* The mapping of YUV channels to the parameter names used here is based on
* the channel ids in @c khr_df.h and is different from the convention used
* in format names in the Vulkan specification where G == Y, R = Cr and B = Cb.
**/
enum InterpretDFDResult interpretDFD(const uint32_t *DFD,
InterpretedDFDChannel *R,
InterpretedDFDChannel *G,
InterpretedDFDChannel *B,
InterpretedDFDChannel *A,
uint32_t *wordBytes)
{
/* DFD points to the whole descriptor, not the basic descriptor block. */
/* Make everything else relative to the basic descriptor block. */
const uint32_t *BDFDB = DFD+1;
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
if (numSamples == 0)
return i_UNSUPPORTED_CHANNEL_TYPES;
int determinedEndianness = 0;
enum InterpretDFDResult result = 0; /* Build this up incrementally. */
bool isDepthStencil = false;
/* Clear these so following code doesn't get confused. */
R->offset = R->size = 0;
G->offset = G->size = 0;
B->offset = B->size = 0;
A->offset = A->size = 0;
/* First rule out the multiple planes case (trivially) */
/* - that is, we check that only bytesPlane0 is non-zero. */
/* This means we don't handle multi-plane YUV, even if the API could. */
/* (We rely on KHR_DF_WORD_BYTESPLANE0..3 being the same and */
/* KHR_DF_WORD_BYTESPLANE4..7 being the same as a short cut.) */
if ((BDFDB[KHR_DF_WORD_BYTESPLANE0] & ~KHR_DF_MASK_BYTESPLANE0)
|| BDFDB[KHR_DF_WORD_BYTESPLANE4]) return i_UNSUPPORTED_MULTIPLE_PLANES;
/* If this is a packed format, we work out our offsets differently. */
/* We assume a packed format has channels that aren't byte-aligned. */
/* If we have a format in which every channel is byte-aligned *and* packed, */
/* we have the RGBA/ABGR ambiguity; we *probably* don't want the packed */
/* version in this case, and if hardware has to pack it and swizzle, */
/* that's up to the hardware to special-case. */
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
uint32_t offset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET);
uint32_t length = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1;
if ((offset & 0x7U) || ((offset + length) & 0x7U)) {
result |= i_PACKED_FORMAT_BIT;
/* Once we're packed, we're packed, no need to keep checking. */
break;
}
}
// Check data types.
bool hasSigned = false;
bool hasFloat = false;
bool hasNormalized = false;
bool hasFixed = false;
khr_df_model_e model = KHR_DFDVAL(BDFDB, MODEL);
// Note: We're ignoring 9995, which is weird and worth special-casing
// rather than trying to generalise to all float formats.
for (uint32_t i = 0; i < numSamples; ++i) {
const bool isSigned = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED) != 0;
const bool isFloat = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_FLOAT) != 0;
// We define "unnormalized" as "sample_upper = 1" or "sample_upper = 1.0f".
// We don't check whether any non-1 normalization value is correct
// (i.e. set to the maximum bit value, and check min value) on
// the assumption that we're looking at a format which *came* from
// an API we can support.
bool isFixed;
bool isNormalized;
if (isFloat) {
isNormalized = *(float*) (void*) &BDFDB[KHR_DF_WORD_SAMPLESTART +
KHR_DF_WORD_SAMPLEWORDS * i +
KHR_DF_SAMPLEWORD_SAMPLEUPPER] != 1.0f;
isFixed = false;
} else {
uint32_t sampleUpper = KHR_DFDSVAL(BDFDB, i, SAMPLEUPPER);
uint32_t maxVal = 1U << KHR_DFDSVAL(BDFDB, i, BITLENGTH);
if (!isSigned) maxVal <<= 1;
maxVal--;
isFixed = 1U < sampleUpper && sampleUpper < maxVal;
isNormalized = !isFixed && sampleUpper != 1U;
}
hasSigned |= isSigned;
hasFixed |= isFixed;
hasFloat |= isFloat;
// By our definition the normalizedness of a single bit channel (like in RGBA 5:5:5:1)
// is ambiguous. Ignore these during normalized checks.
if (KHR_DFDSVAL(BDFDB, i, BITLENGTH) > 0)
hasNormalized |= isNormalized;
}
result |= hasSigned ? i_SIGNED_FORMAT_BIT : 0;
result |= hasFloat ? i_FLOAT_FORMAT_BIT : 0;
result |= hasNormalized ? i_NORMALIZED_FORMAT_BIT : 0;
result |= hasFixed ? i_FIXED_FORMAT_BIT : 0;
// Checks based on color model
if (model == KHR_DF_MODEL_YUVSDA) {
result |= i_NORMALIZED_FORMAT_BIT;
result |= i_COMPRESSED_FORMAT_BIT;
result |= i_YUVSDA_FORMAT_BIT;
for (uint32_t i = 0; i < numSamples; ++i) {
switch (KHR_DFDSVAL(BDFDB, i, CHANNELID)) {
case KHR_DF_CHANNEL_YUVSDA_Y:
case KHR_DF_CHANNEL_YUVSDA_U:
case KHR_DF_CHANNEL_YUVSDA_V:
case KHR_DF_CHANNEL_YUVSDA_A:
break;
case KHR_DF_CHANNEL_YUVSDA_DEPTH:
case KHR_DF_CHANNEL_YUVSDA_STENCIL:
isDepthStencil = true;
break;
default:
return i_UNSUPPORTED_CHANNEL_TYPES;
}
}
// Determine wordBytes
uint32_t largestSampleSize = 0;
for (uint32_t i = 0; i < numSamples; ++i) {
uint32_t length = KHR_DFDSVAL(BDFDB, i, BITLENGTH) + 1;
if (largestSampleSize < length)
largestSampleSize = length;
}
*wordBytes = ((result & i_PACKED_FORMAT_BIT) ? 4 : 1) * bit_ceil(largestSampleSize) / 8;
} else if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_RGBSDA) {
/* Check if transfer is sRGB. */
if (KHR_DFDVAL(BDFDB, TRANSFER) == KHR_DF_TRANSFER_SRGB) result |= i_SRGB_FORMAT_BIT;
/* We only support samples at coordinate 0,0,0,0. */
/* (We could confirm this from texel_block_dimensions in 1.2, but */
/* the interpretation might change in later versions.) */
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
if (KHR_DFDSVAL(BDFDB, sampleCounter, SAMPLEPOSITION_ALL))
return i_UNSUPPORTED_MULTIPLE_SAMPLE_LOCATIONS;
}
}
if (model == KHR_DF_MODEL_RGBSDA || model == KHR_DF_MODEL_YUVSDA) {
/* The values of the DEPTH and STENCIL tokens are the same for */
/* RGBSDA and YUVSDA. */
/* For Depth/Stencil formats mixed channels are allowed */
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
switch (KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID)) {
case KHR_DF_CHANNEL_RGBSDA_DEPTH:
case KHR_DF_CHANNEL_RGBSDA_STENCIL:
isDepthStencil = true;
break;
default:
break;
}
}
// Check for mixed channels
if (!isDepthStencil) {
for (uint32_t i = 0; i < numSamples; ++i) {
const bool isSigned = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED) != 0;
const bool isFloat = (KHR_DFDSVAL(BDFDB, i, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_FLOAT) != 0;
if (isSigned != hasSigned)
return i_UNSUPPORTED_MIXED_CHANNELS;
if (isFloat != hasFloat)
return i_UNSUPPORTED_MIXED_CHANNELS;
// Note: We don't check for inconsistent normalization, because
// channels composed of multiple samples will have 0 in the
// lower/upper range. Single bit channels are also ambiguous.
// This heuristic should handle 64-bit integers, too.
}
}
/* This all relies on the channel id values for RGB being equal to */
/* those for YUV. */
/* Remember: the canonical ordering of samples is to start with */
/* the lowest bit of the channel/location which touches bit 0 of */
/* the data, when the latter is concatenated in little-endian order, */
/* and then progress until all the bits of that channel/location */
/* have been processed. Multiple channels sharing the same source */
/* bits are processed in channel ID order. (I should clarify this */
/* for partially-shared data, but it doesn't really matter so long */
/* as everything is consecutive, except to make things canonical.) */
/* Note: For standard formats we could determine big/little-endianness */
/* simply from whether the first sample starts in bit 0; technically */
/* it's possible to have a format with unaligned channels wherein the */
/* first channel starts at bit 0 and is one byte, yet other channels */
/* take more bytes or aren't aligned (e.g. D24S8), but this should be */
/* irrelevant for the formats that we support. */
if ((result & i_PACKED_FORMAT_BIT)) {
/* A packed format. */
uint32_t currentChannel = ~0U; /* Don't start matched. */
uint32_t currentBitOffset = 0;
uint32_t currentByteOffset = 0;
uint32_t currentBitLength = 0;
*wordBytes = (BDFDB[KHR_DF_WORD_BYTESPLANE0] & 0xFFU);
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
uint32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET);
uint32_t sampleByteOffset = sampleBitOffset >> 3U;
/* The sample bitLength field stores the bit length - 1. */
uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1;
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
InterpretedDFDChannel *sampleChannelPtr;
switch (sampleChannel) {
case KHR_DF_CHANNEL_RGBSDA_RED:
sampleChannelPtr = R;
break;
case KHR_DF_CHANNEL_RGBSDA_GREEN:
sampleChannelPtr = G;
break;
case KHR_DF_CHANNEL_RGBSDA_BLUE:
sampleChannelPtr = B;
break;
case KHR_DF_CHANNEL_RGBSDA_DEPTH:
sampleChannelPtr = R;
break;
case KHR_DF_CHANNEL_RGBSDA_STENCIL:
sampleChannelPtr = G;
break;
case KHR_DF_CHANNEL_RGBSDA_ALPHA:
sampleChannelPtr = A;
break;
default:
return i_UNSUPPORTED_CHANNEL_TYPES;
}
if (sampleChannel == currentChannel) {
/* Continuation of the same channel. */
/* Since a big (>32-bit) channel isn't "packed", */
/* this should only happen in big-endian, or if */
/* we have a wacky format that we won't support. */
if (sampleByteOffset == currentByteOffset - 1U && /* One byte earlier */
((currentBitOffset + currentBitLength) & 7U) == 0 && /* Already at the end of a byte */
(sampleBitOffset & 7U) == 0) { /* Start at the beginning of the byte */
/* All is good, continue big-endian. */
/* N.B. We shouldn't be here if we decided we were little-endian, */
/* so we don't bother to check that disagreement. */
result |= i_BIG_ENDIAN_FORMAT_BIT;
determinedEndianness = 1;
} else {
/* Oh dear. */
/* We could be little-endian, but not with any standard format. */
/* More likely we've got something weird that we can't support. */
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
}
/* Remember where we are. */
currentBitOffset = sampleBitOffset;
currentByteOffset = sampleByteOffset;
currentBitLength = sampleBitLength;
/* Accumulate the bit length. */
sampleChannelPtr->size += sampleBitLength;
} else {
/* Everything is new. Hopefully. */
currentChannel = sampleChannel;
currentBitOffset = sampleBitOffset;
currentByteOffset = sampleByteOffset;
currentBitLength = sampleBitLength;
if (sampleChannelPtr->size) {
if (model == KHR_DF_MODEL_YUVSDA && sampleChannel == KHR_DF_CHANNEL_YUVSDA_Y) {
if (sampleChannelPtr == R) {
/* We've got another Y channel. Record details in A. */
if (A->size == 0) {
sampleChannelPtr = A;
} else {
/* Uh-oh, we've already got a second Y or an alpha channel. */
return i_UNSUPPORTED_CHANNEL_TYPES;
}
}
} else {
/* Uh-oh, we've seen this channel before. */
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
}
}
/* For now, record the bit offset in little-endian terms, */
/* because we may not know to reverse it yet. */
sampleChannelPtr->offset = sampleBitOffset;
sampleChannelPtr->size = sampleBitLength;
}
}
if ((result & i_BIG_ENDIAN_FORMAT_BIT)) {
/* Our bit offsets to bit 0 of each channel are in little-endian terms. */
/* We need to do a byte swap to work out where they should be. */
/* We assume, for sanity, that byte sizes are a power of two for this. */
uint32_t offsetMask = (*wordBytes - 1U) << 3U;
R->offset ^= offsetMask;
G->offset ^= offsetMask;
B->offset ^= offsetMask;
A->offset ^= offsetMask;
}
} else {
/* Not a packed format. */
/* Everything is byte-aligned. */
/* Question is whether there multiple samples per channel. */
uint32_t currentChannel = ~0U; /* Don't start matched. */
uint32_t currentByteOffset = 0;
uint32_t currentByteLength = 0;
for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) {
uint32_t sampleByteOffset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET) >> 3U;
uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1) >> 3U;
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleCounter, CHANNELID);
InterpretedDFDChannel *sampleChannelPtr;
switch (sampleChannel) {
case KHR_DF_CHANNEL_RGBSDA_RED:
sampleChannelPtr = R;
break;
case KHR_DF_CHANNEL_RGBSDA_GREEN:
sampleChannelPtr = G;
break;
case KHR_DF_CHANNEL_RGBSDA_BLUE:
sampleChannelPtr = B;
break;
case KHR_DF_CHANNEL_RGBSDA_DEPTH:
sampleChannelPtr = R;
break;
case KHR_DF_CHANNEL_RGBSDA_STENCIL:
sampleChannelPtr = G;
break;
case KHR_DF_CHANNEL_RGBSDA_ALPHA:
sampleChannelPtr = A;
break;
default:
return i_UNSUPPORTED_CHANNEL_TYPES;
}
if (sampleChannel == currentChannel) {
/* Continuation of the same channel. */
/* Either big-endian, or little-endian with a very large channel. */
if (sampleByteOffset == currentByteOffset - 1) { /* One byte earlier */
if (determinedEndianness && !(result & i_BIG_ENDIAN_FORMAT_BIT)) {
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
}
/* All is good, continue big-endian. */
result |= i_BIG_ENDIAN_FORMAT_BIT;
determinedEndianness = 1;
/* Update the start */
sampleChannelPtr->offset = sampleByteOffset;
} else if (sampleByteOffset == currentByteOffset + currentByteLength) {
if (determinedEndianness && (result & i_BIG_ENDIAN_FORMAT_BIT)) {
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
}
/* All is good, continue little-endian. */
determinedEndianness = 1;
} else {
/* Oh dear. */
/* We could be little-endian, but not with any standard format. */
/* More likely we've got something weird that we can't support. */
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
}
/* Remember where we are. */
currentByteOffset = sampleByteOffset;
currentByteLength = sampleByteLength;
/* Accumulate the byte length. */
sampleChannelPtr->size += sampleByteLength;
/* Assume these are all the same. */
*wordBytes = sampleChannelPtr->size;
} else {
/* Everything is new. Hopefully. */
currentChannel = sampleChannel;
currentByteOffset = sampleByteOffset;
currentByteLength = sampleByteLength;
if (sampleChannelPtr->size) {
if (model == KHR_DF_MODEL_YUVSDA && sampleChannel == KHR_DF_CHANNEL_YUVSDA_Y) {
if (sampleChannelPtr == R) {
/* We've got another Y channel. Record details in A. */
if (A->size == 0) {
sampleChannelPtr = A;
} else {
/* Uh-oh, we've already got a second Y or an alpha channel. */
return i_UNSUPPORTED_CHANNEL_TYPES;
}
}
} else {
/* Uh-oh, we've seen this channel before. */
return i_UNSUPPORTED_NONTRIVIAL_ENDIANNESS;
}
}
/* For now, record the byte offset in little-endian terms, */
/* because we may not know to reverse it yet. */
sampleChannelPtr->offset = sampleByteOffset;
sampleChannelPtr->size = sampleByteLength;
/* Assume these are all the same. */
*wordBytes = sampleByteLength;
}
}
}
} else {
return i_UNSUPPORTED_CHANNEL_TYPES;
}
if (isDepthStencil) {
/* For Depth/Stencil formats wordBytes is determined by the required alignment of */
/* the larger channel. */
uint32_t largerSize = R->size > G->size ? R->size : G->size;
*wordBytes = bit_ceil(largerSize);
}
return result;
}
+288
View File
@@ -0,0 +1,288 @@
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <KHR/khr_df.h>
#include "dfd.h"
uint32_t dfd1[] = {
4U + 4U * (KHR_DF_WORD_SAMPLESTART + (4U * KHR_DF_WORD_SAMPLEWORDS)),
((KHR_DF_VENDORID_KHRONOS << KHR_DF_SHIFT_VENDORID) |
(KHR_DF_KHR_DESCRIPTORTYPE_BASICFORMAT << KHR_DF_SHIFT_DESCRIPTORTYPE)),
((KHR_DF_VERSIONNUMBER_LATEST << KHR_DF_SHIFT_VERSIONNUMBER) |
((4U * (KHR_DF_WORD_SAMPLESTART + (4U * KHR_DF_WORD_SAMPLEWORDS)))
<< KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE)),
((KHR_DF_MODEL_RGBSDA << KHR_DF_SHIFT_MODEL) |
(KHR_DF_PRIMARIES_BT709 << KHR_DF_SHIFT_PRIMARIES) |
(KHR_DF_TRANSFER_SRGB << KHR_DF_SHIFT_TRANSFER) |
(KHR_DF_FLAG_ALPHA_PREMULTIPLIED << KHR_DF_SHIFT_FLAGS)),
0U, /* Dimensions */
4U, /* bytesPlane0 = 4 */
0U, /* bytesPlane7..4 = 0 */
/* Sample 0 */
((0U << KHR_DF_SAMPLESHIFT_BITOFFSET) |
(7U << KHR_DF_SAMPLESHIFT_BITLENGTH) | /* Store length - 1 */
(KHR_DF_CHANNEL_RGBSDA_RED << KHR_DF_SAMPLESHIFT_CHANNELID)),
0U, /* samplePosition */
0U, /* sampleLower */
255U, /* sampleUpper */
/* Sample 1 */
((8U << KHR_DF_SAMPLESHIFT_BITOFFSET) |
(7U << KHR_DF_SAMPLESHIFT_BITLENGTH) | /* Store length - 1 */
(KHR_DF_CHANNEL_RGBSDA_GREEN << KHR_DF_SAMPLESHIFT_CHANNELID)),
0U, /* samplePosition */
0U, /* sampleLower */
255U, /* sampleUpper */
/* Sample 2 */
((16U << KHR_DF_SAMPLESHIFT_BITOFFSET) |
(7U << KHR_DF_SAMPLESHIFT_BITLENGTH) | /* Store length - 1 */
(KHR_DF_CHANNEL_RGBSDA_BLUE << KHR_DF_SAMPLESHIFT_CHANNELID)),
0U, /* samplePosition */
0U, /* sampleLower */
255U, /* sampleUpper */
/* Sample 3 */
((24U << KHR_DF_SAMPLESHIFT_BITOFFSET) |
(7U << KHR_DF_SAMPLESHIFT_BITLENGTH) | /* Store length - 1 */
((KHR_DF_CHANNEL_RGBSDA_ALPHA | KHR_DF_SAMPLE_DATATYPE_LINEAR) << KHR_DF_SAMPLESHIFT_CHANNELID))
};
uint32_t dfd2[] = { /* Little-endian unpacked */
92U,
0U,
2U | (88U << 16U),
KHR_DF_MODEL_RGBSDA | (KHR_DF_PRIMARIES_BT709 << 8) | (KHR_DF_TRANSFER_SRGB << 16) | (KHR_DF_FLAG_ALPHA_PREMULTIPLIED << 24),
0U,
8U,
0U,
/* Sample 0 */
0U | (15U << 16) | (KHR_DF_CHANNEL_RGBSDA_RED << 24),
0U,
0U,
0xFFFFU,
/* Sample 1 */
16U | (15U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
0xFFFFU,
/* Sample 2 */
32U | (15U << 16) | (KHR_DF_CHANNEL_RGBSDA_BLUE << 24),
0U,
0U,
0xFFFFU,
/* Sample 3 */
48U | (15U << 16) | ((KHR_DF_CHANNEL_RGBSDA_ALPHA | KHR_DF_SAMPLE_DATATYPE_LINEAR) << 24),
0U,
0U,
0xFFFFU
};
uint32_t dfd3[] = { /* Big-endian unpacked */
92U,
0U,
2U | (88U << 16U),
KHR_DF_MODEL_RGBSDA | (KHR_DF_PRIMARIES_BT709 << 8) | (KHR_DF_TRANSFER_SRGB << 16) | (KHR_DF_FLAG_ALPHA_PREMULTIPLIED << 24),
0U,
8U,
0U,
/* Sample 0 */
8U | (7U << 16) | (KHR_DF_CHANNEL_RGBSDA_RED << 24),
0U,
0U,
255U,
/* Sample 1 */
0U | (7U << 16) | (KHR_DF_CHANNEL_RGBSDA_RED << 24),
0U,
0U,
255U,
/* Sample 2 */
24U | (7U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
255U,
/* Sample 3 */
16U | (7U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
255U
};
uint32_t dfd4[] = { /* Little-endian packed */
92U,
0U,
2U | (88U << 16U),
KHR_DF_MODEL_RGBSDA | (KHR_DF_PRIMARIES_BT709 << 8) | (KHR_DF_TRANSFER_LINEAR << 16) | (KHR_DF_FLAG_ALPHA_PREMULTIPLIED << 24),
0U,
2U,
0U,
/* Sample 0 */
0U | (3U << 16) | (KHR_DF_CHANNEL_RGBSDA_RED << 24),
0U,
0U,
7U,
/* Sample 1 */
4U | (3U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
7U,
/* Sample 2 */
8U | (3U << 16) | (KHR_DF_CHANNEL_RGBSDA_BLUE << 24),
0U,
0U,
7U,
/* Sample 3 */
12U | (3U << 16) | (KHR_DF_CHANNEL_RGBSDA_ALPHA << 24),
0U,
0U,
7U
};
uint32_t dfd5[] = { /* Big-endian packed */
92U,
0U,
1U | (88U << 16U),
KHR_DF_MODEL_RGBSDA | (KHR_DF_PRIMARIES_BT709 << 8) | (KHR_DF_TRANSFER_SRGB << 16) | (KHR_DF_FLAG_ALPHA_PREMULTIPLIED << 24),
0U,
2U,
0U,
/* Sample 0 (low bits of channel that touches bit 0) */
13U | (2U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
7U,
/* Sample 1 (high bits of channel that touches bit 0) */
0U | (2U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
7U,
/* Sample 2 */
3U | (4U << 16) | (KHR_DF_CHANNEL_RGBSDA_RED << 24),
0U,
0U,
31U,
/* Sample 3 */
8U | (4U << 16) | (KHR_DF_CHANNEL_RGBSDA_BLUE << 24),
0U,
0U,
31U
};
uint32_t dfd6[] = { /* Little-endian unpacked extended (N.B. could be done in two samples) */
92U,
0U,
2U | (88U << 16U),
KHR_DF_MODEL_RGBSDA | (KHR_DF_PRIMARIES_BT709 << 8) | (KHR_DF_TRANSFER_SRGB << 16) | (KHR_DF_FLAG_ALPHA_PREMULTIPLIED << 24),
0U,
16U,
0U,
/* Sample 0 */
0U | (31U << 16) | (KHR_DF_CHANNEL_RGBSDA_RED << 24),
0U,
0U,
0xFFFFFFFFU,
/* Sample 1 */
32U | (31U << 16) | (KHR_DF_CHANNEL_RGBSDA_RED << 24),
0U,
0U,
0xFFFFFFFFU,
/* Sample 2 */
64U | (31U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
0xFFFFFFFFU,
/* Sample 3 */
96U | (31U << 16) | (KHR_DF_CHANNEL_RGBSDA_GREEN << 24),
0U,
0U,
0xFFFFFFFFU
};
int main(int argc, char** argv)
{
const char *errorText[] = {
"UNSUPPORTED_NONTRIVIAL_ENDIANNESS",
"UNSUPPORTED_MULTIPLE_SAMPLE_LOCATIONS",
"UNSUPPORTED_MULTIPLE_PLANES",
"UNSUPPORTED_CHANNEL_TYPES",
"UNSUPPORTED_MIXED_CHANNELS"};
InterpretedDFDChannel R = {0,0}, G = {0,0}, B = {0,0}, A = {0,0};
uint32_t wordSize;
enum InterpretDFDResult t;
#if 0
t = interpretDFD(dfd1, &R, &G, &B, &A, &wordSize);
#else
#if 0
uint32_t *d = createDFDUnpacked(1,2,4,0,s_UNORM);
#elif 0
int channels[] = {0,1,2,3};
int bits[] = {10,10,10,2};
uint32_t *d = createDFDPacked(1,4,bits,channels,s_UNORM);
#elif 0
int channels[] = {0,1,2};
int bits[] = {5,6,5};
uint32_t *d = createDFDPacked(1,3,bits,channels,s_UNORM);
#elif 1
uint32_t *d = createDFDUnpacked(0, 3, 1, 0, s_UNORM);
#endif
printDFD(d, *d);
t = interpretDFD(d, &R, &G, &B, &A, &wordSize);
#endif
if (t & i_UNSUPPORTED_ERROR_BIT) {
printf("%s\n", errorText[t - i_UNSUPPORTED_ERROR_BIT]);
return 0;
} else {
if (t & i_BIG_ENDIAN_FORMAT_BIT) {
printf("Big-endian\n");
} else {
printf("Little-endian\n");
}
if (t & i_PACKED_FORMAT_BIT) {
printf("Packed\n");
if (R.size > 0) {
printf("%u red bit%s starting at %u\n", R.size, R.size>1?"s":"", R.offset);
}
if (G.size > 0) {
printf("%u green bit%s starting at %u\n", G.size, G.size>1?"s":"", G.offset);
}
if (B.size > 0) {
printf("%u blue bit%s starting at %u\n", B.size, B.size>1?"s":"", B.offset);
}
if (A.size > 0) {
printf("%u alpha bit%s starting at %u\n", A.size, A.size>1?"s":"", A.offset);
}
printf("Total word size %u\n", wordSize);
} else {
printf("Not packed\n");
if (R.size > 0) {
printf("%u red byte%s starting at %u\n", R.size, R.size>1?"s":"", R.offset);
}
if (G.size > 0) {
printf("%u green byte%s starting at %u\n", G.size, G.size>1?"s":"", G.offset);
}
if (B.size > 0) {
printf("%u blue byte%s starting at %u\n", B.size, B.size>1?"s":"", B.offset);
}
if (A.size > 0) {
printf("%u alpha byte%s starting at %u\n", A.size, A.size>1?"s":"", A.offset);
}
}
if (t & i_SRGB_FORMAT_BIT) {
printf("sRGB\n");
}
if (t & i_NORMALIZED_FORMAT_BIT) {
printf("Normalized\n");
}
if (t & i_SIGNED_FORMAT_BIT) {
printf("Signed\n");
}
if (t & i_FLOAT_FORMAT_BIT) {
printf("Float\n");
}
}
return 0;
}
+834
View File
@@ -0,0 +1,834 @@
#!/usr/bin/perl
# -*- tab-width: 4; -*-
# vi: set sw=2 ts=4 expandtab:
# Copyright 2019-2020 The Khronos Group Inc.
# SPDX-License-Identifier: Apache-2.0
# N.B. 0 arguments, read stdin, write stdout.
# 1 argument, read ARGV[0], write stdout.
# 2 arguments, read ARGV[0], write ARGV[1].
my $infile = shift @ARGV;
my $outfile = shift @ARGV;
my $input;
if (defined $infile) {
open($input, '<', $infile);
} else {
$input = *STDIN;
}
if (defined $outfile) {
open (my $output, '>', $outfile);
select $output;
}
# Endianness is a parameter to the (non-block-compressed) generators
# This doesn't have to be a number: $bigEndian = "myBigEndianFlag" will drop this argument in the generated code
$bigEndian = 0;
# Keep track of formats we've seen to avoid duplicates
%foundFormats = ();
print "/* Copyright 2019-2020 The Khronos Group Inc. */\n";
print "/* SPDX-", "License-Identifier: Apache-2.0 */\n\n";
print "/***************************** Do not edit. *****************************\n";
print " Automatically generated by makedfd2vk.pl.\n";
print " *************************************************************************/\n";
# Loop over each line of input
# IMPORTANT: Do not use `<>` as that reads all files given on the
# command line.
while ($line = <$input>) {
# Match any format that starts with a channel description (some number
# of R, G, B, A or a number). # In PERL, "=~" performs a regex
# operation on the left argument m/<regex>/ matches the regular expression
if ($line =~ m/VK_FORMAT_[RGBA0-9]+_/) {
# Set $format to the enum identifier
($line =~ m/(VK_FORMAT[A-Z0-9_]+)/);
# $<number> holds the <number>'th parenthesised entry in the previous regex
# (only one in this case)
$format = $1;
# Skip a format if we've already processed it
if (!exists($foundFormats{$format})) {
if ($format =~ m/_PACK/) {
# Packed formats end "_PACK<n>" - is this format packed?
# Extract the channel identifiers and suffix from the packed format
$format =~ m/VK_FORMAT_([RGBA0-9]+)_([^_]+)_PACK[0-9]+/;
# The first parenthesised bit of regex is the channels ("R5G5B5" etc.)
$channels = $1;
# The second parenthesised bit of regex is the suffix ("UNORM" etc.)
$suffix = $2;
# N.B. We don't care about the total bit count (after "PACK" in the name)
# Create an empty array of channel names and corresponding bits
@packChannels = ();
@packBits = ();
# Loop over channels, separating out the last letter followed by a number
while ($channels =~ m/([RGBA0-9]*)([RGBA])([0-9]+)/) {
# Add the rightmost channel name to our array
push @packChannels, $2;
# Add the rightmost channel bits to the array
push @packBits, $3;
# Truncate the channels string to remove the channel we've processed
$channels = $1;
}
# The number of channels we've found is the array length we've built
$numChannels = @packChannels;
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# If we're not packed, do we have a simple RGBA channel size list with a suffix?
# N.B. We don't want to pick up downsampled or planar formats, which have more _-separated fields
# - "$" matches the end of the format identifier
} elsif ($format =~ m/VK_FORMAT_([RGBA0-9]+)_([^_]+)$/) {
# Extract our "channels" (e.g. "B8G8R8") and "suffix" (e.g. "UNORM")
$channels = $1;
$suffix = $2;
# Non-packed format either start with red (R8G8B8A8) or blue (B8G8R8A8)
# We have a special case to notice when we start with blue
if (substr($channels,0,1) eq "B") {
# Red and blue are swapped (B, G, R, A) - record this
# N.B. createDFDUnpacked() just knows this and R,G,B,A channel order, not arbitrary
$rbswap = 1;
# We know we saw "B" for blue, so we must also have red and green
$numChannels = 3;
# If we have "A" in the channels as well, we have four channels
if ($channels =~ m/A/) {
$numChannels = 4;
}
} else {
# We didn't start "B", so we're in conventional order (R, G, B, A)
$rbswap = 0;
# Check for the channel names present and map that to the number of channels
if ($channels =~ m/A/) {
$numChannels = 4;
} elsif ($channels =~ m/B/) {
$numChannels = 3;
} elsif ($channels =~ m/G/) {
$numChannels = 2;
} else {
$numChannels = 1;
}
}
# In an unpacked format, all the channels are the same size, so we only need to check one
$channels =~ m/R([0-9]+)/;
# For unpacked, we need bytes per channel, not bits
$bytesPerChannel = $1 / 8;
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
}
}
# If we weren't VK_FORMAT_ plus a channel, we might be a compressed
# format, that ends "_BLOCK"
# N.B. We don't currently process compressed formats here.
# They're essentially all special cases anyway.
# The code for compressed formats from the code the above is
# derived from is retained here for future work.
} elsif (0 && $line =~ m/(VK_FORMAT_[A-Z0-9x_]+_BLOCK(_EXT)?)/) {
# Extract the format identifier from the rest of the line
$format = $1;
# Skip a format if we've already processed it
if (!exists($foundFormats{$format})) {
# Special-case BC1_RGB to separate it from BC1_RGBA
if ($line =~ m/VK_FORMAT_BC1_RGB_([A-Z]+)_BLOCK/) {
# Pull out the suffix ("UNORM" etc.)
$suffix = $1;
# Output the special case - a 4x4 BC1 block
print "case $format: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# Special case BC1_RGBA (but still extract the suffix with a regex)
} elsif ($line =~ m/VK_FORMAT_BC1_RGBA_([A-Z]+)_BLOCK/) {
$suffix = $1;
print "case $format: return createDFDCompressed(c_BC1_RGBA, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# All the other BC formats don't have a channel identifier in the name, so we regex match them
} elsif ($line =~ m/VK_FORMAT_(BC(?:[2-57]|6H))_([A-Z]+)_BLOCK/) {
$scheme = $1;
$suffix = $2;
print "case $format: return createDFDCompressed(c_$scheme, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# The ETC and EAC formats have two-part names (ETC2_R8G8B8, EAC_R11 etc.) starting with "E"
} elsif ($line =~ m/VK_FORMAT_(E[^_]+_[^_]+)_([A-Z]+)_BLOCK/) {
$scheme = $1;
$suffix = $2;
print "case $format: return createDFDCompressed(c_$scheme, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# Finally, ASTC, the only case where the block size is a parameter
} elsif ($line =~ m/VK_FORMAT_ASTC_([0-9]+)x([0-9]+)(x([0-9]+))?_([A-Z]+)_BLOCK(_EXT)?/) {
$w = $1;
$h = $2;
$d = $4 ? $4 : '1';
$suffix = $5;
print "case $format: return createDFDCompressed(c_ASTC, $w, $h, $d, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
}
# Currently PVRTC drops through unmatched, pending support
}
}
# ...and continue to the next line
}
# Now generate the output for any formats we've seen.
sub checkSuffices {
my $formatPrefix = shift(@_);
my $packSuffix = shift(@_);
my $indentDepth = shift(@_);
$indent = ' ' x $indentDepth;
# Only output tests for formats that exist.
# Simplify things by picking off sRGB and float (always signed for unpacked) first.
if (exists($foundFormats{"VK_FORMAT_" . $formatPrefix . "_SRGB" . $packSuffix})) {
print $indent . "if ((r & i_SRGB_FORMAT_BIT)) return VK_FORMAT_" . $formatPrefix . "_SRGB" . $packSuffix . ";\n";
}
if (exists($foundFormats{"VK_FORMAT_" . $formatPrefix . "_SFLOAT" . $packSuffix})) {
print $indent . "if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_" . $formatPrefix . "_SFLOAT" . $packSuffix . ";\n";
}
if (exists($foundFormats{"VK_FORMAT_" . $formatPrefix . "_UNORM" . $packSuffix})) {
print $indent . "if ((r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_" . $formatPrefix . "_UNORM" . $packSuffix . ";\n";
}
if (exists($foundFormats{"VK_FORMAT_" . $formatPrefix . "_SNORM" . $packSuffix})) {
print $indent . "if ((r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_" . $formatPrefix . "_SNORM" . $packSuffix . ";\n";
}
if (exists($foundFormats{"VK_FORMAT_" . $formatPrefix . "_UINT" . $packSuffix})) {
print $indent . "if (!(r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_" . $formatPrefix . "_UINT" . $packSuffix . ";\n";
}
if (exists($foundFormats{"VK_FORMAT_" . $formatPrefix . "_SINT" . $packSuffix})) {
print $indent . "if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_" . $formatPrefix . "_SINT" . $packSuffix . ";\n";
}
# N.B. Drop through if the VKFORMAT doesn't exist.
}
$prefix = <<'END_PREFIX';
if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA || KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_YUVSDA) {
enum InterpretDFDResult r;
InterpretedDFDChannel R = {0,0};
InterpretedDFDChannel G = {0,0};
InterpretedDFDChannel B = {0,0};
InterpretedDFDChannel A = {0,0};
/* interpretDFD channel overloadings for YUVSDA formats. These are
* different from the mapping used by Vulkan. */
#define Y1 R
#define Y2 A
#define CB G
#define U G
#define CR B
#define V B
uint32_t wordBytes;
/* Special case exponent format */
if (KHR_DFDSAMPLECOUNT(dfd + 1) == 6 &&
((KHR_DFDSVAL((dfd + 1), 1, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_EXPONENT) > 0)) {
/* The only format we expect to be encoded like this. */
return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
}
/* Special case depth formats (assumed little-endian) */
if (KHR_DFDSVAL((dfd + 1), 0, CHANNELID) == KHR_DF_CHANNEL_RGBSDA_DEPTH) {
if (KHR_DFDSAMPLECOUNT((dfd + 1)) == 1) {
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 16-1) return VK_FORMAT_D16_UNORM;
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 24-1) return VK_FORMAT_X8_D24_UNORM_PACK32;
return VK_FORMAT_D32_SFLOAT;
} else {
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 16-1) return VK_FORMAT_D16_UNORM_S8_UINT;
if (KHR_DFDSVAL((dfd + 1), 0, BITLENGTH) == 24-1) return VK_FORMAT_D24_UNORM_S8_UINT;
return VK_FORMAT_D32_SFLOAT_S8_UINT;
}
}
if (KHR_DFDSVAL((dfd + 1), 0, CHANNELID) == KHR_DF_CHANNEL_RGBSDA_STENCIL) {
if (KHR_DFDSAMPLECOUNT((dfd + 1)) == 1) {
return VK_FORMAT_S8_UINT;
} else {
// The KTX 2.0 specification defines D24_UNORM_S8_UINT with S8 in the LSBs
return VK_FORMAT_D24_UNORM_S8_UINT;
}
}
r = interpretDFD(dfd, &R, &G, &B, &A, &wordBytes);
if (r & i_UNSUPPORTED_ERROR_BIT) return VK_FORMAT_UNDEFINED;
if (r & i_PACKED_FORMAT_BIT) {
END_PREFIX
print $prefix;
# Packed format decode.
# There aren't many of these, so we hard-wire them (and identify them minimally).
$packedDecode = << 'END_PACKED';
if (wordBytes == 1) return VK_FORMAT_R4G4_UNORM_PACK8;
else if (wordBytes == 2) { /* PACK16 */
if (A.size == 4) {
if (R.offset == 12) return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
else if (B.offset == 12) return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
else if (A.offset == 12) {
if (R.offset == 8) return VK_FORMAT_A4R4G4B4_UNORM_PACK16;
else return VK_FORMAT_A4B4G4R4_UNORM_PACK16;
}
} else if (G.size == 0 && B.size == 0 && A.size == 0) { /* One channel */
if (R.size == 10)
return VK_FORMAT_R10X6_UNORM_PACK16;
else if (R.size ==12)
return VK_FORMAT_R12X4_UNORM_PACK16;
} else if (A.size == 0) { /* Three channels */
if (B.offset == 0) return VK_FORMAT_R5G6B5_UNORM_PACK16;
else return VK_FORMAT_B5G6R5_UNORM_PACK16;
} else { /* Four channels, one-bit alpha */
if (B.offset == 0) return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
if (B.offset == 1) return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
if (B.offset == 10) return VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR;
return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
}
} else if (wordBytes == 4) { /* PACK32 or 2PACK16 */
END_PACKED
print $packedDecode;
print " if (A.size == 8) {\n";
checkSuffices("A8B8G8R8", "_PACK32", 8);
print " } else if (A.size == 2 && B.offset == 0) {\n";
checkSuffices("A2R10G10B10", "_PACK32", 8);
print " } else if (A.size == 2 && R.offset == 0) {\n";
checkSuffices("A2B10G10R10", "_PACK32", 8);
print " } else if (R.size == 11) {\n";
print " return VK_FORMAT_B10G11R11_UFLOAT_PACK32;\n";
print " } else if (R.size == 10 && G.size == 10 && B.size == 0) { \n";
print " return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;\n";
print " } else if (R.size == 12 && G.size == 12 && B.size == 0) { \n";
print " return VK_FORMAT_R12X4G12X4_UNORM_2PACK16;\n";
print " }\n";
$fourPack16Decode = << 'END_4PACK16';
} else if (wordBytes == 8) { /* 4PACK16 */
if (r & i_YUVSDA_FORMAT_BIT) {
/* In Vulkan G = Y, R = Cr, B = Cb. */
if (Y1.size == 10 && Y1.offset == 6 && Y2.size == 10 && Y2.offset == 38)
return VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16;
if (Y1.size == 10 && Y1.offset == 22 && Y2.size == 10 && Y2.offset == 54)
return VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16;
if (Y1.size == 12 && Y1.offset == 4 && Y2.size == 12 && Y2.offset == 36)
return VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16;
if (Y1.size == 12 && Y1.offset == 20 && Y2.size == 12 && Y2.offset == 52)
return VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16;
} else {
if (R.size == 10)
return VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16;
else if (R.size == 12)
return VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16;
}
}
} else { /* Not a packed format */
END_4PACK16
print $fourPack16Decode;
$yuvDecode = << 'END_YUV';
if (r & i_YUVSDA_FORMAT_BIT) {
/* In Vulkan G = Y, R = Cr, B = Cb. */
if (Y1.size == 1 && Y1.offset == 0 && Y2.size == 1 && Y2.offset == 2)
return VK_FORMAT_G8B8G8R8_422_UNORM;
else if (Y1.size == 1 && Y1.offset == 1 && Y2.size == 1 && Y2.offset == 3)
return VK_FORMAT_B8G8R8G8_422_UNORM;
else if (Y1.size == 2 && Y1.offset == 0 && Y2.size == 2 && Y2.offset == 4)
return VK_FORMAT_G16B16G16R16_422_UNORM;
else if (Y1.size == 2 && Y1.offset == 2 && Y2.size == 2 && Y2.offset == 6)
return VK_FORMAT_B16G16R16G16_422_UNORM;
else
return VK_FORMAT_UNDEFINED; // Until support added.
} else { /* Not YUV */
END_YUV
print $yuvDecode;
# Start by checking sizes
for ($byteSize = 1; $byteSize <= 8; $byteSize <<= 1) {
if ($byteSize == 1) {
print " if (wordBytes == $byteSize) {\n";
# Handle the single alpha-only format (unfortunately, the rest of the script could not handle this)
print " if (A.size == 1 && R.size == 0 && G.size == 0 && B.size == 0 && (r & i_NORMALIZED_FORMAT_BIT) && !(r & i_SIGNED_FORMAT_BIT)) {\n";
print " return VK_FORMAT_A8_UNORM_KHR;\n";
print " }\n";
} elsif ($byteSize == 2) {
print " } else if (wordBytes == $byteSize) {\n";
# Handle VK_FORMAT_R16G16_SFIXED5_NV. checkSuffices does not
# handle this unique suffix.
print " if ((r & i_FIXED_FORMAT_BIT) && R.size == 2 && G.size == 2) return VK_FORMAT_R16G16_SFIXED5_NV;\n";
} else {
print " } else if (wordBytes == $byteSize) {\n";
}
# If we have an alpha channel...
print " if (A.size > 0) { /* 4 channels */\n";
print " if (R.offset == 0) { /* RGBA */\n";
checkSuffices("R" . 8 * $byteSize . "G" . 8 * $byteSize . "B" . 8 * $byteSize . "A" . 8 * $byteSize, "", 12);
print " } else { /* BGRA */\n";
checkSuffices("B" . 8 * $byteSize . "G" . 8 * $byteSize . "R" . 8 * $byteSize . "A" . 8 * $byteSize, "", 12);
print " }\n";
print " } else if (B.size > 0) { /* 3 channels */\n";
print " if (R.offset == 0) { /* RGB */\n";
checkSuffices("R" . 8 * $byteSize . "G" . 8 * $byteSize . "B" . 8 * $byteSize, "", 12);
print " } else { /* BGR */\n";
checkSuffices("B" . 8 * $byteSize . "G" . 8 * $byteSize . "R" . 8 * $byteSize, "", 12);
print " }\n";
print " } else if (G.size > 0) { /* 2 channels */\n";
checkSuffices("R" . 8 * $byteSize . "G" . 8 * $byteSize, "", 10);
print " } else { /* 1 channel */\n"; # Red only
checkSuffices("R" . 8 * $byteSize, "", 10);
print " }\n";
}
print " }\n";
print " }\n";
print " }\n";
$compressedDecode = << 'END_COMPRESSED';
} else if (KHR_DFDVAL((dfd + 1), MODEL) >= 128) {
const uint32_t *bdb = dfd + 1;
switch (KHR_DFDVAL(bdb, MODEL)) {
case KHR_DF_MODEL_BC1A:
if (KHR_DFDSVAL(bdb, 0, CHANNELID) == KHR_DF_CHANNEL_BC1A_COLOR) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
} else {
return VK_FORMAT_BC1_RGB_SRGB_BLOCK;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
} else {
return VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
}
}
case KHR_DF_MODEL_BC2:
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC2_UNORM_BLOCK;
} else {
return VK_FORMAT_BC2_SRGB_BLOCK;
}
case KHR_DF_MODEL_BC3:
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC3_UNORM_BLOCK;
} else {
return VK_FORMAT_BC3_SRGB_BLOCK;
}
case KHR_DF_MODEL_BC4:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_BC4_UNORM_BLOCK;
} else {
return VK_FORMAT_BC4_SNORM_BLOCK;
}
case KHR_DF_MODEL_BC5:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_BC5_UNORM_BLOCK;
} else {
return VK_FORMAT_BC5_SNORM_BLOCK;
}
case KHR_DF_MODEL_BC6H:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_BC6H_UFLOAT_BLOCK;
} else {
return VK_FORMAT_BC6H_SFLOAT_BLOCK;
}
case KHR_DF_MODEL_BC7:
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_BC7_UNORM_BLOCK;
} else {
return VK_FORMAT_BC7_SRGB_BLOCK;
}
case KHR_DF_MODEL_ETC2:
if (KHR_DFDSVAL(bdb, 0, CHANNELID) == KHR_DF_CHANNEL_ETC2_COLOR) {
if (KHR_DFDVAL(bdb, DESCRIPTORBLOCKSIZE) == 40) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
} else {
return VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
} else {
return VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
}
}
} else if (KHR_DFDSVAL(bdb, 0, CHANNELID) == KHR_DF_CHANNEL_ETC2_ALPHA) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
} else {
return VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
}
} else if (KHR_DFDVAL(bdb, DESCRIPTORBLOCKSIZE) == 40) {
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_EAC_R11_UNORM_BLOCK;
} else {
return VK_FORMAT_EAC_R11_SNORM_BLOCK;
}
} else {
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED)) {
return VK_FORMAT_EAC_R11G11_UNORM_BLOCK;
} else {
return VK_FORMAT_EAC_R11G11_SNORM_BLOCK;
}
}
case KHR_DF_MODEL_ASTC:
if (!(KHR_DFDSVAL(bdb, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_FLOAT)) {
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 0) {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_4x4_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_5x4_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_5x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_6x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_6x6_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_8x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_8x6_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_8x8_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x5_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x6_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x8_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_10x10_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_12x10_SRGB_BLOCK;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 11)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
} else {
return VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
}
}
} else {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT;
}
}
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT;
}
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 5)) {
if (KHR_DFDVAL(bdb, TRANSFER) != KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT;
} else {
return VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT;
}
}
}
} else {
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 0) {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
return VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3)) {
return VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
return VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
return VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 7) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
return VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4)) {
return VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5)) {
return VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 7)) {
return VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 9) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
return VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 9)) {
return VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 11) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 11)) {
return VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT;
}
} else {
if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 2) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 2)) {
return VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
return VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 3) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
return VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 3)) {
return VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
return VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 4) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
return VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 4)) {
return VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT;
} else if ((KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION1) == 5) &&
(KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION2) == 5)) {
return VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT;
}
}
}
break;
case KHR_DF_MODEL_PVRTC:
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG;
}
}
case KHR_DF_MODEL_PVRTC2:
if (KHR_DFDVAL(bdb, TEXELBLOCKDIMENSION0) == 3) {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG;
}
} else {
if (KHR_DFDVAL(bdb, TRANSFER) == KHR_DF_TRANSFER_SRGB) {
return VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG;
} else {
return VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG;
}
}
default:
;
}
}
END_COMPRESSED
print $compressedDecode;
# Failed to match.
print "return VK_FORMAT_UNDEFINED; /* Drop-through for unmatched formats. */\n";
+533
View File
@@ -0,0 +1,533 @@
#!/usr/bin/perl
# -*- tab-width: 4; -*-
# vi: set sw=2 ts=4 expandtab:
# Copyright 2019-2020 The Khronos Group Inc.
# SPDX-License-Identifier: Apache-2.0
use strict;
use warnings;
# N.B. 0 arguments, read stdin, write stdout.
# 1 argument, read ARGV[0], write stdout.
# 2 arguments, read ARGV[0], write ARGV[1].
my $infile = shift @ARGV;
my $outfile = shift @ARGV;
my $input;
if (defined $infile) {
open($input, '<', $infile);
} else {
$input = *STDIN;
}
if (defined $outfile) {
open (my $output, '>', $outfile);
select $output;
}
# Endianness is a parameter to the (non-block-compressed) generators
# This doesn't have to be a number: $bigEndian = "myBigEndianFlag" will drop this argument in the generated code
my $bigEndian = 0;
# Keep track of formats we've seen to avoid duplicates
my %foundFormats = ();
# Check if we've processed a format. Returns true for extension formats
# that have been promoted to core when the core format has been processed.
# Usually only _KHR and _EXT extensions are promoted so only those are
# checked.
sub formatProcessed {
my $format =$_[0];
my $format_noext = $format;
$format_noext =~ s/_(EXT|KHR)$//;
return (exists($foundFormats{$format})
|| exists($foundFormats{$format_noext}));
}
print "/* Copyright 2019-2020 The Khronos Group Inc. */\n";
print "/* SPDX-", "License-Identifier: Apache-2.0 */\n\n";
print "/***************************** Do not edit. *****************************\n";
print " Automatically generated by makevk2dfd.pl.\n";
print " *************************************************************************/\n\n";
# Loop over each line of input
# IMPORTANT: Do not use `<>` as that reads all files given on the
# command line.
while (my $line = <$input>) {
# Match any format that starts with a channel description (some number of R, G, B, A or a number)
# In PERL, "=~" performs a regex operation on the left argument
# m/<regex>/ matches the regular expression
my $format = "";
my $suffix = "";
my $channels = "";
my $scheme = "";
# VK_FORMAT_ is a simple 422 format
if ($line =~ m/(VK_FORMAT_[RGBX0-9]+_422_UNORM(_4PACK16)?)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (exists($foundFormats{$format})) { next }
$foundFormats{$format} = 1;
# VK_FORMAT_G8B8G8R8_422_UNORM,
# VK_FORMAT_B8G8R8G8_422_UNORM,
# VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
# VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
# VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
# VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
# VK_FORMAT_G16B16G16R16_422_UNORM,
# VK_FORMAT_B16G16R16G16_422_UNORM,
$format =~ m/VK_FORMAT_([RGBX0-9]+)_422_UNORM(_4PACK16)?/;
my $formatChannels = $1;
my $bits = "";
my $shiftBits = "";
my $position_xs = "";
my $position_ys = "";
my $last_green = 1;
while ($formatChannels =~ m/([RGBX0-9]*)([RGB])([0-9]+)X?([0-9]+)?/) {
# Processing from right to left for ease of regex expression
my $channel = $2;
my $bit = $3;
my $padding = $4 ? $4 : "";
if ($channels ne "") {
$channels = ", " . $channels;
$bits = ", " . $bits;
$shiftBits = ", " . $shiftBits;
$position_xs = ", " . $position_xs;
$position_ys = ", " . $position_ys;
}
# The default 4:2:2 positioning is currently cosited-even.
# Block size is 2x1: Sample positions coded as 1/128 on X and 1/256 on Y
# Cosited-even:
# Position Sample
# X Y X Y
# Y0: 0.5, 0.5 -> 64, 128
# U : 0.5, 0.5 -> 64, 128
# Y1: 1.5, 0.5 -> 192, 128
# V : 0.5, 0.5 -> 64, 128
# Midpoint:
# Position Sample
# X Y X Y
# Y0: 0.5, 0.5 -> 64, 128
# U : 1.0, 0.5 -> 128, 128
# Y1: 1.5, 0.5 -> 192, 128
# V : 1.0, 0.5 -> 128, 128
if ($channel eq 'R') {
$channels = "2" . $channels; # 2 = Cr / V
$position_xs = "64" . $position_xs;
$position_ys = "128" . $position_ys;
} elsif ($channel eq 'G') {
$channels = "0" . $channels; # 0 = Y
$position_xs = ($last_green ? "192" : "64") . $position_xs;
$position_ys = "128" . $position_ys;
$last_green = 0;
} elsif ($channel eq 'B') {
$channels = "1" . $channels; # 1 = Cb / U
$position_xs = "64" . $position_xs;
$position_ys = "128" . $position_ys;
}
$bits = $bit . $bits;
if ($padding ne "") { $shiftBits = $padding . $shiftBits; }
else { $shiftBits = "0" . $shiftBits; }
$formatChannels = $1;
}
print "case $format: {\n";
print " int channels[] = {$channels}; int bits[] = {$bits}; int shiftBits[] = {$shiftBits};\n";
print " int position_xs[] = {$position_xs}; int position_ys[] = {$position_ys};\n";
print " return createDFD422($bigEndian, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);\n}\n";
} elsif ($line =~ m/VK_FORMAT_[RGBAE0-9]+_/) {
# Set $format to the enum identifier
($line =~ m/(VK_FORMAT[A-Z0-9_]+)/);
# $<number> holds the <number>'th parenthesised entry in the previous regex
# (only one in this case)
$format = $1;
# Skip a format if we've already processed it
if (!formatProcessed($format)) {
if ($format =~ m/_E5B9G9R9/) {
# Special case (assumed little-endian).
print "case $format: {\n";
print " int bits[] = {0}; int channels[] = {0};\n";
print " return createDFDPacked(0, 6, bits, channels, s_UFLOAT);\n";
print "}\n";
$foundFormats{$format} = 1;
} elsif ($format =~ m/_PACK/) {
# Packed formats end "_PACK<n>" - is this format packed?
# Extract the channel identifiers and suffix from the packed format
$format =~ m/VK_FORMAT_([RGBA0-9]+)_([^_]+)_PACK[0-9]+/;
# The first parenthesised bit of regex is the channels ("R5G5B5" etc.)
$channels = $1;
# The second parenthesised bit of regex is the suffix ("UNORM" etc.)
$suffix = $2;
# N.B. We don't care about the total bit count (after "PACK" in the name)
# Create an empty array of channel names and corresponding bits
my @packChannels = ();
my @packBits = ();
# Loop over channels, separating out the last letter followed by a number
while ($channels =~ m/([RGBA0-9]*)([RGBA])([0-9]+)/) {
# Add the rightmost channel name to our array
push @packChannels, $2;
# Add the rightmost channel bits to the array
push @packBits, $3;
# Truncate the channels string to remove the channel we've processed
$channels = $1;
}
# The number of channels we've found is the array length we've built
my $numChannels = @packChannels;
# Packed output needs a C block for local variables
print "case $format: {\n";
# Start with a null list of channel ids
my $channelIds = "";
# Loop over the channel names we've found
foreach (@packChannels) {
# Use a comma as a separator, so don't add it if the $channelIds string is empty
if ($channelIds ne "") { $channelIds .= ","; }
# Map the channel names to our internal numbering
if ($_ eq 'R') { $channelIds .= "0"; }
elsif ($_ eq 'G') { $channelIds .= "1"; }
elsif ($_ eq 'B') { $channelIds .= "2"; }
elsif ($_ eq 'A') { $channelIds .= "3"; }
}
# Channel bit counts are easier: we can use join() to make a comma-separated
# string of the numbers in the array
my $channelBits = join (',', @packBits);
# Print initialisation for the two arrays we've created
print " int channels[] = {" . $channelIds . "}; ";
print "int bits[] = {" . $channelBits . "};\n";
# Now print the function call and close the block
print " return createDFDPacked($bigEndian, $numChannels, bits, channels, s_$suffix);\n";
print "}\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# If we're not packed, do we have a simple RGBA channel size list with a suffix?
# N.B. We don't want to pick up downsampled or planar formats, which have more _-separated fields
# - "$" matches the end of the format identifier
} elsif ($format =~ m/VK_FORMAT_A([0-9]+)_([^_]+)(_[^_]+)?$/) {
# Special case for alpha-only formats
# Extract our "suffix" (e.g. "UNORM") and bytes per channel
$suffix = $2;
my $bytesPerChannel = $1 / 8;
# Output the case entry
print "case $format: return createDFDAlpha($bigEndian, $bytesPerChannel, s_$suffix);\n";
} elsif ($format =~ m/VK_FORMAT_([RGBA0-9]+)_([^_]+)$/) {
# Extract our "channels" (e.g. "B8G8R8") and "suffix" (e.g. "UNORM")
$channels = $1;
$suffix = $2;
my $rbswap = 0;
my $numChannels = 0;
# Non-packed format either start with red (R8G8B8A8) or blue (B8G8R8A8)
# We have a special case to notice when we start with blue
if (substr($channels,0,1) eq "B") {
# Red and blue are swapped (B, G, R, A) - record this
# N.B. createDFDUnpacked() just knows this and R,G,B,A channel order, not arbitrary
$rbswap = 1;
# We know we saw "B" for blue, so we must also have red and green
$numChannels = 3;
# If we have "A" in the channels as well, we have four channels
if ($channels =~ m/A/) {
$numChannels = 4;
}
} else {
# We didn't start "B", so we're in conventional order (R, G, B, A)
$rbswap = 0;
# Check for the channel names present and map that to the number of channels
if ($channels =~ m/A/) {
$numChannels = 4;
} elsif ($channels =~ m/B/) {
$numChannels = 3;
} elsif ($channels =~ m/G/) {
$numChannels = 2;
} else {
$numChannels = 1;
}
}
# In an unpacked format, all the channels are the same size, so we only need to check one
$channels =~ m/R([0-9]+)/;
# For unpacked, we need bytes per channel, not bits
my $bytesPerChannel = $1 / 8;
# Output the case entry
print "case $format: return createDFDUnpacked($bigEndian, $numChannels, $bytesPerChannel, $rbswap, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
} elsif ($format =~ m/R16G16_SFIXED5_NV/) {
# Currently only this 2-channel SFIXED5 format exists so an
# explicit match is used.
# Output the case entry
print "case $format: return createDFDUnpacked($bigEndian, 2, 2, 0, s_SFIXED5);\n";
}
}
# VK_FORMAT_ is a packed HDR formats with padding
# R10X6_UNORM_PACK16
# R10X6G10X6_UNORM_2PACK16
# R10X6G10X6B10X6A10X6_UNORM_4PACK16
# R12X4_UNORM_PACK16
# R12X4G12X4_UNORM_2PACK16
# R12X4G12X4B12X4A12X4_UNORM_4PACK16
} elsif ($line =~ m/(VK_FORMAT_R10X6_UNORM_PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0}; int bits[] = {10}; int shiftBits[] = {6};\n";
print " return createDFDPackedShifted($bigEndian, 1, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R10X6G10X6_UNORM_2PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1}; int bits[] = {10, 10}; int shiftBits[] = {6, 6};\n";
print " return createDFDPackedShifted($bigEndian, 2, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1, 2, 3}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};\n";
print " return createDFDPackedShifted($bigEndian, 4, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R12X4_UNORM_PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0}; int bits[] = {12}; int shiftBits[] = {4};\n";
print " return createDFDPackedShifted($bigEndian, 1, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R12X4G12X4_UNORM_2PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1}; int bits[] = {12, 12}; int shiftBits[] = {4, 4};\n";
print " return createDFDPackedShifted($bigEndian, 2, bits, shiftBits, channels, s_UNORM);\n}\n"
}
} elsif ($line =~ m/(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)/) {
$format = $1; # Extract the format identifier from the rest of the line
if (!exists($foundFormats{$format})) {
$foundFormats{$format} = 1;
print "case $format: {\n";
print " int channels[] = {0, 1, 2, 3}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};\n";
print " return createDFDPackedShifted($bigEndian, 4, bits, shiftBits, channels, s_UNORM);\n}\n"
}
# If we weren't VK_FORMAT_ plus a channel, we might be a compressed
# format, that ends "_BLOCK"
} elsif ($line =~ m/(VK_FORMAT_[A-Z0-9x_]+_BLOCK(_[A-Z]+)?)/) {
# Extract the format identifier from the rest of the line
$format = $1;
# Skip a format if we've already processed it
if (!formatProcessed($format)) {
# Special-case BC1_RGB to separate it from BC1_RGBA
if ($line =~ m/VK_FORMAT_BC1_RGB_([A-Z]+)_BLOCK/) {
# Pull out the suffix ("UNORM" etc.)
$suffix = $1;
# Output the special case - a 4x4 BC1 block
print "case $format: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# Special case BC1_RGBA (but still extract the suffix with a regex)
} elsif ($line =~ m/VK_FORMAT_BC1_RGBA_([A-Z]+)_BLOCK/) {
$suffix = $1;
print "case $format: return createDFDCompressed(c_BC1_RGBA, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# All the other BC formats don't have a channel identifier in the name, so we regex match them
} elsif ($line =~ m/VK_FORMAT_(BC(?:[2-57]|6H))_([A-Z]+)_BLOCK/) {
$scheme = $1;
$suffix = $2;
print "case $format: return createDFDCompressed(c_$scheme, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# The ETC and EAC formats have two-part names (ETC2_R8G8B8, EAC_R11 etc.) starting with "E"
} elsif ($line =~ m/VK_FORMAT_(E[^_]+_[^_]+)_([A-Z]+)_BLOCK/) {
$scheme = $1;
$suffix = $2;
print "case $format: return createDFDCompressed(c_$scheme, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
# Finally, ASTC and PVRTC, the only cases where the block size is a parameter
} elsif ($line =~ m/VK_FORMAT_ASTC_([0-9]+)x([0-9]+)(x([0-9]+))?_([A-Z]+)_BLOCK(_EXT)?/) {
my $w = $1;
my $h = $2;
my $d = $4 ? $4 : '1';
$suffix = $5;
print "case $format: return createDFDCompressed(c_ASTC, $w, $h, $d, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
} elsif ($line =~ m/VK_FORMAT_PVRTC1_2BPP_([A-Z]+)_BLOCK_IMG/) {
# Pull out the suffix ("UNORM" etc.)
$suffix = $1;
# Output the special case - an 8x4 PVRTC block
print "case $format: return createDFDCompressed(c_PVRTC, 8, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
} elsif ($line =~ m/VK_FORMAT_PVRTC1_4BPP_([A-Z]+)_BLOCK_IMG/) {
# Pull out the suffix ("UNORM" etc.)
$suffix = $1;
# Output the special case - an 8x4 PVRTC block
print "case $format: return createDFDCompressed(c_PVRTC, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
} elsif ($line =~ m/VK_FORMAT_PVRTC2_2BPP_([A-Z]+)_BLOCK_IMG/) {
# Pull out the suffix ("UNORM" etc.)
$suffix = $1;
# Output the special case - an 8x4 PVRTC block
print "case $format: return createDFDCompressed(c_PVRTC2, 8, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
} elsif ($line =~ m/VK_FORMAT_PVRTC2_4BPP_([A-Z]+)_BLOCK_IMG/) {
# Pull out the suffix ("UNORM" etc.)
$suffix = $1;
# Output the special case - an 8x4 PVRTC block
print "case $format: return createDFDCompressed(c_PVRTC2, 4, 4, 1, s_$suffix);\n";
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
}
}
} elsif ($line =~ m/(VK_FORMAT_X8_D24_UNORM_PACK32)/) {
# Extract the format identifier from the rest of the line
$format = $1;
if (!exists($foundFormats{$format})) {
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
print "case $format: return createDFDDepthStencil(24,0,4);\n";
}
} elsif ($line =~ m/(VK_FORMAT_D32_SFLOAT_S8_UINT)/) {
# Extract the format identifier from the rest of the line
$format = $1;
if (!exists($foundFormats{$format})) {
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
print "case $format: return createDFDDepthStencil(32,8,8);\n";
}
} elsif ($line =~ m/(VK_FORMAT_D16_UNORM_S8_UINT)/) {
# Extract the format identifier from the rest of the line
$format = $1;
if (!exists($foundFormats{$format})) {
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
print "case $format: return createDFDDepthStencil(16,8,4);\n";
}
} elsif ($line =~ m/(VK_FORMAT_D24_UNORM_S8_UINT)/) {
# Extract the format identifier from the rest of the line
$format = $1;
if (!exists($foundFormats{$format})) {
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
print "case $format: return createDFDDepthStencil(24,8,4);\n";
}
} elsif ($line =~ m/(VK_FORMAT_D32_SFLOAT)/) {
# Extract the format identifier from the rest of the line
$format = $1;
if (!exists($foundFormats{$format})) {
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
print "case $format: return createDFDDepthStencil(32,0,4);\n";
}
} elsif ($line =~ m/(VK_FORMAT_S8_UINT)/) {
# Extract the format identifier from the rest of the line
$format = $1;
if (!exists($foundFormats{$format})) {
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
print "case $format: return createDFDDepthStencil(0,8,1);\n";
}
} elsif ($line =~ m/(VK_FORMAT_D16_UNORM)/) {
# Extract the format identifier from the rest of the line
$format = $1;
if (!exists($foundFormats{$format})) {
# Add the format we've processed to our "done" hash
$foundFormats{$format} = 1;
print "case $format: return createDFDDepthStencil(16,0,2);\n";
}
}
# ...and continue to the next line
}
# vim:ai:ts=4:sts=4:sw=2:expandtab
+1050
View File
File diff suppressed because it is too large Load Diff
+215
View File
@@ -0,0 +1,215 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @~English
* @brief Utilities for querying info from a data format descriptor.
* @author Mark Callow
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <KHR/khr_df.h>
#include "dfd.h"
/**
* @~English
* @brief Get the number and size of the image components from a DFD.
*
* This simplified function is for use only with the DFDs for unpacked
* formats which means all components have the same size.
*
* @param DFD Pointer to a Data Format Descriptor to interpret,
described as 32-bit words in native endianness.
Note that this is the whole descriptor, not just
the basic descriptor block.
* @param numComponents pointer to a 32-bit word in which the number of
components will be written.
* @param componentByteLength pointer to a 32-bit word in which the size of
a component in bytes will be written.
*/
void
getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents,
uint32_t* componentByteLength)
{
const uint32_t *BDFDB = DFD+1;
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
uint32_t sampleNumber;
uint32_t currentChannel = ~0U; /* Don't start matched. */
/* This is specifically for unpacked formats which means the size of */
/* each component is the same. */
*numComponents = 0;
for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {
uint32_t sampleByteLength = (KHR_DFDSVAL(BDFDB, sampleNumber, BITLENGTH) + 1) >> 3U;
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleNumber, CHANNELID);
if (sampleChannel == currentChannel) {
/* Continuation of the same channel. */
/* Accumulate the byte length. */
*componentByteLength += sampleByteLength;
} else {
/* Everything is new. Hopefully. */
currentChannel = sampleChannel;
(*numComponents)++;
*componentByteLength = sampleByteLength;
}
}
}
/**
* @~English
* @brief Return the number of "components" in the data.
*
* Calculates the number of uniques samples in the DFD by combining
* multiple samples for the same channel. For uncompressed colorModels
* this is the same as the number of components in the image data. For
* block-compressed color models this is the number of samples in
* the color model, typically 1 and in a few cases 2.
*
* @param DFD Pointer to a Data Format Descriptor for which,
* described as 32-bit words in native endianness.
* Note that this is the whole descriptor, not just
* the basic descriptor block.
*/
uint32_t getDFDNumComponents(const uint32_t* DFD)
{
const uint32_t *BDFDB = DFD+1;
uint32_t currentChannel = ~0U; /* Don't start matched. */
uint32_t numComponents = 0;
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
uint32_t sampleNumber;
for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {
uint32_t sampleChannel = KHR_DFDSVAL(BDFDB, sampleNumber, CHANNELID);
if (sampleChannel != currentChannel) {
numComponents++;
currentChannel = sampleChannel;
}
}
return numComponents;
}
/**
* @~English
* @brief Reconstruct the value of bytesPlane0 from sample info.
*
* @deprecated Use reconstructDFDBytesPlanesFromSamples. This does not handle
* the possible second plane of the ETC1S model.
*
* Reconstruct the value for data that has been variable-rate compressed
* and and whose bytesPlane0 value has been set to 0. For DFDs that
* are valid for KTX files. Little-endian data only and no multi-plane models
* except ETC1S.
*
* @param DFD Pointer to the Data Format Descriptor for which to provide
* the value described as 32-bit words in native endianness.
* Note that this is the whole descriptor, not just
* the basic descriptor block.
* @return The number of bytes a pixel occupies in bytesPlane0.
*/
uint32_t
reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD)
{
const uint32_t *BDFDB = DFD+1;
uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB);
uint32_t sampleNumber;
uint32_t bitsPlane0 = 0;
int32_t largestOffset = 0;
uint32_t sampleNumberWithLargestOffset = 0;
// Special case these depth{,-stencil} formats. The unused bits are
// in the MSBs so have no visibility in the DFD therefore the max offset
// algorithm below returns a value that is too small.
if (KHR_DFDSVAL(BDFDB, 0, CHANNELID) == KHR_DF_CHANNEL_COMMON_DEPTH) {
if (numSamples == 1) {
if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 24) {
// X8_D24_UNORM_PACK32,
return 4;
}
} else if (numSamples == 2) {
if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 16) {
// D16_UNORM_S8_UINT
return 4;
}
if (KHR_DFDSVAL(BDFDB, 0, BITLENGTH) + 1 == 32
&& KHR_DFDSVAL(BDFDB, 1, CHANNELID) == KHR_DF_CHANNEL_COMMON_STENCIL) {
// D32_SFLOAT_S8_UINT
return 8;
}
}
}
if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_ETC1S) {
// Size of the first plane.
return 8;
}
for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) {
int32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleNumber, BITOFFSET);
if (sampleBitOffset > largestOffset) {
largestOffset = sampleBitOffset;
sampleNumberWithLargestOffset = sampleNumber;
}
}
/* The sample bitLength field stores the bit length - 1. */
uint32_t sampleBitLength = KHR_DFDSVAL(BDFDB, sampleNumberWithLargestOffset, BITLENGTH) + 1;
bitsPlane0 = largestOffset + sampleBitLength;
return bitsPlane0 >> 3U;
}
/**
* @~English
* @brief Reconstruct the values of bytesPlane[01] from sample info.
*
* Reconstruct the values for data that has been variable-rate compressed
* and whose bytesPlane[01] values have been set to 0 and update the
* fields of the target DFD. For DFDs that are valid for KTX files.
* Little-endian data only and no multi-plane models except ETC1S hence
* only looking at bytesPlane0 abd bytesPlane1.
*
* @param DFD Pointer to a Data Format Descriptor for which,
* described as 32-bit words in native endianness.
* Note that this is the whole descriptor, not just
* the basic descriptor block.
*/
void
reconstructDFDBytesPlanesFromSamples(uint32_t* DFD)
{
uint32_t *BDFDB = DFD+1;
KHR_DFDSETVAL(BDFDB, BYTESPLANE0, reconstructDFDBytesPlane0FromSamples(DFD));
if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_ETC1S) {
if (KHR_DFDSAMPLECOUNT(BDFDB) == 2)
KHR_DFDSETVAL(BDFDB, BYTESPLANE1, 8);
}
}
/**
* @~English
* @brief Reconstruct the value of bytesPlane0 from sample info.
*
* @see reconstructDFDBytesPlane0FromSamples for details.
* @deprecated For backward comparibility only. Use
* reconstructDFDBytesPlanesFromSamples.
*
* @param DFD Pointer to the Data Format Descriptor for which to provide
* the value described as 32-bit words in native endianness.
* Note that this is the whole descriptor, not just
* the basic descriptor block.
* @param bytesPlane0 pointer to a 32-bit word in which the recreated
* value of bytesPlane0 will be written.
*/
void
recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, uint32_t* bytesPlane0)
{
*bytesPlane0 = reconstructDFDBytesPlane0FromSamples(DFD);
}
+615
View File
@@ -0,0 +1,615 @@
/* Copyright 2019-2020 The Khronos Group Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <vulkan/vulkan_core.h>
#include "KHR/khr_df.h"
#include "dfd.h"
const char*
formatname(VkFormat format)
{
switch (format) {
case VK_FORMAT_UNDEFINED:
return "VK_FORMAT_UNDEFINED";
case VK_FORMAT_R4G4_UNORM_PACK8:
return "VK_FORMAT_R4G4_UNORM_PACK8";
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
return "VK_FORMAT_R4G4B4A4_UNORM_PACK16";
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
return "VK_FORMAT_B4G4R4A4_UNORM_PACK16";
case VK_FORMAT_R5G6B5_UNORM_PACK16:
return "VK_FORMAT_R5G6B5_UNORM_PACK16";
case VK_FORMAT_B5G6R5_UNORM_PACK16:
return "VK_FORMAT_B5G6R5_UNORM_PACK16";
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
return "VK_FORMAT_R5G5B5A1_UNORM_PACK16";
case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
return "VK_FORMAT_B5G5R5A1_UNORM_PACK16";
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
return "VK_FORMAT_A1R5G5B5_UNORM_PACK16";
case VK_FORMAT_R8_UNORM:
return "VK_FORMAT_R8_UNORM";
case VK_FORMAT_R8_SNORM:
return "VK_FORMAT_R8_SNORM";
case VK_FORMAT_R8_USCALED:
return "VK_FORMAT_R8_USCALED";
case VK_FORMAT_R8_SSCALED:
return "VK_FORMAT_R8_SSCALED";
case VK_FORMAT_R8_UINT:
return "VK_FORMAT_R8_UINT";
case VK_FORMAT_R8_SINT:
return "VK_FORMAT_R8_SINT";
case VK_FORMAT_R8_SRGB:
return "VK_FORMAT_R8_SRGB";
case VK_FORMAT_R8G8_UNORM:
return "VK_FORMAT_R8G8_UNORM";
case VK_FORMAT_R8G8_SNORM:
return "VK_FORMAT_R8G8_SNORM";
case VK_FORMAT_R8G8_USCALED:
return "VK_FORMAT_R8G8_USCALED";
case VK_FORMAT_R8G8_SSCALED:
return "VK_FORMAT_R8G8_SSCALED";
case VK_FORMAT_R8G8_UINT:
return "VK_FORMAT_R8G8_UINT";
case VK_FORMAT_R8G8_SINT:
return "VK_FORMAT_R8G8_SINT";
case VK_FORMAT_R8G8_SRGB:
return "VK_FORMAT_R8G8_SRGB";
case VK_FORMAT_R8G8B8_UNORM:
return "VK_FORMAT_R8G8B8_UNORM";
case VK_FORMAT_R8G8B8_SNORM:
return "VK_FORMAT_R8G8B8_SNORM";
case VK_FORMAT_R8G8B8_USCALED:
return "VK_FORMAT_R8G8B8_USCALED";
case VK_FORMAT_R8G8B8_SSCALED:
return "VK_FORMAT_R8G8B8_SSCALED";
case VK_FORMAT_R8G8B8_UINT:
return "VK_FORMAT_R8G8B8_UINT";
case VK_FORMAT_R8G8B8_SINT:
return "VK_FORMAT_R8G8B8_SINT";
case VK_FORMAT_R8G8B8_SRGB:
return "VK_FORMAT_R8G8B8_SRGB";
case VK_FORMAT_B8G8R8_UNORM:
return "VK_FORMAT_B8G8R8_UNORM";
case VK_FORMAT_B8G8R8_SNORM:
return "VK_FORMAT_B8G8R8_SNORM";
case VK_FORMAT_B8G8R8_USCALED:
return "VK_FORMAT_B8G8R8_USCALED";
case VK_FORMAT_B8G8R8_SSCALED:
return "VK_FORMAT_B8G8R8_SSCALED";
case VK_FORMAT_B8G8R8_UINT:
return "VK_FORMAT_B8G8R8_UINT";
case VK_FORMAT_B8G8R8_SINT:
return "VK_FORMAT_B8G8R8_SINT";
case VK_FORMAT_B8G8R8_SRGB:
return "VK_FORMAT_B8G8R8_SRGB";
case VK_FORMAT_R8G8B8A8_UNORM:
return "VK_FORMAT_R8G8B8A8_UNORM";
case VK_FORMAT_R8G8B8A8_SNORM:
return "VK_FORMAT_R8G8B8A8_SNORM";
case VK_FORMAT_R8G8B8A8_USCALED:
return "VK_FORMAT_R8G8B8A8_USCALED";
case VK_FORMAT_R8G8B8A8_SSCALED:
return "VK_FORMAT_R8G8B8A8_SSCALED";
case VK_FORMAT_R8G8B8A8_UINT:
return "VK_FORMAT_R8G8B8A8_UINT";
case VK_FORMAT_R8G8B8A8_SINT:
return "VK_FORMAT_R8G8B8A8_SINT";
case VK_FORMAT_R8G8B8A8_SRGB:
return "VK_FORMAT_R8G8B8A8_SRGB";
case VK_FORMAT_B8G8R8A8_UNORM:
return "VK_FORMAT_B8G8R8A8_UNORM";
case VK_FORMAT_B8G8R8A8_SNORM:
return "VK_FORMAT_B8G8R8A8_SNORM";
case VK_FORMAT_B8G8R8A8_USCALED:
return "VK_FORMAT_B8G8R8A8_USCALED";
case VK_FORMAT_B8G8R8A8_SSCALED:
return "VK_FORMAT_B8G8R8A8_SSCALED";
case VK_FORMAT_B8G8R8A8_UINT:
return "VK_FORMAT_B8G8R8A8_UINT";
case VK_FORMAT_B8G8R8A8_SINT:
return "VK_FORMAT_B8G8R8A8_SINT";
case VK_FORMAT_B8G8R8A8_SRGB:
return "VK_FORMAT_B8G8R8A8_SRGB";
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
return "VK_FORMAT_A8B8G8R8_UNORM_PACK32";
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
return "VK_FORMAT_A8B8G8R8_SNORM_PACK32";
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
return "VK_FORMAT_A8B8G8R8_USCALED_PACK32";
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
return "VK_FORMAT_A8B8G8R8_SSCALED_PACK32";
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
return "VK_FORMAT_A8B8G8R8_UINT_PACK32";
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
return "VK_FORMAT_A8B8G8R8_SINT_PACK32";
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
return "VK_FORMAT_A8B8G8R8_SRGB_PACK32";
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
return "VK_FORMAT_A2R10G10B10_UNORM_PACK32";
case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
return "VK_FORMAT_A2R10G10B10_SNORM_PACK32";
case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
return "VK_FORMAT_A2R10G10B10_USCALED_PACK32";
case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
return "VK_FORMAT_A2R10G10B10_SSCALED_PACK32";
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
return "VK_FORMAT_A2R10G10B10_UINT_PACK32";
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
return "VK_FORMAT_A2R10G10B10_SINT_PACK32";
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
return "VK_FORMAT_A2B10G10R10_UNORM_PACK32";
case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
return "VK_FORMAT_A2B10G10R10_SNORM_PACK32";
case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
return "VK_FORMAT_A2B10G10R10_USCALED_PACK32";
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
return "VK_FORMAT_A2B10G10R10_SSCALED_PACK32";
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
return "VK_FORMAT_A2B10G10R10_UINT_PACK32";
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
return "VK_FORMAT_A2B10G10R10_SINT_PACK32";
case VK_FORMAT_R16_UNORM:
return "VK_FORMAT_R16_UNORM";
case VK_FORMAT_R16_SNORM:
return "VK_FORMAT_R16_SNORM";
case VK_FORMAT_R16_USCALED:
return "VK_FORMAT_R16_USCALED";
case VK_FORMAT_R16_SSCALED:
return "VK_FORMAT_R16_SSCALED";
case VK_FORMAT_R16_UINT:
return "VK_FORMAT_R16_UINT";
case VK_FORMAT_R16_SINT:
return "VK_FORMAT_R16_SINT";
case VK_FORMAT_R16_SFLOAT:
return "VK_FORMAT_R16_SFLOAT";
case VK_FORMAT_R16G16_UNORM:
return "VK_FORMAT_R16G16_UNORM";
case VK_FORMAT_R16G16_SNORM:
return "VK_FORMAT_R16G16_SNORM";
case VK_FORMAT_R16G16_USCALED:
return "VK_FORMAT_R16G16_USCALED";
case VK_FORMAT_R16G16_SSCALED:
return "VK_FORMAT_R16G16_SSCALED";
case VK_FORMAT_R16G16_UINT:
return "VK_FORMAT_R16G16_UINT";
case VK_FORMAT_R16G16_SINT:
return "VK_FORMAT_R16G16_SINT";
case VK_FORMAT_R16G16_SFLOAT:
return "VK_FORMAT_R16G16_SFLOAT";
case VK_FORMAT_R16G16B16_UNORM:
return "VK_FORMAT_R16G16B16_UNORM";
case VK_FORMAT_R16G16B16_SNORM:
return "VK_FORMAT_R16G16B16_SNORM";
case VK_FORMAT_R16G16B16_USCALED:
return "VK_FORMAT_R16G16B16_USCALED";
case VK_FORMAT_R16G16B16_SSCALED:
return "VK_FORMAT_R16G16B16_SSCALED";
case VK_FORMAT_R16G16B16_UINT:
return "VK_FORMAT_R16G16B16_UINT";
case VK_FORMAT_R16G16B16_SINT:
return "VK_FORMAT_R16G16B16_SINT";
case VK_FORMAT_R16G16B16_SFLOAT:
return "VK_FORMAT_R16G16B16_SFLOAT";
case VK_FORMAT_R16G16B16A16_UNORM:
return "VK_FORMAT_R16G16B16A16_UNORM";
case VK_FORMAT_R16G16B16A16_SNORM:
return "VK_FORMAT_R16G16B16A16_SNORM";
case VK_FORMAT_R16G16B16A16_USCALED:
return "VK_FORMAT_R16G16B16A16_USCALED";
case VK_FORMAT_R16G16B16A16_SSCALED:
return "VK_FORMAT_R16G16B16A16_SSCALED";
case VK_FORMAT_R16G16B16A16_UINT:
return "VK_FORMAT_R16G16B16A16_UINT";
case VK_FORMAT_R16G16B16A16_SINT:
return "VK_FORMAT_R16G16B16A16_SINT";
case VK_FORMAT_R16G16B16A16_SFLOAT:
return "VK_FORMAT_R16G16B16A16_SFLOAT";
case VK_FORMAT_R32_UINT:
return "VK_FORMAT_R32_UINT";
case VK_FORMAT_R32_SINT:
return "VK_FORMAT_R32_SINT";
case VK_FORMAT_R32_SFLOAT:
return "VK_FORMAT_R32_SFLOAT";
case VK_FORMAT_R32G32_UINT:
return "VK_FORMAT_R32G32_UINT";
case VK_FORMAT_R32G32_SINT:
return "VK_FORMAT_R32G32_SINT";
case VK_FORMAT_R32G32_SFLOAT:
return "VK_FORMAT_R32G32_SFLOAT";
case VK_FORMAT_R32G32B32_UINT:
return "VK_FORMAT_R32G32B32_UINT";
case VK_FORMAT_R32G32B32_SINT:
return "VK_FORMAT_R32G32B32_SINT";
case VK_FORMAT_R32G32B32_SFLOAT:
return "VK_FORMAT_R32G32B32_SFLOAT";
case VK_FORMAT_R32G32B32A32_UINT:
return "VK_FORMAT_R32G32B32A32_UINT";
case VK_FORMAT_R32G32B32A32_SINT:
return "VK_FORMAT_R32G32B32A32_SINT";
case VK_FORMAT_R32G32B32A32_SFLOAT:
return "VK_FORMAT_R32G32B32A32_SFLOAT";
case VK_FORMAT_R64_UINT:
return "VK_FORMAT_R64_UINT";
case VK_FORMAT_R64_SINT:
return "VK_FORMAT_R64_SINT";
case VK_FORMAT_R64_SFLOAT:
return "VK_FORMAT_R64_SFLOAT";
case VK_FORMAT_R64G64_UINT:
return "VK_FORMAT_R64G64_UINT";
case VK_FORMAT_R64G64_SINT:
return "VK_FORMAT_R64G64_SINT";
case VK_FORMAT_R64G64_SFLOAT:
return "VK_FORMAT_R64G64_SFLOAT";
case VK_FORMAT_R64G64B64_UINT:
return "VK_FORMAT_R64G64B64_UINT";
case VK_FORMAT_R64G64B64_SINT:
return "VK_FORMAT_R64G64B64_SINT";
case VK_FORMAT_R64G64B64_SFLOAT:
return "VK_FORMAT_R64G64B64_SFLOAT";
case VK_FORMAT_R64G64B64A64_UINT:
return "VK_FORMAT_R64G64B64A64_UINT";
case VK_FORMAT_R64G64B64A64_SINT:
return "VK_FORMAT_R64G64B64A64_SINT";
case VK_FORMAT_R64G64B64A64_SFLOAT:
return "VK_FORMAT_R64G64B64A64_SFLOAT";
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
return "VK_FORMAT_B10G11R11_UFLOAT_PACK32";
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
return "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32";
case VK_FORMAT_D16_UNORM:
return "VK_FORMAT_D16_UNORM";
case VK_FORMAT_X8_D24_UNORM_PACK32:
return "VK_FORMAT_X8_D24_UNORM_PACK32";
case VK_FORMAT_D32_SFLOAT:
return "VK_FORMAT_D32_SFLOAT";
case VK_FORMAT_S8_UINT:
return "VK_FORMAT_S8_UINT";
case VK_FORMAT_D16_UNORM_S8_UINT:
return "VK_FORMAT_D16_UNORM_S8_UINT";
case VK_FORMAT_D24_UNORM_S8_UINT:
return "VK_FORMAT_D24_UNORM_S8_UINT";
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return "VK_FORMAT_D32_SFLOAT_S8_UINT";
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
return "VK_FORMAT_BC1_RGB_UNORM_BLOCK";
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
return "VK_FORMAT_BC1_RGB_SRGB_BLOCK";
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
return "VK_FORMAT_BC1_RGBA_UNORM_BLOCK";
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
return "VK_FORMAT_BC1_RGBA_SRGB_BLOCK";
case VK_FORMAT_BC2_UNORM_BLOCK:
return "VK_FORMAT_BC2_UNORM_BLOCK";
case VK_FORMAT_BC2_SRGB_BLOCK:
return "VK_FORMAT_BC2_SRGB_BLOCK";
case VK_FORMAT_BC3_UNORM_BLOCK:
return "VK_FORMAT_BC3_UNORM_BLOCK";
case VK_FORMAT_BC3_SRGB_BLOCK:
return "VK_FORMAT_BC3_SRGB_BLOCK";
case VK_FORMAT_BC4_UNORM_BLOCK:
return "VK_FORMAT_BC4_UNORM_BLOCK";
case VK_FORMAT_BC4_SNORM_BLOCK:
return "VK_FORMAT_BC4_SNORM_BLOCK";
case VK_FORMAT_BC5_UNORM_BLOCK:
return "VK_FORMAT_BC5_UNORM_BLOCK";
case VK_FORMAT_BC5_SNORM_BLOCK:
return "VK_FORMAT_BC5_SNORM_BLOCK";
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
return "VK_FORMAT_BC6H_UFLOAT_BLOCK";
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
return "VK_FORMAT_BC6H_SFLOAT_BLOCK";
case VK_FORMAT_BC7_UNORM_BLOCK:
return "VK_FORMAT_BC7_UNORM_BLOCK";
case VK_FORMAT_BC7_SRGB_BLOCK:
return "VK_FORMAT_BC7_SRGB_BLOCK";
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
return "VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK";
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
return "VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK";
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
return "VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK";
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
return "VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK";
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
return "VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK";
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
return "VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK";
case VK_FORMAT_EAC_R11_UNORM_BLOCK:
return "VK_FORMAT_EAC_R11_UNORM_BLOCK";
case VK_FORMAT_EAC_R11_SNORM_BLOCK:
return "VK_FORMAT_EAC_R11_SNORM_BLOCK";
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
return "VK_FORMAT_EAC_R11G11_UNORM_BLOCK";
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
return "VK_FORMAT_EAC_R11G11_SNORM_BLOCK";
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
return "VK_FORMAT_ASTC_4x4_UNORM_BLOCK";
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
return "VK_FORMAT_ASTC_4x4_SRGB_BLOCK";
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
return "VK_FORMAT_ASTC_5x4_UNORM_BLOCK";
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
return "VK_FORMAT_ASTC_5x4_SRGB_BLOCK";
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
return "VK_FORMAT_ASTC_5x5_UNORM_BLOCK";
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
return "VK_FORMAT_ASTC_5x5_SRGB_BLOCK";
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
return "VK_FORMAT_ASTC_6x5_UNORM_BLOCK";
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
return "VK_FORMAT_ASTC_6x5_SRGB_BLOCK";
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
return "VK_FORMAT_ASTC_6x6_UNORM_BLOCK";
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
return "VK_FORMAT_ASTC_6x6_SRGB_BLOCK";
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
return "VK_FORMAT_ASTC_8x5_UNORM_BLOCK";
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
return "VK_FORMAT_ASTC_8x5_SRGB_BLOCK";
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
return "VK_FORMAT_ASTC_8x6_UNORM_BLOCK";
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
return "VK_FORMAT_ASTC_8x6_SRGB_BLOCK";
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
return "VK_FORMAT_ASTC_8x8_UNORM_BLOCK";
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
return "VK_FORMAT_ASTC_8x8_SRGB_BLOCK";
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
return "VK_FORMAT_ASTC_10x5_UNORM_BLOCK";
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
return "VK_FORMAT_ASTC_10x5_SRGB_BLOCK";
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
return "VK_FORMAT_ASTC_10x6_UNORM_BLOCK";
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
return "VK_FORMAT_ASTC_10x6_SRGB_BLOCK";
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
return "VK_FORMAT_ASTC_10x8_UNORM_BLOCK";
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
return "VK_FORMAT_ASTC_10x8_SRGB_BLOCK";
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
return "VK_FORMAT_ASTC_10x10_UNORM_BLOCK";
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
return "VK_FORMAT_ASTC_10x10_SRGB_BLOCK";
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
return "VK_FORMAT_ASTC_12x10_UNORM_BLOCK";
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
return "VK_FORMAT_ASTC_12x10_SRGB_BLOCK";
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
return "VK_FORMAT_ASTC_12x12_UNORM_BLOCK";
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
return "VK_FORMAT_ASTC_12x12_SRGB_BLOCK";
case VK_FORMAT_G8B8G8R8_422_UNORM:
return "VK_FORMAT_G8B8G8R8_422_UNORM";
case VK_FORMAT_B8G8R8G8_422_UNORM:
return "VK_FORMAT_B8G8R8G8_422_UNORM";
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
return "VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM";
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
return "VK_FORMAT_G8_B8R8_2PLANE_420_UNORM";
case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
return "VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM";
case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
return "VK_FORMAT_G8_B8R8_2PLANE_422_UNORM";
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
return "VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM";
case VK_FORMAT_R10X6_UNORM_PACK16:
return "VK_FORMAT_R10X6_UNORM_PACK16";
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
return "VK_FORMAT_R10X6G10X6_UNORM_2PACK16";
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
return "VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16";
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
return "VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16";
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
return "VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16";
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
return "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16";
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
return "VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16";
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
return "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16";
case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
return "VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16";
case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
return "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16";
case VK_FORMAT_R12X4_UNORM_PACK16:
return "VK_FORMAT_R12X4_UNORM_PACK16";
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
return "VK_FORMAT_R12X4G12X4_UNORM_2PACK16";
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
return "VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16";
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
return "VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16";
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
return "VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16";
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
return "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16";
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
return "VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16";
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
return "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16";
case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
return "VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16";
case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
return "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16";
case VK_FORMAT_G16B16G16R16_422_UNORM:
return "VK_FORMAT_G16B16G16R16_422_UNORM";
case VK_FORMAT_B16G16R16G16_422_UNORM:
return "VK_FORMAT_B16G16R16G16_422_UNORM";
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
return "VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM";
case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
return "VK_FORMAT_G16_B16R16_2PLANE_420_UNORM";
case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
return "VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM";
case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
return "VK_FORMAT_G16_B16R16_2PLANE_422_UNORM";
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
return "VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM";
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
return "VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG";
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
return "VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG";
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
return "VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG";
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
return "VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG";
case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
return "VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG";
case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
return "VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG";
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
return "VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG";
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
return "VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG";
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK:
return "VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK";
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT";
case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT";
case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT";
case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT:
return "VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT";
default:
return "VK_UNKNOWN_FORMAT";
}
}
uint32_t *getmap(enum VkFormat f)
{
switch (f) {
#include "vk2dfd.inl"
default:
return 0; /* Unsupported value (notably, YUV formats). */
}
}
enum VkFormat unmap(uint32_t *dfd)
{
#include "dfd2vk.inl"
}
int main(int argc, char** argv)
{
unsigned int i;
for (i = 1; i <= 184; ++i) {
uint32_t *dfd = getmap((enum VkFormat)i);
VkFormat f = unmap(dfd);
if (i != f) printf("Input and output enums differ: %s (%d) -> %s (%d)\n",
formatname(i),i, formatname(f),f);
free((void *)dfd);
}
for (i = VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG;
i <= VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG; ++i) {
uint32_t *dfd = getmap((enum VkFormat)i);
VkFormat f = unmap(dfd);
if (i != f) printf("Input and output enums differ: %s (%d) -> %s (%d)\n",
formatname(i),i, formatname(f),f);
free((void *)dfd);
}
for (i = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT;
i <= VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT; ++i) {
uint32_t *dfd = getmap((enum VkFormat)i);
VkFormat f = unmap(dfd);
if (i != f) printf("Input and output enums differ: %s (%d) -> %s (%d)\n",
formatname(i),i, formatname(f),f);
free((void *)dfd);
}
for (i = VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT;
i <= VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT; ++i) {
uint32_t *dfd = getmap((enum VkFormat)i);
VkFormat f = unmap(dfd);
if (i != f) printf("Input and output enums differ: %s (%d) -> %s (%d)\n",
formatname(i),i, formatname(f),f);
free((void *)dfd);
}
return 0;
}
+34
View File
@@ -0,0 +1,34 @@
/* -*- tab-width: 4; -*- */
/* vi: set sw=2 ts=4 expandtab: */
/* Copyright 2019-2020 Mark Callow
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @~English
* @brief Create a DFD for a VkFormat.
*/
#include "dfd.h"
/**
* @~English
* @brief Create a DFD matching a VkFormat.
*
* @param[in] format VkFormat for which to create a DFD.
*
* @return pointer to the created DFD or 0 if format not supported or
* unrecognized. Caller is responsible for freeing the created
* DFD.
*/
uint32_t*
vk2dfd(enum VkFormat format)
{
switch (format) {
#include "vk2dfd.inl"
default: return 0;
}
}
+408
View File
@@ -0,0 +1,408 @@
/* Copyright 2019-2020 The Khronos Group Inc. */
/* SPDX-License-Identifier: Apache-2.0 */
/***************************** Do not edit. *****************************
Automatically generated by makevk2dfd.pl.
*************************************************************************/
case VK_FORMAT_R4G4_UNORM_PACK8: {
int channels[] = {1,0}; int bits[] = {4,4};
return createDFDPacked(0, 2, bits, channels, s_UNORM);
}
case VK_FORMAT_R4G4B4A4_UNORM_PACK16: {
int channels[] = {3,2,1,0}; int bits[] = {4,4,4,4};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_B4G4R4A4_UNORM_PACK16: {
int channels[] = {3,0,1,2}; int bits[] = {4,4,4,4};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_R5G6B5_UNORM_PACK16: {
int channels[] = {2,1,0}; int bits[] = {5,6,5};
return createDFDPacked(0, 3, bits, channels, s_UNORM);
}
case VK_FORMAT_B5G6R5_UNORM_PACK16: {
int channels[] = {0,1,2}; int bits[] = {5,6,5};
return createDFDPacked(0, 3, bits, channels, s_UNORM);
}
case VK_FORMAT_R5G5B5A1_UNORM_PACK16: {
int channels[] = {3,2,1,0}; int bits[] = {1,5,5,5};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_B5G5R5A1_UNORM_PACK16: {
int channels[] = {3,0,1,2}; int bits[] = {1,5,5,5};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_A1R5G5B5_UNORM_PACK16: {
int channels[] = {2,1,0,3}; int bits[] = {5,5,5,1};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_R8_UNORM: return createDFDUnpacked(0, 1, 1, 0, s_UNORM);
case VK_FORMAT_R8_SNORM: return createDFDUnpacked(0, 1, 1, 0, s_SNORM);
case VK_FORMAT_R8_USCALED: return createDFDUnpacked(0, 1, 1, 0, s_USCALED);
case VK_FORMAT_R8_SSCALED: return createDFDUnpacked(0, 1, 1, 0, s_SSCALED);
case VK_FORMAT_R8_UINT: return createDFDUnpacked(0, 1, 1, 0, s_UINT);
case VK_FORMAT_R8_SINT: return createDFDUnpacked(0, 1, 1, 0, s_SINT);
case VK_FORMAT_R8_SRGB: return createDFDUnpacked(0, 1, 1, 0, s_SRGB);
case VK_FORMAT_R8G8_UNORM: return createDFDUnpacked(0, 2, 1, 0, s_UNORM);
case VK_FORMAT_R8G8_SNORM: return createDFDUnpacked(0, 2, 1, 0, s_SNORM);
case VK_FORMAT_R8G8_USCALED: return createDFDUnpacked(0, 2, 1, 0, s_USCALED);
case VK_FORMAT_R8G8_SSCALED: return createDFDUnpacked(0, 2, 1, 0, s_SSCALED);
case VK_FORMAT_R8G8_UINT: return createDFDUnpacked(0, 2, 1, 0, s_UINT);
case VK_FORMAT_R8G8_SINT: return createDFDUnpacked(0, 2, 1, 0, s_SINT);
case VK_FORMAT_R8G8_SRGB: return createDFDUnpacked(0, 2, 1, 0, s_SRGB);
case VK_FORMAT_R8G8B8_UNORM: return createDFDUnpacked(0, 3, 1, 0, s_UNORM);
case VK_FORMAT_R8G8B8_SNORM: return createDFDUnpacked(0, 3, 1, 0, s_SNORM);
case VK_FORMAT_R8G8B8_USCALED: return createDFDUnpacked(0, 3, 1, 0, s_USCALED);
case VK_FORMAT_R8G8B8_SSCALED: return createDFDUnpacked(0, 3, 1, 0, s_SSCALED);
case VK_FORMAT_R8G8B8_UINT: return createDFDUnpacked(0, 3, 1, 0, s_UINT);
case VK_FORMAT_R8G8B8_SINT: return createDFDUnpacked(0, 3, 1, 0, s_SINT);
case VK_FORMAT_R8G8B8_SRGB: return createDFDUnpacked(0, 3, 1, 0, s_SRGB);
case VK_FORMAT_B8G8R8_UNORM: return createDFDUnpacked(0, 3, 1, 1, s_UNORM);
case VK_FORMAT_B8G8R8_SNORM: return createDFDUnpacked(0, 3, 1, 1, s_SNORM);
case VK_FORMAT_B8G8R8_USCALED: return createDFDUnpacked(0, 3, 1, 1, s_USCALED);
case VK_FORMAT_B8G8R8_SSCALED: return createDFDUnpacked(0, 3, 1, 1, s_SSCALED);
case VK_FORMAT_B8G8R8_UINT: return createDFDUnpacked(0, 3, 1, 1, s_UINT);
case VK_FORMAT_B8G8R8_SINT: return createDFDUnpacked(0, 3, 1, 1, s_SINT);
case VK_FORMAT_B8G8R8_SRGB: return createDFDUnpacked(0, 3, 1, 1, s_SRGB);
case VK_FORMAT_R8G8B8A8_UNORM: return createDFDUnpacked(0, 4, 1, 0, s_UNORM);
case VK_FORMAT_R8G8B8A8_SNORM: return createDFDUnpacked(0, 4, 1, 0, s_SNORM);
case VK_FORMAT_R8G8B8A8_USCALED: return createDFDUnpacked(0, 4, 1, 0, s_USCALED);
case VK_FORMAT_R8G8B8A8_SSCALED: return createDFDUnpacked(0, 4, 1, 0, s_SSCALED);
case VK_FORMAT_R8G8B8A8_UINT: return createDFDUnpacked(0, 4, 1, 0, s_UINT);
case VK_FORMAT_R8G8B8A8_SINT: return createDFDUnpacked(0, 4, 1, 0, s_SINT);
case VK_FORMAT_R8G8B8A8_SRGB: return createDFDUnpacked(0, 4, 1, 0, s_SRGB);
case VK_FORMAT_B8G8R8A8_UNORM: return createDFDUnpacked(0, 4, 1, 1, s_UNORM);
case VK_FORMAT_B8G8R8A8_SNORM: return createDFDUnpacked(0, 4, 1, 1, s_SNORM);
case VK_FORMAT_B8G8R8A8_USCALED: return createDFDUnpacked(0, 4, 1, 1, s_USCALED);
case VK_FORMAT_B8G8R8A8_SSCALED: return createDFDUnpacked(0, 4, 1, 1, s_SSCALED);
case VK_FORMAT_B8G8R8A8_UINT: return createDFDUnpacked(0, 4, 1, 1, s_UINT);
case VK_FORMAT_B8G8R8A8_SINT: return createDFDUnpacked(0, 4, 1, 1, s_SINT);
case VK_FORMAT_B8G8R8A8_SRGB: return createDFDUnpacked(0, 4, 1, 1, s_SRGB);
case VK_FORMAT_A8B8G8R8_UNORM_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {8,8,8,8};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_A8B8G8R8_SNORM_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {8,8,8,8};
return createDFDPacked(0, 4, bits, channels, s_SNORM);
}
case VK_FORMAT_A8B8G8R8_USCALED_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {8,8,8,8};
return createDFDPacked(0, 4, bits, channels, s_USCALED);
}
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {8,8,8,8};
return createDFDPacked(0, 4, bits, channels, s_SSCALED);
}
case VK_FORMAT_A8B8G8R8_UINT_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {8,8,8,8};
return createDFDPacked(0, 4, bits, channels, s_UINT);
}
case VK_FORMAT_A8B8G8R8_SINT_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {8,8,8,8};
return createDFDPacked(0, 4, bits, channels, s_SINT);
}
case VK_FORMAT_A8B8G8R8_SRGB_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {8,8,8,8};
return createDFDPacked(0, 4, bits, channels, s_SRGB);
}
case VK_FORMAT_A2R10G10B10_UNORM_PACK32: {
int channels[] = {2,1,0,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_A2R10G10B10_SNORM_PACK32: {
int channels[] = {2,1,0,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_SNORM);
}
case VK_FORMAT_A2R10G10B10_USCALED_PACK32: {
int channels[] = {2,1,0,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_USCALED);
}
case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: {
int channels[] = {2,1,0,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_SSCALED);
}
case VK_FORMAT_A2R10G10B10_UINT_PACK32: {
int channels[] = {2,1,0,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_UINT);
}
case VK_FORMAT_A2R10G10B10_SINT_PACK32: {
int channels[] = {2,1,0,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_SINT);
}
case VK_FORMAT_A2B10G10R10_UNORM_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_A2B10G10R10_SNORM_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_SNORM);
}
case VK_FORMAT_A2B10G10R10_USCALED_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_USCALED);
}
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_SSCALED);
}
case VK_FORMAT_A2B10G10R10_UINT_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_UINT);
}
case VK_FORMAT_A2B10G10R10_SINT_PACK32: {
int channels[] = {0,1,2,3}; int bits[] = {10,10,10,2};
return createDFDPacked(0, 4, bits, channels, s_SINT);
}
case VK_FORMAT_R16_UNORM: return createDFDUnpacked(0, 1, 2, 0, s_UNORM);
case VK_FORMAT_R16_SNORM: return createDFDUnpacked(0, 1, 2, 0, s_SNORM);
case VK_FORMAT_R16_USCALED: return createDFDUnpacked(0, 1, 2, 0, s_USCALED);
case VK_FORMAT_R16_SSCALED: return createDFDUnpacked(0, 1, 2, 0, s_SSCALED);
case VK_FORMAT_R16_UINT: return createDFDUnpacked(0, 1, 2, 0, s_UINT);
case VK_FORMAT_R16_SINT: return createDFDUnpacked(0, 1, 2, 0, s_SINT);
case VK_FORMAT_R16_SFLOAT: return createDFDUnpacked(0, 1, 2, 0, s_SFLOAT);
case VK_FORMAT_R16G16_UNORM: return createDFDUnpacked(0, 2, 2, 0, s_UNORM);
case VK_FORMAT_R16G16_SNORM: return createDFDUnpacked(0, 2, 2, 0, s_SNORM);
case VK_FORMAT_R16G16_USCALED: return createDFDUnpacked(0, 2, 2, 0, s_USCALED);
case VK_FORMAT_R16G16_SSCALED: return createDFDUnpacked(0, 2, 2, 0, s_SSCALED);
case VK_FORMAT_R16G16_UINT: return createDFDUnpacked(0, 2, 2, 0, s_UINT);
case VK_FORMAT_R16G16_SINT: return createDFDUnpacked(0, 2, 2, 0, s_SINT);
case VK_FORMAT_R16G16_SFLOAT: return createDFDUnpacked(0, 2, 2, 0, s_SFLOAT);
case VK_FORMAT_R16G16B16_UNORM: return createDFDUnpacked(0, 3, 2, 0, s_UNORM);
case VK_FORMAT_R16G16B16_SNORM: return createDFDUnpacked(0, 3, 2, 0, s_SNORM);
case VK_FORMAT_R16G16B16_USCALED: return createDFDUnpacked(0, 3, 2, 0, s_USCALED);
case VK_FORMAT_R16G16B16_SSCALED: return createDFDUnpacked(0, 3, 2, 0, s_SSCALED);
case VK_FORMAT_R16G16B16_UINT: return createDFDUnpacked(0, 3, 2, 0, s_UINT);
case VK_FORMAT_R16G16B16_SINT: return createDFDUnpacked(0, 3, 2, 0, s_SINT);
case VK_FORMAT_R16G16B16_SFLOAT: return createDFDUnpacked(0, 3, 2, 0, s_SFLOAT);
case VK_FORMAT_R16G16B16A16_UNORM: return createDFDUnpacked(0, 4, 2, 0, s_UNORM);
case VK_FORMAT_R16G16B16A16_SNORM: return createDFDUnpacked(0, 4, 2, 0, s_SNORM);
case VK_FORMAT_R16G16B16A16_USCALED: return createDFDUnpacked(0, 4, 2, 0, s_USCALED);
case VK_FORMAT_R16G16B16A16_SSCALED: return createDFDUnpacked(0, 4, 2, 0, s_SSCALED);
case VK_FORMAT_R16G16B16A16_UINT: return createDFDUnpacked(0, 4, 2, 0, s_UINT);
case VK_FORMAT_R16G16B16A16_SINT: return createDFDUnpacked(0, 4, 2, 0, s_SINT);
case VK_FORMAT_R16G16B16A16_SFLOAT: return createDFDUnpacked(0, 4, 2, 0, s_SFLOAT);
case VK_FORMAT_R32_UINT: return createDFDUnpacked(0, 1, 4, 0, s_UINT);
case VK_FORMAT_R32_SINT: return createDFDUnpacked(0, 1, 4, 0, s_SINT);
case VK_FORMAT_R32_SFLOAT: return createDFDUnpacked(0, 1, 4, 0, s_SFLOAT);
case VK_FORMAT_R32G32_UINT: return createDFDUnpacked(0, 2, 4, 0, s_UINT);
case VK_FORMAT_R32G32_SINT: return createDFDUnpacked(0, 2, 4, 0, s_SINT);
case VK_FORMAT_R32G32_SFLOAT: return createDFDUnpacked(0, 2, 4, 0, s_SFLOAT);
case VK_FORMAT_R32G32B32_UINT: return createDFDUnpacked(0, 3, 4, 0, s_UINT);
case VK_FORMAT_R32G32B32_SINT: return createDFDUnpacked(0, 3, 4, 0, s_SINT);
case VK_FORMAT_R32G32B32_SFLOAT: return createDFDUnpacked(0, 3, 4, 0, s_SFLOAT);
case VK_FORMAT_R32G32B32A32_UINT: return createDFDUnpacked(0, 4, 4, 0, s_UINT);
case VK_FORMAT_R32G32B32A32_SINT: return createDFDUnpacked(0, 4, 4, 0, s_SINT);
case VK_FORMAT_R32G32B32A32_SFLOAT: return createDFDUnpacked(0, 4, 4, 0, s_SFLOAT);
case VK_FORMAT_R64_UINT: return createDFDUnpacked(0, 1, 8, 0, s_UINT);
case VK_FORMAT_R64_SINT: return createDFDUnpacked(0, 1, 8, 0, s_SINT);
case VK_FORMAT_R64_SFLOAT: return createDFDUnpacked(0, 1, 8, 0, s_SFLOAT);
case VK_FORMAT_R64G64_UINT: return createDFDUnpacked(0, 2, 8, 0, s_UINT);
case VK_FORMAT_R64G64_SINT: return createDFDUnpacked(0, 2, 8, 0, s_SINT);
case VK_FORMAT_R64G64_SFLOAT: return createDFDUnpacked(0, 2, 8, 0, s_SFLOAT);
case VK_FORMAT_R64G64B64_UINT: return createDFDUnpacked(0, 3, 8, 0, s_UINT);
case VK_FORMAT_R64G64B64_SINT: return createDFDUnpacked(0, 3, 8, 0, s_SINT);
case VK_FORMAT_R64G64B64_SFLOAT: return createDFDUnpacked(0, 3, 8, 0, s_SFLOAT);
case VK_FORMAT_R64G64B64A64_UINT: return createDFDUnpacked(0, 4, 8, 0, s_UINT);
case VK_FORMAT_R64G64B64A64_SINT: return createDFDUnpacked(0, 4, 8, 0, s_SINT);
case VK_FORMAT_R64G64B64A64_SFLOAT: return createDFDUnpacked(0, 4, 8, 0, s_SFLOAT);
case VK_FORMAT_B10G11R11_UFLOAT_PACK32: {
int channels[] = {0,1,2}; int bits[] = {11,11,10};
return createDFDPacked(0, 3, bits, channels, s_UFLOAT);
}
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: {
int bits[] = {0}; int channels[] = {0};
return createDFDPacked(0, 6, bits, channels, s_UFLOAT);
}
case VK_FORMAT_D16_UNORM: return createDFDDepthStencil(16,0,2);
case VK_FORMAT_X8_D24_UNORM_PACK32: return createDFDDepthStencil(24,0,4);
case VK_FORMAT_D32_SFLOAT: return createDFDDepthStencil(32,0,4);
case VK_FORMAT_S8_UINT: return createDFDDepthStencil(0,8,1);
case VK_FORMAT_D16_UNORM_S8_UINT: return createDFDDepthStencil(16,8,4);
case VK_FORMAT_D24_UNORM_S8_UINT: return createDFDDepthStencil(24,8,4);
case VK_FORMAT_D32_SFLOAT_S8_UINT: return createDFDDepthStencil(32,8,8);
case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_UNORM);
case VK_FORMAT_BC1_RGB_SRGB_BLOCK: return createDFDCompressed(c_BC1_RGB, 4, 4, 1, s_SRGB);
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return createDFDCompressed(c_BC1_RGBA, 4, 4, 1, s_UNORM);
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: return createDFDCompressed(c_BC1_RGBA, 4, 4, 1, s_SRGB);
case VK_FORMAT_BC2_UNORM_BLOCK: return createDFDCompressed(c_BC2, 4, 4, 1, s_UNORM);
case VK_FORMAT_BC2_SRGB_BLOCK: return createDFDCompressed(c_BC2, 4, 4, 1, s_SRGB);
case VK_FORMAT_BC3_UNORM_BLOCK: return createDFDCompressed(c_BC3, 4, 4, 1, s_UNORM);
case VK_FORMAT_BC3_SRGB_BLOCK: return createDFDCompressed(c_BC3, 4, 4, 1, s_SRGB);
case VK_FORMAT_BC4_UNORM_BLOCK: return createDFDCompressed(c_BC4, 4, 4, 1, s_UNORM);
case VK_FORMAT_BC4_SNORM_BLOCK: return createDFDCompressed(c_BC4, 4, 4, 1, s_SNORM);
case VK_FORMAT_BC5_UNORM_BLOCK: return createDFDCompressed(c_BC5, 4, 4, 1, s_UNORM);
case VK_FORMAT_BC5_SNORM_BLOCK: return createDFDCompressed(c_BC5, 4, 4, 1, s_SNORM);
case VK_FORMAT_BC6H_UFLOAT_BLOCK: return createDFDCompressed(c_BC6H, 4, 4, 1, s_UFLOAT);
case VK_FORMAT_BC6H_SFLOAT_BLOCK: return createDFDCompressed(c_BC6H, 4, 4, 1, s_SFLOAT);
case VK_FORMAT_BC7_UNORM_BLOCK: return createDFDCompressed(c_BC7, 4, 4, 1, s_UNORM);
case VK_FORMAT_BC7_SRGB_BLOCK: return createDFDCompressed(c_BC7, 4, 4, 1, s_SRGB);
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return createDFDCompressed(c_ETC2_R8G8B8, 4, 4, 1, s_UNORM);
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: return createDFDCompressed(c_ETC2_R8G8B8, 4, 4, 1, s_SRGB);
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: return createDFDCompressed(c_ETC2_R8G8B8A1, 4, 4, 1, s_UNORM);
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: return createDFDCompressed(c_ETC2_R8G8B8A1, 4, 4, 1, s_SRGB);
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: return createDFDCompressed(c_ETC2_R8G8B8A8, 4, 4, 1, s_UNORM);
case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: return createDFDCompressed(c_ETC2_R8G8B8A8, 4, 4, 1, s_SRGB);
case VK_FORMAT_EAC_R11_UNORM_BLOCK: return createDFDCompressed(c_EAC_R11, 4, 4, 1, s_UNORM);
case VK_FORMAT_EAC_R11_SNORM_BLOCK: return createDFDCompressed(c_EAC_R11, 4, 4, 1, s_SNORM);
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: return createDFDCompressed(c_EAC_R11G11, 4, 4, 1, s_UNORM);
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: return createDFDCompressed(c_EAC_R11G11, 4, 4, 1, s_SNORM);
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 4, 4, 1, s_UNORM);
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 4, 4, 1, s_SRGB);
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 5, 4, 1, s_UNORM);
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 5, 4, 1, s_SRGB);
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 5, 5, 1, s_UNORM);
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 5, 5, 1, s_SRGB);
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 6, 5, 1, s_UNORM);
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 6, 5, 1, s_SRGB);
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 6, 6, 1, s_UNORM);
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 6, 6, 1, s_SRGB);
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 8, 5, 1, s_UNORM);
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 8, 5, 1, s_SRGB);
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 8, 6, 1, s_UNORM);
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 8, 6, 1, s_SRGB);
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 8, 8, 1, s_UNORM);
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 8, 8, 1, s_SRGB);
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 10, 5, 1, s_UNORM);
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 10, 5, 1, s_SRGB);
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 10, 6, 1, s_UNORM);
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 10, 6, 1, s_SRGB);
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 10, 8, 1, s_UNORM);
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 10, 8, 1, s_SRGB);
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 10, 10, 1, s_UNORM);
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 10, 10, 1, s_SRGB);
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 12, 10, 1, s_UNORM);
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 12, 10, 1, s_SRGB);
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_UNORM);
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_SRGB);
case VK_FORMAT_G8B8G8R8_422_UNORM: {
int channels[] = {0, 1, 0, 2}; int bits[] = {8, 8, 8, 8}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B8G8R8G8_422_UNORM: {
int channels[] = {1, 0, 2, 0}; int bits[] = {8, 8, 8, 8}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_R10X6_UNORM_PACK16: {
int channels[] = {0}; int bits[] = {10}; int shiftBits[] = {6};
return createDFDPackedShifted(0, 1, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: {
int channels[] = {0, 1}; int bits[] = {10, 10}; int shiftBits[] = {6, 6};
return createDFDPackedShifted(0, 2, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: {
int channels[] = {0, 1, 2, 3}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};
return createDFDPackedShifted(0, 4, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: {
int channels[] = {0, 1, 0, 2}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: {
int channels[] = {1, 0, 2, 0}; int bits[] = {10, 10, 10, 10}; int shiftBits[] = {6, 6, 6, 6};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_R12X4_UNORM_PACK16: {
int channels[] = {0}; int bits[] = {12}; int shiftBits[] = {4};
return createDFDPackedShifted(0, 1, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: {
int channels[] = {0, 1}; int bits[] = {12, 12}; int shiftBits[] = {4, 4};
return createDFDPackedShifted(0, 2, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: {
int channels[] = {0, 1, 2, 3}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};
return createDFDPackedShifted(0, 4, bits, shiftBits, channels, s_UNORM);
}
case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: {
int channels[] = {0, 1, 0, 2}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: {
int channels[] = {1, 0, 2, 0}; int bits[] = {12, 12, 12, 12}; int shiftBits[] = {4, 4, 4, 4};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_G16B16G16R16_422_UNORM: {
int channels[] = {0, 1, 0, 2}; int bits[] = {16, 16, 16, 16}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 192, 64}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_B16G16R16G16_422_UNORM: {
int channels[] = {1, 0, 2, 0}; int bits[] = {16, 16, 16, 16}; int shiftBits[] = {0, 0, 0, 0};
int position_xs[] = {64, 64, 64, 192}; int position_ys[] = {128, 128, 128, 128};
return createDFD422(0, 4, bits, shiftBits, channels, position_xs, position_ys, s_UNORM);
}
case VK_FORMAT_A4R4G4B4_UNORM_PACK16: {
int channels[] = {2,1,0,3}; int bits[] = {4,4,4,4};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_A4B4G4R4_UNORM_PACK16: {
int channels[] = {0,1,2,3}; int bits[] = {4,4,4,4};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 4, 4, 1, s_SFLOAT);
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 5, 4, 1, s_SFLOAT);
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 5, 5, 1, s_SFLOAT);
case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 6, 5, 1, s_SFLOAT);
case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 6, 6, 1, s_SFLOAT);
case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 8, 5, 1, s_SFLOAT);
case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 8, 6, 1, s_SFLOAT);
case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 8, 8, 1, s_SFLOAT);
case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 5, 1, s_SFLOAT);
case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 6, 1, s_SFLOAT);
case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 8, 1, s_SFLOAT);
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 10, 10, 1, s_SFLOAT);
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 12, 10, 1, s_SFLOAT);
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK: return createDFDCompressed(c_ASTC, 12, 12, 1, s_SFLOAT);
case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 8, 4, 1, s_UNORM);
case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 4, 4, 1, s_UNORM);
case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 8, 4, 1, s_UNORM);
case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 4, 4, 1, s_UNORM);
case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 8, 4, 1, s_SRGB);
case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 4, 4, 1, s_SRGB);
case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 8, 4, 1, s_SRGB);
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 4, 4, 1, s_SRGB);
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_UNORM);
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_SRGB);
case VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 3, 3, 3, s_SFLOAT);
case VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 3, 3, s_UNORM);
case VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 3, 3, s_SRGB);
case VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 3, 3, s_SFLOAT);
case VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 4, 3, s_UNORM);
case VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 4, 3, s_SRGB);
case VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 4, 3, s_SFLOAT);
case VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 4, 4, s_UNORM);
case VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 4, 4, s_SRGB);
case VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 4, 4, 4, s_SFLOAT);
case VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 4, 4, s_UNORM);
case VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 4, 4, s_SRGB);
case VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 4, 4, s_SFLOAT);
case VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 5, 4, s_UNORM);
case VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 5, 4, s_SRGB);
case VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 5, 4, s_SFLOAT);
case VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 5, 5, s_UNORM);
case VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 5, 5, s_SRGB);
case VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 5, 5, 5, s_SFLOAT);
case VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 5, 5, s_UNORM);
case VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 5, 5, s_SRGB);
case VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 5, 5, s_SFLOAT);
case VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 5, s_UNORM);
case VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 5, s_SRGB);
case VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 5, s_SFLOAT);
case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_UNORM);
case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SRGB);
case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SFLOAT);
case VK_FORMAT_R16G16_SFIXED5_NV: return createDFDUnpacked(0, 2, 2, 0, s_SFIXED5);
case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR: {
int channels[] = {0,1,2,3}; int bits[] = {5,5,5,1};
return createDFDPacked(0, 4, bits, channels, s_UNORM);
}
case VK_FORMAT_A8_UNORM_KHR: return createDFDAlpha(0, 1, s_UNORM);
+16
View File
@@ -0,0 +1,16 @@
<!-- Copyright 2023 The Khronos Group Inc. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
# Why Vulkan Header Files Here?
The `vulkan_core.h` included here is custom generated from the Vulkan
Registry's `vk.xml` in order to include the format enumerators for the
ASTC 3d formats. We need to support these formats because there are OpenGL implementations even though, as yet, there are no Vulkan implementations.
See `./build_custom_vulkan_core` for instructions on generating the file.
`vulkan_core.h` is used to generate the switch bodies `dfd2vk.inl` and `vk2dfd.inl`.
## To Do
Generate the switch bodies from `vk.xml` instead.
+64
View File
@@ -0,0 +1,64 @@
#!/bin/sh -e
# Copyright 2023 The Khronos Group Inc.
# SPDX-License-Identifier: Apache-2.0
# Build vulkan_core.h to be included with dfdutils. It is the standard
# vulkan_core.h with the unreleased VK_EXT_texture_compression_ASTC_3d
# extension force included and VK_KHR_video_decode_h264 and
# VK_KHR_video_decode_h265 removed due to their including other large
# header files.
# You need python3 installed to use this script. You also need
# the pyparsing module. Install with `pip install pyparsing`.
# Note that genvk.py explicitly calls for /usr/bin/python3. If you are
# on macOS, the only way to get this is to install the Xcode command
# line tools. If this is not possible, use Docker.
# If you do not have python but have Docker and the Vulkan docker image
# installed you can do the work with that but you will have to manually
# run the command and copy the resulting file here.
#
function usage() {
echo "$0 <path>"
echo "Path to vulkan directory in your clone of the Khronos GitLab vulkan"
echo "repo or path to your clone of the GitHub KhronosGroup/Vulkan-Docs"
echo "repo. GitLab is the preferred source."
}
if [ "$1" = "-h" -o "$1" = "--help" ]; then
usage
exit 0
fi
if [ $# -ne 1 ]; then
echo "Need path."
usage
exit 2
fi
# Generated file goes in same directory as this script.
dst=$(dirname $0)
if [ ! "${dst:0:1}" = "/" ]; then
dst="$(pwd)/$dst"
fi
cd $1
scripts/genvk.py -extension VK_EXT_extension_289 -removeExtensions '(VK_KHR_video_decode_av1|VK_KHR_video_decode_h264|VK_KHR_video_encode_h264|VK_KHR_video_decode_h265|VK_KHR_video_encode_h265)' -registry xml/vk.xml -o $dst vulkan_core.h
# To use with Docker
# 1. Install Docker
# 2. In a terminal
# $ cd <your clone of the GitLab vulkan repo>
# $ scripts/runDocker
# 3. At the prompt in the shell started by Docker
# $ <paste the above scripts/genvk command with $dst replaced with '.'>
# $ ^d # to exit the Docker shell.
# 4. Back at the prompt in no. 2
# $ mv vulkan_core.h <path to your dfdutils repo clone/vulkan/
# $ cd <path to your dfdutils repo>
# The pasting and copying steps are needed because programs cannot reach
# outside docker to the host file system.
+84
View File
@@ -0,0 +1,84 @@
//
// File: vk_platform.h
//
/*
** Copyright 2014-2023 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
#ifndef VK_PLATFORM_H_
#define VK_PLATFORM_H_
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/
/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
// On Windows, Vulkan commands use the stdcall convention
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan is not supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
// is true even if the rest of the application passes floats on the stack,
// as it does by default when compiling for the armeabi-v7a NDK ABI.
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
// On other platforms, use the default calling convention
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif
#if !defined(VK_NO_STDDEF_H)
#include <stddef.h>
#endif // !defined(VK_NO_STDDEF_H)
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined(VK_NO_STDINT_H)
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif
File diff suppressed because it is too large Load Diff