1 /* Copyright (c) 2015-2016 The Khronos Group Inc.
2  * Copyright (c) 2015-2016 Valve Corporation
3  * Copyright (c) 2015-2016 LunarG, Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * Author: Mark Lobodzinski <mark@lunarg.com>
18  * Author: Dave Houlton <daveh@lunarg.com>
19  *
20  */
21 
22 #include <string.h>
23 #include <string>
24 #include <vector>
25 #include <map>
26 #include "vulkan/vulkan.h"
27 #include "vk_format_utils.h"
28 
29 struct VULKAN_FORMAT_INFO {
30     size_t size;
31     uint32_t channel_count;
32     VkFormatCompatibilityClass format_class;
33 };
34 
35 // Disable auto-formatting for this large table
36 // clang-format off
37 
38 // Set up data structure with number of bytes and number of channels for each Vulkan format
39 const std::map<VkFormat, VULKAN_FORMAT_INFO> vk_format_table = {
40     {VK_FORMAT_UNDEFINED,                   {0, 0, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT }},
41     {VK_FORMAT_R4G4_UNORM_PACK8,            {1, 2, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
42     {VK_FORMAT_R4G4B4A4_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
43     {VK_FORMAT_B4G4R4A4_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
44     {VK_FORMAT_R5G6B5_UNORM_PACK16,         {2, 3, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
45     {VK_FORMAT_B5G6R5_UNORM_PACK16,         {2, 3, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
46     {VK_FORMAT_R5G5B5A1_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
47     {VK_FORMAT_B5G5R5A1_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
48     {VK_FORMAT_A1R5G5B5_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
49     {VK_FORMAT_R8_UNORM,                    {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
50     {VK_FORMAT_R8_SNORM,                    {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
51     {VK_FORMAT_R8_USCALED,                  {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
52     {VK_FORMAT_R8_SSCALED,                  {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
53     {VK_FORMAT_R8_UINT,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
54     {VK_FORMAT_R8_SINT,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
55     {VK_FORMAT_R8_SRGB,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
56     {VK_FORMAT_R8G8_UNORM,                  {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
57     {VK_FORMAT_R8G8_SNORM,                  {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
58     {VK_FORMAT_R8G8_USCALED,                {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
59     {VK_FORMAT_R8G8_SSCALED,                {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
60     {VK_FORMAT_R8G8_UINT,                   {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
61     {VK_FORMAT_R8G8_SINT,                   {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
62     {VK_FORMAT_R8G8_SRGB,                   {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
63     {VK_FORMAT_R8G8B8_UNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
64     {VK_FORMAT_R8G8B8_SNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
65     {VK_FORMAT_R8G8B8_USCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
66     {VK_FORMAT_R8G8B8_SSCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
67     {VK_FORMAT_R8G8B8_UINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
68     {VK_FORMAT_R8G8B8_SINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
69     {VK_FORMAT_R8G8B8_SRGB,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
70     {VK_FORMAT_B8G8R8_UNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
71     {VK_FORMAT_B8G8R8_SNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
72     {VK_FORMAT_B8G8R8_USCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
73     {VK_FORMAT_B8G8R8_SSCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
74     {VK_FORMAT_B8G8R8_UINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
75     {VK_FORMAT_B8G8R8_SINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
76     {VK_FORMAT_B8G8R8_SRGB,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
77     {VK_FORMAT_R8G8B8A8_UNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
78     {VK_FORMAT_R8G8B8A8_SNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
79     {VK_FORMAT_R8G8B8A8_USCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
80     {VK_FORMAT_R8G8B8A8_SSCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
81     {VK_FORMAT_R8G8B8A8_UINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
82     {VK_FORMAT_R8G8B8A8_SINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
83     {VK_FORMAT_R8G8B8A8_SRGB,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
84     {VK_FORMAT_B8G8R8A8_UNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
85     {VK_FORMAT_B8G8R8A8_SNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
86     {VK_FORMAT_B8G8R8A8_USCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
87     {VK_FORMAT_B8G8R8A8_SSCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
88     {VK_FORMAT_B8G8R8A8_UINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
89     {VK_FORMAT_B8G8R8A8_SINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
90     {VK_FORMAT_B8G8R8A8_SRGB,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
91     {VK_FORMAT_A8B8G8R8_UNORM_PACK32,       {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
92     {VK_FORMAT_A8B8G8R8_SNORM_PACK32,       {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
93     {VK_FORMAT_A8B8G8R8_USCALED_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
94     {VK_FORMAT_A8B8G8R8_SSCALED_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
95     {VK_FORMAT_A8B8G8R8_UINT_PACK32,        {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
96     {VK_FORMAT_A8B8G8R8_SINT_PACK32,        {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
97     {VK_FORMAT_A8B8G8R8_SRGB_PACK32,        {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
98     {VK_FORMAT_A2R10G10B10_UNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
99     {VK_FORMAT_A2R10G10B10_SNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
100     {VK_FORMAT_A2R10G10B10_USCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
101     {VK_FORMAT_A2R10G10B10_SSCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
102     {VK_FORMAT_A2R10G10B10_UINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
103     {VK_FORMAT_A2R10G10B10_SINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
104     {VK_FORMAT_A2B10G10R10_UNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
105     {VK_FORMAT_A2B10G10R10_SNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
106     {VK_FORMAT_A2B10G10R10_USCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
107     {VK_FORMAT_A2B10G10R10_SSCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
108     {VK_FORMAT_A2B10G10R10_UINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
109     {VK_FORMAT_A2B10G10R10_SINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
110     {VK_FORMAT_R16_UNORM,                   {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
111     {VK_FORMAT_R16_SNORM,                   {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
112     {VK_FORMAT_R16_USCALED,                 {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
113     {VK_FORMAT_R16_SSCALED,                 {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
114     {VK_FORMAT_R16_UINT,                    {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
115     {VK_FORMAT_R16_SINT,                    {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
116     {VK_FORMAT_R16_SFLOAT,                  {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
117     {VK_FORMAT_R16G16_UNORM,                {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
118     {VK_FORMAT_R16G16_SNORM,                {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
119     {VK_FORMAT_R16G16_USCALED,              {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
120     {VK_FORMAT_R16G16_SSCALED,              {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
121     {VK_FORMAT_R16G16_UINT,                 {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
122     {VK_FORMAT_R16G16_SINT,                 {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
123     {VK_FORMAT_R16G16_SFLOAT,               {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
124     {VK_FORMAT_R16G16B16_UNORM,             {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
125     {VK_FORMAT_R16G16B16_SNORM,             {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
126     {VK_FORMAT_R16G16B16_USCALED,           {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
127     {VK_FORMAT_R16G16B16_SSCALED,           {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
128     {VK_FORMAT_R16G16B16_UINT,              {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
129     {VK_FORMAT_R16G16B16_SINT,              {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
130     {VK_FORMAT_R16G16B16_SFLOAT,            {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
131     {VK_FORMAT_R16G16B16A16_UNORM,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
132     {VK_FORMAT_R16G16B16A16_SNORM,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
133     {VK_FORMAT_R16G16B16A16_USCALED,        {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
134     {VK_FORMAT_R16G16B16A16_SSCALED,        {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
135     {VK_FORMAT_R16G16B16A16_UINT,           {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
136     {VK_FORMAT_R16G16B16A16_SINT,           {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
137     {VK_FORMAT_R16G16B16A16_SFLOAT,         {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
138     {VK_FORMAT_R32_UINT,                    {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
139     {VK_FORMAT_R32_SINT,                    {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
140     {VK_FORMAT_R32_SFLOAT,                  {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
141     {VK_FORMAT_R32G32_UINT,                 {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
142     {VK_FORMAT_R32G32_SINT,                 {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
143     {VK_FORMAT_R32G32_SFLOAT,               {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
144     {VK_FORMAT_R32G32B32_UINT,              {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_96_BIT}},
145     {VK_FORMAT_R32G32B32_SINT,              {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_96_BIT}},
146     {VK_FORMAT_R32G32B32_SFLOAT,            {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_96_BIT}},
147     {VK_FORMAT_R32G32B32A32_UINT,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
148     {VK_FORMAT_R32G32B32A32_SINT,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
149     {VK_FORMAT_R32G32B32A32_SFLOAT,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
150     {VK_FORMAT_R64_UINT,                    {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
151     {VK_FORMAT_R64_SINT,                    {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
152     {VK_FORMAT_R64_SFLOAT,                  {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
153     {VK_FORMAT_R64G64_UINT,                 {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
154     {VK_FORMAT_R64G64_SINT,                 {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
155     {VK_FORMAT_R64G64_SFLOAT,               {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
156     {VK_FORMAT_R64G64B64_UINT,              {24, 3, VK_FORMAT_COMPATIBILITY_CLASS_192_BIT}},
157     {VK_FORMAT_R64G64B64_SINT,              {24, 3, VK_FORMAT_COMPATIBILITY_CLASS_192_BIT}},
158     {VK_FORMAT_R64G64B64_SFLOAT,            {24, 3, VK_FORMAT_COMPATIBILITY_CLASS_192_BIT}},
159     {VK_FORMAT_R64G64B64A64_UINT,           {32, 4, VK_FORMAT_COMPATIBILITY_CLASS_256_BIT}},
160     {VK_FORMAT_R64G64B64A64_SINT,           {32, 4, VK_FORMAT_COMPATIBILITY_CLASS_256_BIT}},
161     {VK_FORMAT_R64G64B64A64_SFLOAT,         {32, 4, VK_FORMAT_COMPATIBILITY_CLASS_256_BIT}},
162     {VK_FORMAT_B10G11R11_UFLOAT_PACK32,     {4, 3, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
163     {VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,      {4, 3, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
164     {VK_FORMAT_D16_UNORM,                   {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
165     {VK_FORMAT_X8_D24_UNORM_PACK32,         {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
166     {VK_FORMAT_D32_SFLOAT,                  {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
167     {VK_FORMAT_S8_UINT,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
168     {VK_FORMAT_D16_UNORM_S8_UINT,           {3, 2, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
169     {VK_FORMAT_D24_UNORM_S8_UINT,           {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
170     {VK_FORMAT_D32_SFLOAT_S8_UINT,          {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
171     {VK_FORMAT_BC1_RGB_UNORM_BLOCK,         {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGB_BIT}},
172     {VK_FORMAT_BC1_RGB_SRGB_BLOCK,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGB_BIT}},
173     {VK_FORMAT_BC1_RGBA_UNORM_BLOCK,        {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGBA_BIT}},
174     {VK_FORMAT_BC1_RGBA_SRGB_BLOCK,         {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGBA_BIT}},
175     {VK_FORMAT_BC2_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC2_BIT}},
176     {VK_FORMAT_BC2_SRGB_BLOCK,              {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC2_BIT}},
177     {VK_FORMAT_BC3_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC3_BIT}},
178     {VK_FORMAT_BC3_SRGB_BLOCK,              {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC3_BIT}},
179     {VK_FORMAT_BC4_UNORM_BLOCK,             {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC4_BIT}},
180     {VK_FORMAT_BC4_SNORM_BLOCK,             {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC4_BIT}},
181     {VK_FORMAT_BC5_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC5_BIT}},
182     {VK_FORMAT_BC5_SNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC5_BIT}},
183     {VK_FORMAT_BC6H_UFLOAT_BLOCK,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC6H_BIT}},
184     {VK_FORMAT_BC6H_SFLOAT_BLOCK,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC6H_BIT}},
185     {VK_FORMAT_BC7_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC7_BIT}},
186     {VK_FORMAT_BC7_SRGB_BLOCK,              {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC7_BIT}},
187     {VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,     {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGB_BIT}},
188     {VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,      {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGB_BIT}},
189     {VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,   {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGBA_BIT}},
190     {VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,    {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGBA_BIT}},
191     {VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,   {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_EAC_RGBA_BIT}},
192     {VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,    {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_EAC_RGBA_BIT}},
193     {VK_FORMAT_EAC_R11_UNORM_BLOCK,         {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_EAC_R_BIT}},
194     {VK_FORMAT_EAC_R11_SNORM_BLOCK,         {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_EAC_R_BIT}},
195     {VK_FORMAT_EAC_R11G11_UNORM_BLOCK,      {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_EAC_RG_BIT}},
196     {VK_FORMAT_EAC_R11G11_SNORM_BLOCK,      {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_EAC_RG_BIT}},
197     {VK_FORMAT_ASTC_4x4_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_4X4_BIT}},
198     {VK_FORMAT_ASTC_4x4_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_4X4_BIT}},
199     {VK_FORMAT_ASTC_5x4_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X4_BIT}},
200     {VK_FORMAT_ASTC_5x4_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X4_BIT}},
201     {VK_FORMAT_ASTC_5x5_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X5_BIT}},
202     {VK_FORMAT_ASTC_5x5_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X5_BIT}},
203     {VK_FORMAT_ASTC_6x5_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X5_BIT}},
204     {VK_FORMAT_ASTC_6x5_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X5_BIT}},
205     {VK_FORMAT_ASTC_6x6_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X6_BIT}},
206     {VK_FORMAT_ASTC_6x6_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X6_BIT}},
207     {VK_FORMAT_ASTC_8x5_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X5_BIT}},
208     {VK_FORMAT_ASTC_8x5_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X5_BIT}},
209     {VK_FORMAT_ASTC_8x6_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X6_BIT}},
210     {VK_FORMAT_ASTC_8x6_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X6_BIT}},
211     {VK_FORMAT_ASTC_8x8_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X8_BIT}},
212     {VK_FORMAT_ASTC_8x8_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X8_BIT}},
213     {VK_FORMAT_ASTC_10x5_UNORM_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X5_BIT}},
214     {VK_FORMAT_ASTC_10x5_SRGB_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X5_BIT}},
215     {VK_FORMAT_ASTC_10x6_UNORM_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X6_BIT}},
216     {VK_FORMAT_ASTC_10x6_SRGB_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X6_BIT}},
217     {VK_FORMAT_ASTC_10x8_UNORM_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X8_BIT}},
218     {VK_FORMAT_ASTC_10x8_SRGB_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X8_BIT}},
219     {VK_FORMAT_ASTC_10x10_UNORM_BLOCK,      {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X10_BIT}},
220     {VK_FORMAT_ASTC_10x10_SRGB_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X10_BIT}},
221     {VK_FORMAT_ASTC_12x10_UNORM_BLOCK,      {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X10_BIT}},
222     {VK_FORMAT_ASTC_12x10_SRGB_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X10_BIT}},
223     {VK_FORMAT_ASTC_12x12_UNORM_BLOCK,      {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X12_BIT}},
224     {VK_FORMAT_ASTC_12x12_SRGB_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X12_BIT}},
225     {VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_2BPP_BIT}},
226     {VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_4BPP_BIT}},
227     {VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_2BPP_BIT}},
228     {VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_4BPP_BIT}},
229     {VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_2BPP_BIT}},
230     {VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_4BPP_BIT}},
231     {VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_2BPP_BIT}},
232     {VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_4BPP_BIT}}
233 };
234 
235 // Renable formatting
236 // clang-format on
237 
238 // Return true if format is an ETC2 or EAC compressed texture format
239 VK_LAYER_EXPORT bool FormatIsCompressed_ETC2_EAC(VkFormat format) {
240     bool found = false;
241 
242     switch (format) {
243         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
244         case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
245         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
246         case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
247         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
248         case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
249         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
250         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
251         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
252         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
253             found = true;
254             break;
255         default:
256             break;
257     }
258     return found;
259 }
260 
261 // Return true if format is an ASTC compressed texture format
262 VK_LAYER_EXPORT bool FormatIsCompressed_ASTC_LDR(VkFormat format) {
263     bool found = false;
264 
265     switch (format) {
266         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
267         case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
268         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
269         case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
270         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
271         case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
272         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
273         case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
274         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
275         case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
276         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
277         case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
278         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
279         case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
280         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
281         case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
282         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
283         case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
284         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
285         case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
286         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
287         case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
288         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
289         case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
290         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
291         case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
292         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
293         case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
294             found = true;
295             break;
296         default:
297             break;
298     }
299     return found;
300 }
301 
302 // Return true if format is a BC compressed texture format
303 VK_LAYER_EXPORT bool FormatIsCompressed_BC(VkFormat format) {
304     bool found = false;
305 
306     switch (format) {
307         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
308         case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
309         case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
310         case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
311         case VK_FORMAT_BC2_UNORM_BLOCK:
312         case VK_FORMAT_BC2_SRGB_BLOCK:
313         case VK_FORMAT_BC3_UNORM_BLOCK:
314         case VK_FORMAT_BC3_SRGB_BLOCK:
315         case VK_FORMAT_BC4_UNORM_BLOCK:
316         case VK_FORMAT_BC4_SNORM_BLOCK:
317         case VK_FORMAT_BC5_UNORM_BLOCK:
318         case VK_FORMAT_BC5_SNORM_BLOCK:
319         case VK_FORMAT_BC6H_UFLOAT_BLOCK:
320         case VK_FORMAT_BC6H_SFLOAT_BLOCK:
321         case VK_FORMAT_BC7_UNORM_BLOCK:
322         case VK_FORMAT_BC7_SRGB_BLOCK:
323             found = true;
324             break;
325         default:
326             break;
327     }
328     return found;
329 }
330 
331 // Return true if format is a PVRTC compressed texture format
332 VK_LAYER_EXPORT bool FormatIsCompressed_PVRTC(VkFormat format) {
333     bool found = false;
334 
335     switch (format) {
336         case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
337         case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
338         case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
339         case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
340         case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
341         case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
342         case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
343         case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
344             found = true;
345             break;
346         default:
347             break;
348     }
349     return found;
350 }
351 
352 // Return true if format is compressed
353 VK_LAYER_EXPORT bool FormatIsCompressed(VkFormat format) {
354     return (FormatIsCompressed_ASTC_LDR(format) || FormatIsCompressed_BC(format) || FormatIsCompressed_ETC2_EAC(format) ||
355             FormatIsCompressed_PVRTC(format));
356 }
357 
358 // Return true if format is a depth or stencil format
359 VK_LAYER_EXPORT bool FormatIsDepthOrStencil(VkFormat format) {
360     return (FormatIsDepthAndStencil(format) || FormatIsDepthOnly(format) || FormatIsStencilOnly(format));
361 }
362 
363 // Return true if format contains depth and stencil information
364 VK_LAYER_EXPORT bool FormatIsDepthAndStencil(VkFormat format) {
365     bool is_ds = false;
366 
367     switch (format) {
368         case VK_FORMAT_D16_UNORM_S8_UINT:
369         case VK_FORMAT_D24_UNORM_S8_UINT:
370         case VK_FORMAT_D32_SFLOAT_S8_UINT:
371             is_ds = true;
372             break;
373         default:
374             break;
375     }
376     return is_ds;
377 }
378 
379 // Return true if format is a stencil-only format
380 VK_LAYER_EXPORT bool FormatIsStencilOnly(VkFormat format) { return (format == VK_FORMAT_S8_UINT); }
381 
382 // Return true if format is a depth-only format
383 VK_LAYER_EXPORT bool FormatIsDepthOnly(VkFormat format) {
384     bool is_depth = false;
385 
386     switch (format) {
387         case VK_FORMAT_D16_UNORM:
388         case VK_FORMAT_X8_D24_UNORM_PACK32:
389         case VK_FORMAT_D32_SFLOAT:
390             is_depth = true;
391             break;
392         default:
393             break;
394     }
395 
396     return is_depth;
397 }
398 
399 // Return true if format is of type NORM
400 VK_LAYER_EXPORT bool FormatIsNorm(VkFormat format) {
401     bool is_norm = false;
402 
403     switch (format) {
404         case VK_FORMAT_R4G4_UNORM_PACK8:
405         case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
406         case VK_FORMAT_R5G6B5_UNORM_PACK16:
407         case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
408         case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
409         case VK_FORMAT_R8_UNORM:
410         case VK_FORMAT_R8_SNORM:
411         case VK_FORMAT_R8G8_UNORM:
412         case VK_FORMAT_R8G8_SNORM:
413         case VK_FORMAT_R8G8B8_UNORM:
414         case VK_FORMAT_R8G8B8_SNORM:
415         case VK_FORMAT_R8G8B8A8_UNORM:
416         case VK_FORMAT_R8G8B8A8_SNORM:
417         case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
418         case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
419         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
420         case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
421         case VK_FORMAT_R16_UNORM:
422         case VK_FORMAT_R16_SNORM:
423         case VK_FORMAT_R16G16_UNORM:
424         case VK_FORMAT_R16G16_SNORM:
425         case VK_FORMAT_R16G16B16_UNORM:
426         case VK_FORMAT_R16G16B16_SNORM:
427         case VK_FORMAT_R16G16B16A16_UNORM:
428         case VK_FORMAT_R16G16B16A16_SNORM:
429         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
430         case VK_FORMAT_BC2_UNORM_BLOCK:
431         case VK_FORMAT_BC3_UNORM_BLOCK:
432         case VK_FORMAT_BC4_UNORM_BLOCK:
433         case VK_FORMAT_BC4_SNORM_BLOCK:
434         case VK_FORMAT_BC5_UNORM_BLOCK:
435         case VK_FORMAT_BC5_SNORM_BLOCK:
436         case VK_FORMAT_BC7_UNORM_BLOCK:
437         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
438         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
439         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
440         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
441         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
442         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
443         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
444         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
445         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
446         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
447         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
448         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
449         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
450         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
451         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
452         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
453         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
454         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
455         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
456         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
457         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
458         case VK_FORMAT_B5G6R5_UNORM_PACK16:
459         case VK_FORMAT_B8G8R8_UNORM:
460         case VK_FORMAT_B8G8R8_SNORM:
461         case VK_FORMAT_B8G8R8A8_UNORM:
462         case VK_FORMAT_B8G8R8A8_SNORM:
463         case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
464         case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
465             is_norm = true;
466             break;
467         default:
468             break;
469     }
470 
471     return is_norm;
472 }
473 
474 // Return true if format is of type UNORM
475 VK_LAYER_EXPORT bool FormatIsUNorm(VkFormat format) {
476     bool is_unorm = false;
477 
478     switch (format) {
479         case VK_FORMAT_R4G4_UNORM_PACK8:
480         case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
481         case VK_FORMAT_R5G6B5_UNORM_PACK16:
482         case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
483         case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
484         case VK_FORMAT_R8_UNORM:
485         case VK_FORMAT_R8G8_UNORM:
486         case VK_FORMAT_R8G8B8_UNORM:
487         case VK_FORMAT_R8G8B8A8_UNORM:
488         case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
489         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
490         case VK_FORMAT_R16_UNORM:
491         case VK_FORMAT_R16G16_UNORM:
492         case VK_FORMAT_R16G16B16_UNORM:
493         case VK_FORMAT_R16G16B16A16_UNORM:
494         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
495         case VK_FORMAT_BC2_UNORM_BLOCK:
496         case VK_FORMAT_BC3_UNORM_BLOCK:
497         case VK_FORMAT_BC4_UNORM_BLOCK:
498         case VK_FORMAT_BC5_UNORM_BLOCK:
499         case VK_FORMAT_BC7_UNORM_BLOCK:
500         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
501         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
502         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
503         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
504         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
505         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
506         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
507         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
508         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
509         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
510         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
511         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
512         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
513         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
514         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
515         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
516         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
517         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
518         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
519         case VK_FORMAT_B5G6R5_UNORM_PACK16:
520         case VK_FORMAT_B8G8R8_UNORM:
521         case VK_FORMAT_B8G8R8A8_UNORM:
522         case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
523             is_unorm = true;
524             break;
525         default:
526             break;
527     }
528 
529     return is_unorm;
530 }
531 
532 // Return true if format is of type SNORM
533 VK_LAYER_EXPORT bool FormatIsSNorm(VkFormat format) {
534     bool is_snorm = false;
535 
536     switch (format) {
537         case VK_FORMAT_R8_SNORM:
538         case VK_FORMAT_R8G8_SNORM:
539         case VK_FORMAT_R8G8B8_SNORM:
540         case VK_FORMAT_R8G8B8A8_SNORM:
541         case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
542         case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
543         case VK_FORMAT_R16_SNORM:
544         case VK_FORMAT_R16G16_SNORM:
545         case VK_FORMAT_R16G16B16_SNORM:
546         case VK_FORMAT_R16G16B16A16_SNORM:
547         case VK_FORMAT_BC4_SNORM_BLOCK:
548         case VK_FORMAT_BC5_SNORM_BLOCK:
549         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
550         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
551         case VK_FORMAT_B8G8R8_SNORM:
552         case VK_FORMAT_B8G8R8A8_SNORM:
553         case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
554             is_snorm = true;
555             break;
556         default:
557             break;
558     }
559 
560     return is_snorm;
561 }
562 
563 // Return true if format is an integer format
564 VK_LAYER_EXPORT bool FormatIsInt(VkFormat format) { return (FormatIsSInt(format) || FormatIsUInt(format)); }
565 
566 // Return true if format is an unsigned integer format
567 VK_LAYER_EXPORT bool FormatIsUInt(VkFormat format) {
568     bool is_uint = false;
569 
570     switch (format) {
571         case VK_FORMAT_R8_UINT:
572         case VK_FORMAT_S8_UINT:
573         case VK_FORMAT_R8G8_UINT:
574         case VK_FORMAT_R8G8B8_UINT:
575         case VK_FORMAT_R8G8B8A8_UINT:
576         case VK_FORMAT_A8B8G8R8_UINT_PACK32:
577         case VK_FORMAT_A2B10G10R10_UINT_PACK32:
578         case VK_FORMAT_R16_UINT:
579         case VK_FORMAT_R16G16_UINT:
580         case VK_FORMAT_R16G16B16_UINT:
581         case VK_FORMAT_R16G16B16A16_UINT:
582         case VK_FORMAT_R32_UINT:
583         case VK_FORMAT_R32G32_UINT:
584         case VK_FORMAT_R32G32B32_UINT:
585         case VK_FORMAT_R32G32B32A32_UINT:
586         case VK_FORMAT_R64_UINT:
587         case VK_FORMAT_R64G64_UINT:
588         case VK_FORMAT_R64G64B64_UINT:
589         case VK_FORMAT_R64G64B64A64_UINT:
590         case VK_FORMAT_B8G8R8_UINT:
591         case VK_FORMAT_B8G8R8A8_UINT:
592         case VK_FORMAT_A2R10G10B10_UINT_PACK32:
593             is_uint = true;
594             break;
595         default:
596             break;
597     }
598 
599     return is_uint;
600 }
601 
602 // Return true if format is a signed integer format
603 VK_LAYER_EXPORT bool FormatIsSInt(VkFormat format) {
604     bool is_sint = false;
605 
606     switch (format) {
607         case VK_FORMAT_R8_SINT:
608         case VK_FORMAT_R8G8_SINT:
609         case VK_FORMAT_R8G8B8_SINT:
610         case VK_FORMAT_R8G8B8A8_SINT:
611         case VK_FORMAT_A8B8G8R8_SINT_PACK32:
612         case VK_FORMAT_A2B10G10R10_SINT_PACK32:
613         case VK_FORMAT_R16_SINT:
614         case VK_FORMAT_R16G16_SINT:
615         case VK_FORMAT_R16G16B16_SINT:
616         case VK_FORMAT_R16G16B16A16_SINT:
617         case VK_FORMAT_R32_SINT:
618         case VK_FORMAT_R32G32_SINT:
619         case VK_FORMAT_R32G32B32_SINT:
620         case VK_FORMAT_R32G32B32A32_SINT:
621         case VK_FORMAT_R64_SINT:
622         case VK_FORMAT_R64G64_SINT:
623         case VK_FORMAT_R64G64B64_SINT:
624         case VK_FORMAT_R64G64B64A64_SINT:
625         case VK_FORMAT_B8G8R8_SINT:
626         case VK_FORMAT_B8G8R8A8_SINT:
627         case VK_FORMAT_A2R10G10B10_SINT_PACK32:
628             is_sint = true;
629             break;
630         default:
631             break;
632     }
633 
634     return is_sint;
635 }
636 
637 // Return true if format is a floating-point format
638 VK_LAYER_EXPORT bool FormatIsFloat(VkFormat format) {
639     bool is_float = false;
640 
641     switch (format) {
642         case VK_FORMAT_R16_SFLOAT:
643         case VK_FORMAT_R16G16_SFLOAT:
644         case VK_FORMAT_R16G16B16_SFLOAT:
645         case VK_FORMAT_R16G16B16A16_SFLOAT:
646         case VK_FORMAT_R32_SFLOAT:
647         case VK_FORMAT_R32G32_SFLOAT:
648         case VK_FORMAT_R32G32B32_SFLOAT:
649         case VK_FORMAT_R32G32B32A32_SFLOAT:
650         case VK_FORMAT_R64_SFLOAT:
651         case VK_FORMAT_R64G64_SFLOAT:
652         case VK_FORMAT_R64G64B64_SFLOAT:
653         case VK_FORMAT_R64G64B64A64_SFLOAT:
654         case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
655         case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
656         case VK_FORMAT_BC6H_UFLOAT_BLOCK:
657         case VK_FORMAT_BC6H_SFLOAT_BLOCK:
658             is_float = true;
659             break;
660         default:
661             break;
662     }
663 
664     return is_float;
665 }
666 
667 // Return true if format is in the SRGB colorspace
668 VK_LAYER_EXPORT bool FormatIsSRGB(VkFormat format) {
669     bool is_srgb = false;
670 
671     switch (format) {
672         case VK_FORMAT_R8_SRGB:
673         case VK_FORMAT_R8G8_SRGB:
674         case VK_FORMAT_R8G8B8_SRGB:
675         case VK_FORMAT_R8G8B8A8_SRGB:
676         case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
677         case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
678         case VK_FORMAT_BC2_SRGB_BLOCK:
679         case VK_FORMAT_BC3_SRGB_BLOCK:
680         case VK_FORMAT_BC7_SRGB_BLOCK:
681         case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
682         case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
683         case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
684         case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
685         case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
686         case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
687         case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
688         case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
689         case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
690         case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
691         case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
692         case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
693         case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
694         case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
695         case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
696         case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
697         case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
698         case VK_FORMAT_B8G8R8_SRGB:
699         case VK_FORMAT_B8G8R8A8_SRGB:
700             is_srgb = true;
701             break;
702         default:
703             break;
704     }
705 
706     return is_srgb;
707 }
708 
709 // Return true if format is a USCALED format
710 VK_LAYER_EXPORT bool FormatIsUScaled(VkFormat format) {
711     bool is_uscaled = false;
712 
713     switch (format) {
714         case VK_FORMAT_R8_USCALED:
715         case VK_FORMAT_R8G8_USCALED:
716         case VK_FORMAT_R8G8B8_USCALED:
717         case VK_FORMAT_B8G8R8_USCALED:
718         case VK_FORMAT_R8G8B8A8_USCALED:
719         case VK_FORMAT_B8G8R8A8_USCALED:
720         case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
721         case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
722         case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
723         case VK_FORMAT_R16_USCALED:
724         case VK_FORMAT_R16G16_USCALED:
725         case VK_FORMAT_R16G16B16_USCALED:
726         case VK_FORMAT_R16G16B16A16_USCALED:
727             is_uscaled = true;
728             break;
729         default:
730             break;
731     }
732 
733     return is_uscaled;
734 }
735 
736 // Return true if format is a SSCALED format
737 VK_LAYER_EXPORT bool FormatIsSScaled(VkFormat format) {
738     bool is_sscaled = false;
739 
740     switch (format) {
741         case VK_FORMAT_R8_SSCALED:
742         case VK_FORMAT_R8G8_SSCALED:
743         case VK_FORMAT_R8G8B8_SSCALED:
744         case VK_FORMAT_B8G8R8_SSCALED:
745         case VK_FORMAT_R8G8B8A8_SSCALED:
746         case VK_FORMAT_B8G8R8A8_SSCALED:
747         case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
748         case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
749         case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
750         case VK_FORMAT_R16_SSCALED:
751         case VK_FORMAT_R16G16_SSCALED:
752         case VK_FORMAT_R16G16B16_SSCALED:
753         case VK_FORMAT_R16G16B16A16_SSCALED:
754             is_sscaled = true;
755             break;
756         default:
757             break;
758     }
759 
760     return is_sscaled;
761 }
762 
763 // Return compressed texel block sizes for block compressed formats
764 VK_LAYER_EXPORT VkExtent3D FormatCompressedTexelBlockExtent(VkFormat format) {
765     VkExtent3D block_size = {1, 1, 1};
766     switch (format) {
767         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
768         case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
769         case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
770         case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
771         case VK_FORMAT_BC2_UNORM_BLOCK:
772         case VK_FORMAT_BC2_SRGB_BLOCK:
773         case VK_FORMAT_BC3_UNORM_BLOCK:
774         case VK_FORMAT_BC3_SRGB_BLOCK:
775         case VK_FORMAT_BC4_UNORM_BLOCK:
776         case VK_FORMAT_BC4_SNORM_BLOCK:
777         case VK_FORMAT_BC5_UNORM_BLOCK:
778         case VK_FORMAT_BC5_SNORM_BLOCK:
779         case VK_FORMAT_BC6H_UFLOAT_BLOCK:
780         case VK_FORMAT_BC6H_SFLOAT_BLOCK:
781         case VK_FORMAT_BC7_UNORM_BLOCK:
782         case VK_FORMAT_BC7_SRGB_BLOCK:
783         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
784         case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
785         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
786         case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
787         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
788         case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
789         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
790         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
791         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
792         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
793         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
794         case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
795             block_size = {4, 4, 1};
796             break;
797         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
798         case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
799             block_size = {5, 4, 1};
800             break;
801         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
802         case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
803             block_size = {5, 5, 1};
804             break;
805         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
806         case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
807             block_size = {6, 5, 1};
808             break;
809         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
810         case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
811             block_size = {6, 6, 1};
812             break;
813         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
814         case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
815             block_size = {8, 5, 1};
816             break;
817         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
818         case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
819             block_size = {8, 6, 1};
820             break;
821         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
822         case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
823             block_size = {8, 8, 1};
824             break;
825         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
826         case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
827             block_size = {10, 5, 1};
828             break;
829         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
830         case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
831             block_size = {10, 6, 1};
832             break;
833         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
834         case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
835             block_size = {10, 8, 1};
836             break;
837         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
838         case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
839             block_size = {10, 10, 1};
840             break;
841         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
842         case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
843             block_size = {12, 10, 1};
844             break;
845         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
846         case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
847             block_size = {12, 12, 1};
848             break;
849         case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
850         case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
851         case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
852         case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
853             block_size = {8, 4, 1};
854             break;
855         case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
856         case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
857         case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
858         case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
859             block_size = {4, 4, 1};
860             break;
861         default:
862             break;
863     }
864     return block_size;
865 }
866 
867 VK_LAYER_EXPORT uint32_t FormatPlaneCount(VkFormat format) {
868     switch (format) {
869         case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
870         case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
871         case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
872         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
873         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
874         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
875         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
876         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
877         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
878         case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
879         case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
880         case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
881             return 3u;
882             break;
883         case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
884         case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
885         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
886         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
887         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
888         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
889         case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
890         case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
891             return 2u;
892             break;
893         default:
894             return 1u;
895             break;
896     }
897 }
898 
899 // Return format class of the specified format
900 VK_LAYER_EXPORT VkFormatCompatibilityClass FormatCompatibilityClass(VkFormat format) {
901     auto item = vk_format_table.find(format);
902     if (item != vk_format_table.end()) {
903         return item->second.format_class;
904     }
905     return VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT;
906 }
907 
908 // Return size, in bytes, of a pixel of the specified format
909 VK_LAYER_EXPORT size_t FormatSize(VkFormat format) {
910     auto item = vk_format_table.find(format);
911     if (item != vk_format_table.end()) {
912         return item->second.size;
913     }
914     return 0;
915 }
916 
917 // Return the number of channels for a given format
918 uint32_t FormatChannelCount(VkFormat format) {
919     auto item = vk_format_table.find(format);
920     if (item != vk_format_table.end()) {
921         return item->second.channel_count;
922     }
923     return 0;
924 }
925 
926 // Perform a zero-tolerant modulo operation
927 VK_LAYER_EXPORT VkDeviceSize SafeModulo(VkDeviceSize dividend, VkDeviceSize divisor) {
928     VkDeviceSize result = 0;
929     if (divisor != 0) {
930         result = dividend % divisor;
931     }
932     return result;
933 }
934