• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2015-2019 The Khronos Group Inc.
2  * Copyright (c) 2015-2019 Valve Corporation
3  * Copyright (c) 2015-2019 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     uint32_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 size(bytes) and number of channels for each Vulkan format
39 // For compressed and multi-plane formats, size is bytes per compressed or shared block
40 const std::map<VkFormat, VULKAN_FORMAT_INFO> vk_format_table = {
41     {VK_FORMAT_UNDEFINED,                   {0, 0, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT }},
42     {VK_FORMAT_R4G4_UNORM_PACK8,            {1, 2, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
43     {VK_FORMAT_R4G4B4A4_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
44     {VK_FORMAT_B4G4R4A4_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
45     {VK_FORMAT_R5G6B5_UNORM_PACK16,         {2, 3, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
46     {VK_FORMAT_B5G6R5_UNORM_PACK16,         {2, 3, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
47     {VK_FORMAT_R5G5B5A1_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
48     {VK_FORMAT_B5G5R5A1_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
49     {VK_FORMAT_A1R5G5B5_UNORM_PACK16,       {2, 4, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
50     {VK_FORMAT_R8_UNORM,                    {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
51     {VK_FORMAT_R8_SNORM,                    {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
52     {VK_FORMAT_R8_USCALED,                  {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
53     {VK_FORMAT_R8_SSCALED,                  {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
54     {VK_FORMAT_R8_UINT,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
55     {VK_FORMAT_R8_SINT,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
56     {VK_FORMAT_R8_SRGB,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_8_BIT}},
57     {VK_FORMAT_R8G8_UNORM,                  {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
58     {VK_FORMAT_R8G8_SNORM,                  {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
59     {VK_FORMAT_R8G8_USCALED,                {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
60     {VK_FORMAT_R8G8_SSCALED,                {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
61     {VK_FORMAT_R8G8_UINT,                   {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
62     {VK_FORMAT_R8G8_SINT,                   {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
63     {VK_FORMAT_R8G8_SRGB,                   {2, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
64     {VK_FORMAT_R8G8B8_UNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
65     {VK_FORMAT_R8G8B8_SNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
66     {VK_FORMAT_R8G8B8_USCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
67     {VK_FORMAT_R8G8B8_SSCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
68     {VK_FORMAT_R8G8B8_UINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
69     {VK_FORMAT_R8G8B8_SINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
70     {VK_FORMAT_R8G8B8_SRGB,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
71     {VK_FORMAT_B8G8R8_UNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
72     {VK_FORMAT_B8G8R8_SNORM,                {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
73     {VK_FORMAT_B8G8R8_USCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
74     {VK_FORMAT_B8G8R8_SSCALED,              {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
75     {VK_FORMAT_B8G8R8_UINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
76     {VK_FORMAT_B8G8R8_SINT,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
77     {VK_FORMAT_B8G8R8_SRGB,                 {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_24_BIT}},
78     {VK_FORMAT_R8G8B8A8_UNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
79     {VK_FORMAT_R8G8B8A8_SNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
80     {VK_FORMAT_R8G8B8A8_USCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
81     {VK_FORMAT_R8G8B8A8_SSCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
82     {VK_FORMAT_R8G8B8A8_UINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
83     {VK_FORMAT_R8G8B8A8_SINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
84     {VK_FORMAT_R8G8B8A8_SRGB,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
85     {VK_FORMAT_B8G8R8A8_UNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
86     {VK_FORMAT_B8G8R8A8_SNORM,              {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
87     {VK_FORMAT_B8G8R8A8_USCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
88     {VK_FORMAT_B8G8R8A8_SSCALED,            {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
89     {VK_FORMAT_B8G8R8A8_UINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
90     {VK_FORMAT_B8G8R8A8_SINT,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
91     {VK_FORMAT_B8G8R8A8_SRGB,               {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
92     {VK_FORMAT_A8B8G8R8_UNORM_PACK32,       {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
93     {VK_FORMAT_A8B8G8R8_SNORM_PACK32,       {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
94     {VK_FORMAT_A8B8G8R8_USCALED_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
95     {VK_FORMAT_A8B8G8R8_SSCALED_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
96     {VK_FORMAT_A8B8G8R8_UINT_PACK32,        {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
97     {VK_FORMAT_A8B8G8R8_SINT_PACK32,        {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
98     {VK_FORMAT_A8B8G8R8_SRGB_PACK32,        {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
99     {VK_FORMAT_A2R10G10B10_UNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
100     {VK_FORMAT_A2R10G10B10_SNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
101     {VK_FORMAT_A2R10G10B10_USCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
102     {VK_FORMAT_A2R10G10B10_SSCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
103     {VK_FORMAT_A2R10G10B10_UINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
104     {VK_FORMAT_A2R10G10B10_SINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
105     {VK_FORMAT_A2B10G10R10_UNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
106     {VK_FORMAT_A2B10G10R10_SNORM_PACK32,    {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
107     {VK_FORMAT_A2B10G10R10_USCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
108     {VK_FORMAT_A2B10G10R10_SSCALED_PACK32,  {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
109     {VK_FORMAT_A2B10G10R10_UINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
110     {VK_FORMAT_A2B10G10R10_SINT_PACK32,     {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
111     {VK_FORMAT_R16_UNORM,                   {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
112     {VK_FORMAT_R16_SNORM,                   {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
113     {VK_FORMAT_R16_USCALED,                 {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
114     {VK_FORMAT_R16_SSCALED,                 {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
115     {VK_FORMAT_R16_UINT,                    {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
116     {VK_FORMAT_R16_SINT,                    {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
117     {VK_FORMAT_R16_SFLOAT,                  {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
118     {VK_FORMAT_R16G16_UNORM,                {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
119     {VK_FORMAT_R16G16_SNORM,                {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
120     {VK_FORMAT_R16G16_USCALED,              {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
121     {VK_FORMAT_R16G16_SSCALED,              {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
122     {VK_FORMAT_R16G16_UINT,                 {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
123     {VK_FORMAT_R16G16_SINT,                 {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
124     {VK_FORMAT_R16G16_SFLOAT,               {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
125     {VK_FORMAT_R16G16B16_UNORM,             {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
126     {VK_FORMAT_R16G16B16_SNORM,             {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
127     {VK_FORMAT_R16G16B16_USCALED,           {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
128     {VK_FORMAT_R16G16B16_SSCALED,           {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
129     {VK_FORMAT_R16G16B16_UINT,              {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
130     {VK_FORMAT_R16G16B16_SINT,              {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
131     {VK_FORMAT_R16G16B16_SFLOAT,            {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_48_BIT}},
132     {VK_FORMAT_R16G16B16A16_UNORM,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
133     {VK_FORMAT_R16G16B16A16_SNORM,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
134     {VK_FORMAT_R16G16B16A16_USCALED,        {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
135     {VK_FORMAT_R16G16B16A16_SSCALED,        {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
136     {VK_FORMAT_R16G16B16A16_UINT,           {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
137     {VK_FORMAT_R16G16B16A16_SINT,           {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
138     {VK_FORMAT_R16G16B16A16_SFLOAT,         {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
139     {VK_FORMAT_R32_UINT,                    {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
140     {VK_FORMAT_R32_SINT,                    {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
141     {VK_FORMAT_R32_SFLOAT,                  {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
142     {VK_FORMAT_R32G32_UINT,                 {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
143     {VK_FORMAT_R32G32_SINT,                 {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
144     {VK_FORMAT_R32G32_SFLOAT,               {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
145     {VK_FORMAT_R32G32B32_UINT,              {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_96_BIT}},
146     {VK_FORMAT_R32G32B32_SINT,              {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_96_BIT}},
147     {VK_FORMAT_R32G32B32_SFLOAT,            {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_96_BIT}},
148     {VK_FORMAT_R32G32B32A32_UINT,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
149     {VK_FORMAT_R32G32B32A32_SINT,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
150     {VK_FORMAT_R32G32B32A32_SFLOAT,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
151     {VK_FORMAT_R64_UINT,                    {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
152     {VK_FORMAT_R64_SINT,                    {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
153     {VK_FORMAT_R64_SFLOAT,                  {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_64_BIT}},
154     {VK_FORMAT_R64G64_UINT,                 {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
155     {VK_FORMAT_R64G64_SINT,                 {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
156     {VK_FORMAT_R64G64_SFLOAT,               {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_128_BIT}},
157     {VK_FORMAT_R64G64B64_UINT,              {24, 3, VK_FORMAT_COMPATIBILITY_CLASS_192_BIT}},
158     {VK_FORMAT_R64G64B64_SINT,              {24, 3, VK_FORMAT_COMPATIBILITY_CLASS_192_BIT}},
159     {VK_FORMAT_R64G64B64_SFLOAT,            {24, 3, VK_FORMAT_COMPATIBILITY_CLASS_192_BIT}},
160     {VK_FORMAT_R64G64B64A64_UINT,           {32, 4, VK_FORMAT_COMPATIBILITY_CLASS_256_BIT}},
161     {VK_FORMAT_R64G64B64A64_SINT,           {32, 4, VK_FORMAT_COMPATIBILITY_CLASS_256_BIT}},
162     {VK_FORMAT_R64G64B64A64_SFLOAT,         {32, 4, VK_FORMAT_COMPATIBILITY_CLASS_256_BIT}},
163     {VK_FORMAT_B10G11R11_UFLOAT_PACK32,     {4, 3, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
164     {VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,      {4, 3, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
165     {VK_FORMAT_D16_UNORM,                   {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
166     {VK_FORMAT_X8_D24_UNORM_PACK32,         {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
167     {VK_FORMAT_D32_SFLOAT,                  {4, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
168     {VK_FORMAT_S8_UINT,                     {1, 1, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
169     {VK_FORMAT_D16_UNORM_S8_UINT,           {3, 2, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
170     {VK_FORMAT_D24_UNORM_S8_UINT,           {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
171     {VK_FORMAT_D32_SFLOAT_S8_UINT,          {8, 2, VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT}},
172     {VK_FORMAT_BC1_RGB_UNORM_BLOCK,         {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGB_BIT}},
173     {VK_FORMAT_BC1_RGB_SRGB_BLOCK,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGB_BIT}},
174     {VK_FORMAT_BC1_RGBA_UNORM_BLOCK,        {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGBA_BIT}},
175     {VK_FORMAT_BC1_RGBA_SRGB_BLOCK,         {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC1_RGBA_BIT}},
176     {VK_FORMAT_BC2_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC2_BIT}},
177     {VK_FORMAT_BC2_SRGB_BLOCK,              {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC2_BIT}},
178     {VK_FORMAT_BC3_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC3_BIT}},
179     {VK_FORMAT_BC3_SRGB_BLOCK,              {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC3_BIT}},
180     {VK_FORMAT_BC4_UNORM_BLOCK,             {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC4_BIT}},
181     {VK_FORMAT_BC4_SNORM_BLOCK,             {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC4_BIT}},
182     {VK_FORMAT_BC5_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC5_BIT}},
183     {VK_FORMAT_BC5_SNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC5_BIT}},
184     {VK_FORMAT_BC6H_UFLOAT_BLOCK,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC6H_BIT}},
185     {VK_FORMAT_BC6H_SFLOAT_BLOCK,           {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC6H_BIT}},
186     {VK_FORMAT_BC7_UNORM_BLOCK,             {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC7_BIT}},
187     {VK_FORMAT_BC7_SRGB_BLOCK,              {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_BC7_BIT}},
188     {VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,     {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGB_BIT}},
189     {VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,      {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGB_BIT}},
190     {VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,   {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGBA_BIT}},
191     {VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,    {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_RGBA_BIT}},
192     {VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,   {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_EAC_RGBA_BIT}},
193     {VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,    {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ETC2_EAC_RGBA_BIT}},
194     {VK_FORMAT_EAC_R11_UNORM_BLOCK,         {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_EAC_R_BIT}},
195     {VK_FORMAT_EAC_R11_SNORM_BLOCK,         {8, 1, VK_FORMAT_COMPATIBILITY_CLASS_EAC_R_BIT}},
196     {VK_FORMAT_EAC_R11G11_UNORM_BLOCK,      {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_EAC_RG_BIT}},
197     {VK_FORMAT_EAC_R11G11_SNORM_BLOCK,      {16, 2, VK_FORMAT_COMPATIBILITY_CLASS_EAC_RG_BIT}},
198     {VK_FORMAT_ASTC_4x4_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_4X4_BIT}},
199     {VK_FORMAT_ASTC_4x4_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_4X4_BIT}},
200     {VK_FORMAT_ASTC_5x4_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X4_BIT}},
201     {VK_FORMAT_ASTC_5x4_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X4_BIT}},
202     {VK_FORMAT_ASTC_5x5_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X5_BIT}},
203     {VK_FORMAT_ASTC_5x5_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_5X5_BIT}},
204     {VK_FORMAT_ASTC_6x5_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X5_BIT}},
205     {VK_FORMAT_ASTC_6x5_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X5_BIT}},
206     {VK_FORMAT_ASTC_6x6_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X6_BIT}},
207     {VK_FORMAT_ASTC_6x6_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_6X6_BIT}},
208     {VK_FORMAT_ASTC_8x5_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X5_BIT}},
209     {VK_FORMAT_ASTC_8x5_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X5_BIT}},
210     {VK_FORMAT_ASTC_8x6_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X6_BIT}},
211     {VK_FORMAT_ASTC_8x6_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X6_BIT}},
212     {VK_FORMAT_ASTC_8x8_UNORM_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X8_BIT}},
213     {VK_FORMAT_ASTC_8x8_SRGB_BLOCK,         {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_8X8_BIT}},
214     {VK_FORMAT_ASTC_10x5_UNORM_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X5_BIT}},
215     {VK_FORMAT_ASTC_10x5_SRGB_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X5_BIT}},
216     {VK_FORMAT_ASTC_10x6_UNORM_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X6_BIT}},
217     {VK_FORMAT_ASTC_10x6_SRGB_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X6_BIT}},
218     {VK_FORMAT_ASTC_10x8_UNORM_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X8_BIT}},
219     {VK_FORMAT_ASTC_10x8_SRGB_BLOCK,        {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X8_BIT}},
220     {VK_FORMAT_ASTC_10x10_UNORM_BLOCK,      {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X10_BIT}},
221     {VK_FORMAT_ASTC_10x10_SRGB_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_10X10_BIT}},
222     {VK_FORMAT_ASTC_12x10_UNORM_BLOCK,      {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X10_BIT}},
223     {VK_FORMAT_ASTC_12x10_SRGB_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X10_BIT}},
224     {VK_FORMAT_ASTC_12x12_UNORM_BLOCK,      {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X12_BIT}},
225     {VK_FORMAT_ASTC_12x12_SRGB_BLOCK,       {16, 4, VK_FORMAT_COMPATIBILITY_CLASS_ASTC_12X12_BIT}},
226     {VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_2BPP_BIT}},
227     {VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_4BPP_BIT}},
228     {VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_2BPP_BIT}},
229     {VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG, {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_4BPP_BIT}},
230     {VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_2BPP_BIT}},
231     {VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC1_4BPP_BIT}},
232     {VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_2BPP_BIT}},
233     {VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG,  {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_PVRTC2_4BPP_BIT}},
234     // KHR_sampler_YCbCr_conversion extension - single-plane variants
235     // 'PACK' formats are normal, uncompressed
236     {VK_FORMAT_R10X6_UNORM_PACK16,                          {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
237     {VK_FORMAT_R10X6G10X6_UNORM_2PACK16,                    {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_32_BIT}},
238     {VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_R10G10B10A10}},
239     {VK_FORMAT_R12X4_UNORM_PACK16,                          {2, 1, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
240     {VK_FORMAT_R12X4G12X4_UNORM_2PACK16,                    {4, 2, VK_FORMAT_COMPATIBILITY_CLASS_16_BIT}},
241     {VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,          {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_R12G12B12A12}},
242     // _422 formats encode 2 texels per entry with B, R components shared - treated as compressed w/ 2x1 block size
243     {VK_FORMAT_G8B8G8R8_422_UNORM,                          {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32BIT_G8B8G8R8}},
244     {VK_FORMAT_B8G8R8G8_422_UNORM,                          {4, 4, VK_FORMAT_COMPATIBILITY_CLASS_32BIT_B8G8R8G8}},
245     {VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,      {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_G10B10G10R10}},
246     {VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,      {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_B10G10R10G10}},
247     {VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,      {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_G12B12G12R12}},
248     {VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,      {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_B12G12R12G12}},
249     {VK_FORMAT_G16B16G16R16_422_UNORM,                      {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_G16B16G16R16}},
250     {VK_FORMAT_B16G16R16G16_422_UNORM,                      {8, 4, VK_FORMAT_COMPATIBILITY_CLASS_64BIT_B16G16R16G16}},
251     // KHR_sampler_YCbCr_conversion extension - multi-plane variants
252     // Formats that 'share' components among texels (_420 and _422), size represents total bytes for the smallest possible texel block
253     // _420 share B, R components within a 2x2 texel block
254     {VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,                   {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_8BIT_3PLANE_420}},
255     {VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,                    {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_8BIT_2PLANE_420}},
256     {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,  {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_10BIT_3PLANE_420}},
257     {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,   {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_10BIT_2PLANE_420}},
258     {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,  {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_12BIT_3PLANE_420}},
259     {VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,   {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_12BIT_2PLANE_420}},
260     {VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,                {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_16BIT_3PLANE_420}},
261     {VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,                 {12, 3, VK_FORMAT_COMPATIBILITY_CLASS_16BIT_2PLANE_420}},
262     // _422 share B, R components within a 2x1 texel block
263     {VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,                   {4, 3, VK_FORMAT_COMPATIBILITY_CLASS_8BIT_3PLANE_422}},
264     {VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,                    {4, 3, VK_FORMAT_COMPATIBILITY_CLASS_8BIT_2PLANE_422}},
265     {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,  {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_10BIT_3PLANE_422}},
266     {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,   {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_10BIT_2PLANE_422}},
267     {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,  {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_12BIT_3PLANE_422}},
268     {VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,   {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_12BIT_2PLANE_422}},
269     {VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,                {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_16BIT_3PLANE_422}},
270     {VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,                 {8, 3, VK_FORMAT_COMPATIBILITY_CLASS_16BIT_2PLANE_422}},
271     // _444 do not share
272     {VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,                   {3, 3, VK_FORMAT_COMPATIBILITY_CLASS_8BIT_3PLANE_444}},
273     {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,  {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_10BIT_3PLANE_444}},
274     {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,  {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_12BIT_3PLANE_444}},
275     {VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,                {6, 3, VK_FORMAT_COMPATIBILITY_CLASS_16BIT_3PLANE_444}}
276 };
277 
278 // Renable formatting
279 // clang-format on
280 
281 // Return true if format is an ETC2 or EAC compressed texture format
FormatIsCompressed_ETC2_EAC(VkFormat format)282 VK_LAYER_EXPORT bool FormatIsCompressed_ETC2_EAC(VkFormat format) {
283     bool found = false;
284 
285     switch (format) {
286         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
287         case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
288         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
289         case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
290         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
291         case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
292         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
293         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
294         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
295         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
296             found = true;
297             break;
298         default:
299             break;
300     }
301     return found;
302 }
303 
304 // Return true if format is an ASTC compressed texture format
FormatIsCompressed_ASTC_LDR(VkFormat format)305 VK_LAYER_EXPORT bool FormatIsCompressed_ASTC_LDR(VkFormat format) {
306     bool found = false;
307 
308     switch (format) {
309         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
310         case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
311         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
312         case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
313         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
314         case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
315         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
316         case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
317         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
318         case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
319         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
320         case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
321         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
322         case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
323         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
324         case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
325         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
326         case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
327         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
328         case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
329         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
330         case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
331         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
332         case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
333         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
334         case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
335         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
336         case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
337             found = true;
338             break;
339         default:
340             break;
341     }
342     return found;
343 }
344 
345 // Return true if format is a BC compressed texture format
FormatIsCompressed_BC(VkFormat format)346 VK_LAYER_EXPORT bool FormatIsCompressed_BC(VkFormat format) {
347     bool found = false;
348 
349     switch (format) {
350         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
351         case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
352         case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
353         case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
354         case VK_FORMAT_BC2_UNORM_BLOCK:
355         case VK_FORMAT_BC2_SRGB_BLOCK:
356         case VK_FORMAT_BC3_UNORM_BLOCK:
357         case VK_FORMAT_BC3_SRGB_BLOCK:
358         case VK_FORMAT_BC4_UNORM_BLOCK:
359         case VK_FORMAT_BC4_SNORM_BLOCK:
360         case VK_FORMAT_BC5_UNORM_BLOCK:
361         case VK_FORMAT_BC5_SNORM_BLOCK:
362         case VK_FORMAT_BC6H_UFLOAT_BLOCK:
363         case VK_FORMAT_BC6H_SFLOAT_BLOCK:
364         case VK_FORMAT_BC7_UNORM_BLOCK:
365         case VK_FORMAT_BC7_SRGB_BLOCK:
366             found = true;
367             break;
368         default:
369             break;
370     }
371     return found;
372 }
373 
374 // Return true if format is a PVRTC compressed texture format
FormatIsCompressed_PVRTC(VkFormat format)375 VK_LAYER_EXPORT bool FormatIsCompressed_PVRTC(VkFormat format) {
376     bool found = false;
377 
378     switch (format) {
379         case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
380         case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
381         case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
382         case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
383         case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
384         case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
385         case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
386         case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
387             found = true;
388             break;
389         default:
390             break;
391     }
392     return found;
393 }
394 
395 // Single-plane "_422" formats are treated as 2x1 compressed (for copies)
FormatIsSinglePlane_422(VkFormat format)396 VK_LAYER_EXPORT bool FormatIsSinglePlane_422(VkFormat format) {
397     bool found = false;
398 
399     switch (format) {
400         case VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
401         case VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
402         case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
403         case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
404         case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
405         case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
406         case VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
407         case VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
408             found = true;
409             break;
410         default:
411             break;
412     }
413     return found;
414 }
415 
416 // Return true if format is compressed
FormatIsCompressed(VkFormat format)417 VK_LAYER_EXPORT bool FormatIsCompressed(VkFormat format) {
418     return (FormatIsCompressed_ASTC_LDR(format) || FormatIsCompressed_BC(format) || FormatIsCompressed_ETC2_EAC(format) ||
419             FormatIsCompressed_PVRTC(format));
420 }
421 // Return true if format is packed
FormatIsPacked(VkFormat format)422 VK_LAYER_EXPORT bool FormatIsPacked(VkFormat format) {
423     bool found = false;
424 
425     switch (format) {
426         case VK_FORMAT_R4G4_UNORM_PACK8:
427         case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
428         case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
429         case VK_FORMAT_R5G6B5_UNORM_PACK16:
430         case VK_FORMAT_B5G6R5_UNORM_PACK16:
431         case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
432         case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
433         case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
434         case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
435         case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
436         case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
437         case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
438         case VK_FORMAT_A8B8G8R8_UINT_PACK32:
439         case VK_FORMAT_A8B8G8R8_SINT_PACK32:
440         case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
441         case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
442         case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
443         case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
444         case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
445         case VK_FORMAT_A2R10G10B10_UINT_PACK32:
446         case VK_FORMAT_A2R10G10B10_SINT_PACK32:
447         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
448         case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
449         case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
450         case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
451         case VK_FORMAT_A2B10G10R10_UINT_PACK32:
452         case VK_FORMAT_A2B10G10R10_SINT_PACK32:
453         case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
454         case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
455         case VK_FORMAT_X8_D24_UNORM_PACK32:
456         case VK_FORMAT_R10X6_UNORM_PACK16:
457         case VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
458         case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
459         case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
460         case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
461         case VK_FORMAT_R12X4_UNORM_PACK16:
462         case VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
463         case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
464         case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
465         case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
466         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
467         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
468         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
469         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
470         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
471         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
472         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
473         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
474         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
475         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
476             found = true;
477             break;
478         default:
479             break;
480     }
481     return found;
482 }
483 
484 // Return true if format is 'normal', with one texel per format element
FormatElementIsTexel(VkFormat format)485 VK_LAYER_EXPORT bool FormatElementIsTexel(VkFormat format) {
486     if (FormatIsPacked(format) || FormatIsCompressed(format) || FormatIsSinglePlane_422(format) || FormatIsMultiplane(format)) {
487         return false;
488     } else {
489         return true;
490     }
491 }
492 
493 // Return true if format is a depth or stencil format
FormatIsDepthOrStencil(VkFormat format)494 VK_LAYER_EXPORT bool FormatIsDepthOrStencil(VkFormat format) {
495     return (FormatIsDepthAndStencil(format) || FormatIsDepthOnly(format) || FormatIsStencilOnly(format));
496 }
497 
498 // Return true if format contains depth and stencil information
FormatIsDepthAndStencil(VkFormat format)499 VK_LAYER_EXPORT bool FormatIsDepthAndStencil(VkFormat format) {
500     bool is_ds = false;
501 
502     switch (format) {
503         case VK_FORMAT_D16_UNORM_S8_UINT:
504         case VK_FORMAT_D24_UNORM_S8_UINT:
505         case VK_FORMAT_D32_SFLOAT_S8_UINT:
506             is_ds = true;
507             break;
508         default:
509             break;
510     }
511     return is_ds;
512 }
513 
514 // Return true if format is a stencil-only format
FormatIsStencilOnly(VkFormat format)515 VK_LAYER_EXPORT bool FormatIsStencilOnly(VkFormat format) { return (format == VK_FORMAT_S8_UINT); }
516 
517 // Return true if format is a depth-only format
FormatIsDepthOnly(VkFormat format)518 VK_LAYER_EXPORT bool FormatIsDepthOnly(VkFormat format) {
519     bool is_depth = false;
520 
521     switch (format) {
522         case VK_FORMAT_D16_UNORM:
523         case VK_FORMAT_X8_D24_UNORM_PACK32:
524         case VK_FORMAT_D32_SFLOAT:
525             is_depth = true;
526             break;
527         default:
528             break;
529     }
530 
531     return is_depth;
532 }
533 
534 // Return true if format is of type NORM
FormatIsNorm(VkFormat format)535 VK_LAYER_EXPORT bool FormatIsNorm(VkFormat format) {
536     bool is_norm = false;
537 
538     switch (format) {
539         case VK_FORMAT_R4G4_UNORM_PACK8:
540         case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
541         case VK_FORMAT_R5G6B5_UNORM_PACK16:
542         case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
543         case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
544         case VK_FORMAT_R8_UNORM:
545         case VK_FORMAT_R8_SNORM:
546         case VK_FORMAT_R8G8_UNORM:
547         case VK_FORMAT_R8G8_SNORM:
548         case VK_FORMAT_R8G8B8_UNORM:
549         case VK_FORMAT_R8G8B8_SNORM:
550         case VK_FORMAT_R8G8B8A8_UNORM:
551         case VK_FORMAT_R8G8B8A8_SNORM:
552         case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
553         case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
554         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
555         case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
556         case VK_FORMAT_R16_UNORM:
557         case VK_FORMAT_R16_SNORM:
558         case VK_FORMAT_R16G16_UNORM:
559         case VK_FORMAT_R16G16_SNORM:
560         case VK_FORMAT_R16G16B16_UNORM:
561         case VK_FORMAT_R16G16B16_SNORM:
562         case VK_FORMAT_R16G16B16A16_UNORM:
563         case VK_FORMAT_R16G16B16A16_SNORM:
564         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
565         case VK_FORMAT_BC2_UNORM_BLOCK:
566         case VK_FORMAT_BC3_UNORM_BLOCK:
567         case VK_FORMAT_BC4_UNORM_BLOCK:
568         case VK_FORMAT_BC4_SNORM_BLOCK:
569         case VK_FORMAT_BC5_UNORM_BLOCK:
570         case VK_FORMAT_BC5_SNORM_BLOCK:
571         case VK_FORMAT_BC7_UNORM_BLOCK:
572         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
573         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
574         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
575         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
576         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
577         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
578         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
579         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
580         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
581         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
582         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
583         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
584         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
585         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
586         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
587         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
588         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
589         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
590         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
591         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
592         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
593         case VK_FORMAT_B5G6R5_UNORM_PACK16:
594         case VK_FORMAT_B8G8R8_UNORM:
595         case VK_FORMAT_B8G8R8_SNORM:
596         case VK_FORMAT_B8G8R8A8_UNORM:
597         case VK_FORMAT_B8G8R8A8_SNORM:
598         case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
599         case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
600             is_norm = true;
601             break;
602         default:
603             break;
604     }
605 
606     return is_norm;
607 }
608 
609 // Return true if format is of type UNORM
FormatIsUNorm(VkFormat format)610 VK_LAYER_EXPORT bool FormatIsUNorm(VkFormat format) {
611     bool is_unorm = false;
612 
613     switch (format) {
614         case VK_FORMAT_R4G4_UNORM_PACK8:
615         case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
616         case VK_FORMAT_R5G6B5_UNORM_PACK16:
617         case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
618         case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
619         case VK_FORMAT_R8_UNORM:
620         case VK_FORMAT_R8G8_UNORM:
621         case VK_FORMAT_R8G8B8_UNORM:
622         case VK_FORMAT_R8G8B8A8_UNORM:
623         case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
624         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
625         case VK_FORMAT_R16_UNORM:
626         case VK_FORMAT_R16G16_UNORM:
627         case VK_FORMAT_R16G16B16_UNORM:
628         case VK_FORMAT_R16G16B16A16_UNORM:
629         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
630         case VK_FORMAT_BC2_UNORM_BLOCK:
631         case VK_FORMAT_BC3_UNORM_BLOCK:
632         case VK_FORMAT_BC4_UNORM_BLOCK:
633         case VK_FORMAT_BC5_UNORM_BLOCK:
634         case VK_FORMAT_BC7_UNORM_BLOCK:
635         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
636         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
637         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
638         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
639         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
640         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
641         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
642         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
643         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
644         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
645         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
646         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
647         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
648         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
649         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
650         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
651         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
652         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
653         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
654         case VK_FORMAT_B5G6R5_UNORM_PACK16:
655         case VK_FORMAT_B8G8R8_UNORM:
656         case VK_FORMAT_B8G8R8A8_UNORM:
657         case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
658             is_unorm = true;
659             break;
660         default:
661             break;
662     }
663 
664     return is_unorm;
665 }
666 
667 // Return true if format is of type SNORM
FormatIsSNorm(VkFormat format)668 VK_LAYER_EXPORT bool FormatIsSNorm(VkFormat format) {
669     bool is_snorm = false;
670 
671     switch (format) {
672         case VK_FORMAT_R8_SNORM:
673         case VK_FORMAT_R8G8_SNORM:
674         case VK_FORMAT_R8G8B8_SNORM:
675         case VK_FORMAT_R8G8B8A8_SNORM:
676         case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
677         case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
678         case VK_FORMAT_R16_SNORM:
679         case VK_FORMAT_R16G16_SNORM:
680         case VK_FORMAT_R16G16B16_SNORM:
681         case VK_FORMAT_R16G16B16A16_SNORM:
682         case VK_FORMAT_BC4_SNORM_BLOCK:
683         case VK_FORMAT_BC5_SNORM_BLOCK:
684         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
685         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
686         case VK_FORMAT_B8G8R8_SNORM:
687         case VK_FORMAT_B8G8R8A8_SNORM:
688         case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
689             is_snorm = true;
690             break;
691         default:
692             break;
693     }
694 
695     return is_snorm;
696 }
697 
698 // Return true if format is an integer format
FormatIsInt(VkFormat format)699 VK_LAYER_EXPORT bool FormatIsInt(VkFormat format) { return (FormatIsSInt(format) || FormatIsUInt(format)); }
700 
701 // Return true if format is an unsigned integer format
FormatIsUInt(VkFormat format)702 VK_LAYER_EXPORT bool FormatIsUInt(VkFormat format) {
703     bool is_uint = false;
704 
705     switch (format) {
706         case VK_FORMAT_R8_UINT:
707         case VK_FORMAT_S8_UINT:
708         case VK_FORMAT_R8G8_UINT:
709         case VK_FORMAT_R8G8B8_UINT:
710         case VK_FORMAT_R8G8B8A8_UINT:
711         case VK_FORMAT_A8B8G8R8_UINT_PACK32:
712         case VK_FORMAT_A2B10G10R10_UINT_PACK32:
713         case VK_FORMAT_R16_UINT:
714         case VK_FORMAT_R16G16_UINT:
715         case VK_FORMAT_R16G16B16_UINT:
716         case VK_FORMAT_R16G16B16A16_UINT:
717         case VK_FORMAT_R32_UINT:
718         case VK_FORMAT_R32G32_UINT:
719         case VK_FORMAT_R32G32B32_UINT:
720         case VK_FORMAT_R32G32B32A32_UINT:
721         case VK_FORMAT_R64_UINT:
722         case VK_FORMAT_R64G64_UINT:
723         case VK_FORMAT_R64G64B64_UINT:
724         case VK_FORMAT_R64G64B64A64_UINT:
725         case VK_FORMAT_B8G8R8_UINT:
726         case VK_FORMAT_B8G8R8A8_UINT:
727         case VK_FORMAT_A2R10G10B10_UINT_PACK32:
728             is_uint = true;
729             break;
730         default:
731             break;
732     }
733 
734     return is_uint;
735 }
736 
737 // Return true if format is a signed integer format
FormatIsSInt(VkFormat format)738 VK_LAYER_EXPORT bool FormatIsSInt(VkFormat format) {
739     bool is_sint = false;
740 
741     switch (format) {
742         case VK_FORMAT_R8_SINT:
743         case VK_FORMAT_R8G8_SINT:
744         case VK_FORMAT_R8G8B8_SINT:
745         case VK_FORMAT_R8G8B8A8_SINT:
746         case VK_FORMAT_A8B8G8R8_SINT_PACK32:
747         case VK_FORMAT_A2B10G10R10_SINT_PACK32:
748         case VK_FORMAT_R16_SINT:
749         case VK_FORMAT_R16G16_SINT:
750         case VK_FORMAT_R16G16B16_SINT:
751         case VK_FORMAT_R16G16B16A16_SINT:
752         case VK_FORMAT_R32_SINT:
753         case VK_FORMAT_R32G32_SINT:
754         case VK_FORMAT_R32G32B32_SINT:
755         case VK_FORMAT_R32G32B32A32_SINT:
756         case VK_FORMAT_R64_SINT:
757         case VK_FORMAT_R64G64_SINT:
758         case VK_FORMAT_R64G64B64_SINT:
759         case VK_FORMAT_R64G64B64A64_SINT:
760         case VK_FORMAT_B8G8R8_SINT:
761         case VK_FORMAT_B8G8R8A8_SINT:
762         case VK_FORMAT_A2R10G10B10_SINT_PACK32:
763             is_sint = true;
764             break;
765         default:
766             break;
767     }
768 
769     return is_sint;
770 }
771 
772 // Return true if format is a floating-point format
FormatIsFloat(VkFormat format)773 VK_LAYER_EXPORT bool FormatIsFloat(VkFormat format) {
774     bool is_float = false;
775 
776     switch (format) {
777         case VK_FORMAT_R16_SFLOAT:
778         case VK_FORMAT_R16G16_SFLOAT:
779         case VK_FORMAT_R16G16B16_SFLOAT:
780         case VK_FORMAT_R16G16B16A16_SFLOAT:
781         case VK_FORMAT_R32_SFLOAT:
782         case VK_FORMAT_R32G32_SFLOAT:
783         case VK_FORMAT_R32G32B32_SFLOAT:
784         case VK_FORMAT_R32G32B32A32_SFLOAT:
785         case VK_FORMAT_R64_SFLOAT:
786         case VK_FORMAT_R64G64_SFLOAT:
787         case VK_FORMAT_R64G64B64_SFLOAT:
788         case VK_FORMAT_R64G64B64A64_SFLOAT:
789         case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
790         case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
791         case VK_FORMAT_BC6H_UFLOAT_BLOCK:
792         case VK_FORMAT_BC6H_SFLOAT_BLOCK:
793             is_float = true;
794             break;
795         default:
796             break;
797     }
798 
799     return is_float;
800 }
801 
802 // Return true if format is in the SRGB colorspace
FormatIsSRGB(VkFormat format)803 VK_LAYER_EXPORT bool FormatIsSRGB(VkFormat format) {
804     bool is_srgb = false;
805 
806     switch (format) {
807         case VK_FORMAT_R8_SRGB:
808         case VK_FORMAT_R8G8_SRGB:
809         case VK_FORMAT_R8G8B8_SRGB:
810         case VK_FORMAT_R8G8B8A8_SRGB:
811         case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
812         case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
813         case VK_FORMAT_BC2_SRGB_BLOCK:
814         case VK_FORMAT_BC3_SRGB_BLOCK:
815         case VK_FORMAT_BC7_SRGB_BLOCK:
816         case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
817         case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
818         case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
819         case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
820         case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
821         case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
822         case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
823         case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
824         case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
825         case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
826         case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
827         case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
828         case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
829         case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
830         case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
831         case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
832         case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
833         case VK_FORMAT_B8G8R8_SRGB:
834         case VK_FORMAT_B8G8R8A8_SRGB:
835             is_srgb = true;
836             break;
837         default:
838             break;
839     }
840 
841     return is_srgb;
842 }
843 
844 // Return true if format is a USCALED format
FormatIsUScaled(VkFormat format)845 VK_LAYER_EXPORT bool FormatIsUScaled(VkFormat format) {
846     bool is_uscaled = false;
847 
848     switch (format) {
849         case VK_FORMAT_R8_USCALED:
850         case VK_FORMAT_R8G8_USCALED:
851         case VK_FORMAT_R8G8B8_USCALED:
852         case VK_FORMAT_B8G8R8_USCALED:
853         case VK_FORMAT_R8G8B8A8_USCALED:
854         case VK_FORMAT_B8G8R8A8_USCALED:
855         case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
856         case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
857         case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
858         case VK_FORMAT_R16_USCALED:
859         case VK_FORMAT_R16G16_USCALED:
860         case VK_FORMAT_R16G16B16_USCALED:
861         case VK_FORMAT_R16G16B16A16_USCALED:
862             is_uscaled = true;
863             break;
864         default:
865             break;
866     }
867 
868     return is_uscaled;
869 }
870 
871 // Return true if format is a SSCALED format
FormatIsSScaled(VkFormat format)872 VK_LAYER_EXPORT bool FormatIsSScaled(VkFormat format) {
873     bool is_sscaled = false;
874 
875     switch (format) {
876         case VK_FORMAT_R8_SSCALED:
877         case VK_FORMAT_R8G8_SSCALED:
878         case VK_FORMAT_R8G8B8_SSCALED:
879         case VK_FORMAT_B8G8R8_SSCALED:
880         case VK_FORMAT_R8G8B8A8_SSCALED:
881         case VK_FORMAT_B8G8R8A8_SSCALED:
882         case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
883         case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
884         case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
885         case VK_FORMAT_R16_SSCALED:
886         case VK_FORMAT_R16G16_SSCALED:
887         case VK_FORMAT_R16G16B16_SSCALED:
888         case VK_FORMAT_R16G16B16A16_SSCALED:
889             is_sscaled = true;
890             break;
891         default:
892             break;
893     }
894 
895     return is_sscaled;
896 }
897 
898 // Return texel block sizes for all formats
899 // Uncompressed formats return {1, 1, 1}
900 // Compressed formats return the compression block extents
901 // Multiplane formats return the 'shared' extent of their low-res channel(s)
FormatTexelBlockExtent(VkFormat format)902 VK_LAYER_EXPORT VkExtent3D FormatTexelBlockExtent(VkFormat format) {
903     VkExtent3D block_size = {1, 1, 1};
904     switch (format) {
905         case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
906         case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
907         case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
908         case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
909         case VK_FORMAT_BC2_UNORM_BLOCK:
910         case VK_FORMAT_BC2_SRGB_BLOCK:
911         case VK_FORMAT_BC3_UNORM_BLOCK:
912         case VK_FORMAT_BC3_SRGB_BLOCK:
913         case VK_FORMAT_BC4_UNORM_BLOCK:
914         case VK_FORMAT_BC4_SNORM_BLOCK:
915         case VK_FORMAT_BC5_UNORM_BLOCK:
916         case VK_FORMAT_BC5_SNORM_BLOCK:
917         case VK_FORMAT_BC6H_UFLOAT_BLOCK:
918         case VK_FORMAT_BC6H_SFLOAT_BLOCK:
919         case VK_FORMAT_BC7_UNORM_BLOCK:
920         case VK_FORMAT_BC7_SRGB_BLOCK:
921         case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
922         case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
923         case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
924         case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
925         case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
926         case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
927         case VK_FORMAT_EAC_R11_UNORM_BLOCK:
928         case VK_FORMAT_EAC_R11_SNORM_BLOCK:
929         case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
930         case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
931         case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
932         case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
933             block_size = {4, 4, 1};
934             break;
935         case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
936         case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
937             block_size = {5, 4, 1};
938             break;
939         case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
940         case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
941             block_size = {5, 5, 1};
942             break;
943         case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
944         case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
945             block_size = {6, 5, 1};
946             break;
947         case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
948         case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
949             block_size = {6, 6, 1};
950             break;
951         case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
952         case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
953             block_size = {8, 5, 1};
954             break;
955         case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
956         case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
957             block_size = {8, 6, 1};
958             break;
959         case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
960         case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
961             block_size = {8, 8, 1};
962             break;
963         case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
964         case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
965             block_size = {10, 5, 1};
966             break;
967         case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
968         case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
969             block_size = {10, 6, 1};
970             break;
971         case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
972         case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
973             block_size = {10, 8, 1};
974             break;
975         case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
976         case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
977             block_size = {10, 10, 1};
978             break;
979         case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
980         case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
981             block_size = {12, 10, 1};
982             break;
983         case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
984         case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
985             block_size = {12, 12, 1};
986             break;
987         case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
988         case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
989         case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
990         case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
991             block_size = {8, 4, 1};
992             break;
993         case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
994         case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
995         case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
996         case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
997             block_size = {4, 4, 1};
998             break;
999         // (KHR_sampler_ycbcr_conversion) _422 single-plane formats are treated as 2x1 compressed (for copies)
1000         case VK_FORMAT_G8B8G8R8_422_UNORM:
1001         case VK_FORMAT_B8G8R8G8_422_UNORM:
1002         case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
1003         case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
1004         case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
1005         case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
1006         case VK_FORMAT_G16B16G16R16_422_UNORM:
1007         case VK_FORMAT_B16G16R16G16_422_UNORM:
1008             block_size = {2, 1, 1};
1009             break;
1010         // _422 multi-plane formats are not considered compressed, but shared components form a logical 2x1 block
1011         case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
1012         case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
1013         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
1014         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
1015         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
1016         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
1017         case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
1018         case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
1019             block_size = {2, 1, 1};
1020             break;
1021         // _420 formats are not considered compressed, but shared components form a logical 2x2 block
1022         case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
1023         case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
1024         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
1025         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
1026         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
1027         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
1028         case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
1029         case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
1030             block_size = {2, 2, 1};
1031             break;
1032         // _444 multi-plane formats do not share components, default to 1x1
1033         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
1034         case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
1035         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
1036         case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
1037         default:
1038             break;
1039     }
1040     return block_size;
1041 }
1042 
FormatDepthSize(VkFormat format)1043 VK_LAYER_EXPORT uint32_t FormatDepthSize(VkFormat format) {
1044     uint32_t depth_size = 0;
1045     switch (format) {
1046         case VK_FORMAT_D16_UNORM:
1047         case VK_FORMAT_D16_UNORM_S8_UINT:
1048             depth_size = 16;
1049             break;
1050         case VK_FORMAT_X8_D24_UNORM_PACK32:
1051         case VK_FORMAT_D24_UNORM_S8_UINT:
1052             depth_size = 24;
1053             break;
1054         case VK_FORMAT_D32_SFLOAT:
1055         case VK_FORMAT_D32_SFLOAT_S8_UINT:
1056             depth_size = 32;
1057             break;
1058 
1059         default:
1060             break;
1061     }
1062     return depth_size;
1063 }
1064 
FormatDepthNumericalType(VkFormat format)1065 VK_LAYER_EXPORT VkFormatNumericalType FormatDepthNumericalType(VkFormat format) {
1066     VkFormatNumericalType numerical_type = VK_FORMAT_NUMERICAL_TYPE_NONE;
1067     switch (format) {
1068         case VK_FORMAT_D16_UNORM:
1069         case VK_FORMAT_D16_UNORM_S8_UINT:
1070         case VK_FORMAT_X8_D24_UNORM_PACK32:
1071         case VK_FORMAT_D24_UNORM_S8_UINT:
1072             numerical_type = VK_FORMAT_NUMERICAL_TYPE_UNORM;
1073             break;
1074         case VK_FORMAT_D32_SFLOAT:
1075         case VK_FORMAT_D32_SFLOAT_S8_UINT:
1076             numerical_type = VK_FORMAT_NUMERICAL_TYPE_SFLOAT;
1077             break;
1078 
1079         default:
1080             break;
1081     }
1082     return numerical_type;
1083 }
1084 
FormatStencilSize(VkFormat format)1085 VK_LAYER_EXPORT uint32_t FormatStencilSize(VkFormat format) {
1086     uint32_t stencil_size = 0;
1087     switch (format) {
1088         case VK_FORMAT_S8_UINT:
1089         case VK_FORMAT_D16_UNORM_S8_UINT:
1090         case VK_FORMAT_D24_UNORM_S8_UINT:
1091         case VK_FORMAT_D32_SFLOAT_S8_UINT:
1092             stencil_size = 8;
1093             break;
1094 
1095         default:
1096             break;
1097     }
1098     return stencil_size;
1099 }
1100 
FormatStencilNumericalType(VkFormat format)1101 VK_LAYER_EXPORT VkFormatNumericalType FormatStencilNumericalType(VkFormat format) {
1102     VkFormatNumericalType numerical_type = VK_FORMAT_NUMERICAL_TYPE_NONE;
1103     switch (format) {
1104         case VK_FORMAT_S8_UINT:
1105         case VK_FORMAT_D16_UNORM_S8_UINT:
1106         case VK_FORMAT_D24_UNORM_S8_UINT:
1107         case VK_FORMAT_D32_SFLOAT_S8_UINT:
1108             numerical_type = VK_FORMAT_NUMERICAL_TYPE_UINT;
1109             break;
1110 
1111         default:
1112             break;
1113     }
1114     return numerical_type;
1115 }
1116 
FormatPlaneCount(VkFormat format)1117 VK_LAYER_EXPORT uint32_t FormatPlaneCount(VkFormat format) {
1118     switch (format) {
1119         case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
1120         case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
1121         case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
1122         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
1123         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
1124         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
1125         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
1126         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
1127         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
1128         case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
1129         case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
1130         case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
1131             return 3;
1132             break;
1133         case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
1134         case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
1135         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
1136         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
1137         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
1138         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
1139         case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
1140         case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
1141             return 2;
1142             break;
1143         default:
1144             return 1;
1145             break;
1146     }
1147 }
1148 
1149 // Return format class of the specified format
FormatCompatibilityClass(VkFormat format)1150 VK_LAYER_EXPORT VkFormatCompatibilityClass FormatCompatibilityClass(VkFormat format) {
1151     auto item = vk_format_table.find(format);
1152     if (item != vk_format_table.end()) {
1153         return item->second.format_class;
1154     }
1155     return VK_FORMAT_COMPATIBILITY_CLASS_NONE_BIT;
1156 }
1157 
1158 // Return size, in bytes, of one element of the specified format
1159 // For uncompressed this is one texel, for compressed it is one block
FormatElementSize(VkFormat format,VkImageAspectFlags aspectMask)1160 VK_LAYER_EXPORT uint32_t FormatElementSize(VkFormat format, VkImageAspectFlags aspectMask) {
1161     // Handle special buffer packing rules for specific depth/stencil formats
1162     if (aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
1163         format = VK_FORMAT_S8_UINT;
1164     } else if (aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
1165         switch (format) {
1166             case VK_FORMAT_D16_UNORM_S8_UINT:
1167                 format = VK_FORMAT_D16_UNORM;
1168                 break;
1169             case VK_FORMAT_D32_SFLOAT_S8_UINT:
1170                 format = VK_FORMAT_D32_SFLOAT;
1171                 break;
1172             default:
1173                 break;
1174         }
1175     } else if (FormatIsMultiplane(format)) {
1176         format = FindMultiplaneCompatibleFormat(format, aspectMask);
1177     }
1178 
1179     auto item = vk_format_table.find(format);
1180     if (item != vk_format_table.end()) {
1181         return item->second.size;
1182     }
1183     return 0;
1184 }
1185 
1186 // Return the size in bytes of one texel of given foramt
1187 // For compressed or multi-plane, this may be a fractional number
FormatTexelSize(VkFormat format)1188 VK_LAYER_EXPORT double FormatTexelSize(VkFormat format) {
1189     double texel_size = static_cast<double>(FormatElementSize(format));
1190     VkExtent3D block_extent = FormatTexelBlockExtent(format);
1191     uint32_t texels_per_block = block_extent.width * block_extent.height * block_extent.depth;
1192     if (1 < texels_per_block) {
1193         texel_size /= static_cast<double>(texels_per_block);
1194     }
1195     return texel_size;
1196 }
1197 
1198 // Return the number of channels for a given format
FormatChannelCount(VkFormat format)1199 uint32_t FormatChannelCount(VkFormat format) {
1200     auto item = vk_format_table.find(format);
1201     if (item != vk_format_table.end()) {
1202         return item->second.channel_count;
1203     }
1204     return 0;
1205 }
1206 
1207 // Perform a zero-tolerant modulo operation
SafeModulo(VkDeviceSize dividend,VkDeviceSize divisor)1208 VK_LAYER_EXPORT VkDeviceSize SafeModulo(VkDeviceSize dividend, VkDeviceSize divisor) {
1209     VkDeviceSize result = 0;
1210     if (divisor != 0) {
1211         result = dividend % divisor;
1212     }
1213     return result;
1214 }
1215 
SafeDivision(VkDeviceSize dividend,VkDeviceSize divisor)1216 VK_LAYER_EXPORT VkDeviceSize SafeDivision(VkDeviceSize dividend, VkDeviceSize divisor) {
1217     VkDeviceSize result = 0;
1218     if (divisor != 0) {
1219         result = dividend / divisor;
1220     }
1221     return result;
1222 }
1223 
1224 struct VULKAN_PER_PLANE_COMPATIBILITY {
1225     uint32_t width_divisor;
1226     uint32_t height_divisor;
1227     VkFormat compatible_format;
1228 };
1229 
1230 struct VULKAN_MULTIPLANE_COMPATIBILITY {
1231     VULKAN_PER_PLANE_COMPATIBILITY per_plane[VK_MULTIPLANE_FORMAT_MAX_PLANES];
1232 };
1233 
1234 // Source: Vulkan spec Table 45. Plane Format Compatibility Table
1235 // clang-format off
1236 const std::map<VkFormat, VULKAN_MULTIPLANE_COMPATIBILITY> vk_multiplane_compatibility_map {
1237     { VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,                  { { { 1, 1, VK_FORMAT_R8_UNORM },
1238                                                                 { 2, 2, VK_FORMAT_R8_UNORM },
1239                                                                 { 2, 2, VK_FORMAT_R8_UNORM } } } },
1240     { VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,                   { { { 1, 1, VK_FORMAT_R8_UNORM },
1241                                                                 { 2, 2, VK_FORMAT_R8G8_UNORM },
1242                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1243     { VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,                  { { { 1, 1, VK_FORMAT_R8_UNORM },
1244                                                                 { 2, 1, VK_FORMAT_R8_UNORM },
1245                                                                 { 2, 1, VK_FORMAT_R8_UNORM } } } },
1246     { VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,                   { { { 1, 1, VK_FORMAT_R8_UNORM },
1247                                                                 { 2, 1, VK_FORMAT_R8G8_UNORM },
1248                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1249     { VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,                  { { { 1, 1, VK_FORMAT_R8_UNORM },
1250                                                                 { 1, 1, VK_FORMAT_R8_UNORM },
1251                                                                 { 1, 1, VK_FORMAT_R8_UNORM } } } },
1252     { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, { { { 1, 1, VK_FORMAT_R10X6_UNORM_PACK16 },
1253                                                                 { 2, 2, VK_FORMAT_R10X6_UNORM_PACK16 },
1254                                                                 { 2, 2, VK_FORMAT_R10X6_UNORM_PACK16 } } } },
1255     { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,  { { { 1, 1, VK_FORMAT_R10X6_UNORM_PACK16 },
1256                                                                 { 2, 2, VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
1257                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1258     { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, { { { 1, 1, VK_FORMAT_R10X6_UNORM_PACK16 },
1259                                                                 { 2, 1, VK_FORMAT_R10X6_UNORM_PACK16 },
1260                                                                 { 2, 1, VK_FORMAT_R10X6_UNORM_PACK16 } } } },
1261     { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,  { { { 1, 1, VK_FORMAT_R10X6_UNORM_PACK16 },
1262                                                                 { 2, 1, VK_FORMAT_R10X6G10X6_UNORM_2PACK16 },
1263                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1264     { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, { { { 1, 1, VK_FORMAT_R10X6_UNORM_PACK16 },
1265                                                                 { 1, 1, VK_FORMAT_R10X6_UNORM_PACK16 },
1266                                                                 { 1, 1, VK_FORMAT_R10X6_UNORM_PACK16 } } } },
1267     { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, { { { 1, 1, VK_FORMAT_R12X4_UNORM_PACK16 },
1268                                                                 { 2, 2, VK_FORMAT_R12X4_UNORM_PACK16 },
1269                                                                 { 2, 2, VK_FORMAT_R12X4_UNORM_PACK16 } } } },
1270     { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,  { { { 1, 1, VK_FORMAT_R12X4_UNORM_PACK16 },
1271                                                                 { 2, 2, VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
1272                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1273     { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, { { { 1, 1, VK_FORMAT_R12X4_UNORM_PACK16 },
1274                                                                 { 2, 1, VK_FORMAT_R12X4_UNORM_PACK16 },
1275                                                                 { 2, 1, VK_FORMAT_R12X4_UNORM_PACK16 } } } },
1276     { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,  { { { 1, 1, VK_FORMAT_R12X4_UNORM_PACK16 },
1277                                                                 { 2, 1, VK_FORMAT_R12X4G12X4_UNORM_2PACK16 },
1278                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1279     { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, { { { 1, 1, VK_FORMAT_R12X4_UNORM_PACK16 },
1280                                                                 { 1, 1, VK_FORMAT_R12X4_UNORM_PACK16 },
1281                                                                 { 1, 1, VK_FORMAT_R12X4_UNORM_PACK16 } } } },
1282     { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,               { { { 1, 1, VK_FORMAT_R16_UNORM },
1283                                                                 { 2, 2, VK_FORMAT_R16_UNORM },
1284                                                                 { 2, 2, VK_FORMAT_R16_UNORM } } } },
1285     { VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,                { { { 1, 1, VK_FORMAT_R16_UNORM },
1286                                                                 { 2, 2, VK_FORMAT_R16G16_UNORM },
1287                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1288     { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,               { { { 1, 1, VK_FORMAT_R16_UNORM },
1289                                                                 { 2, 1, VK_FORMAT_R16_UNORM },
1290                                                                 { 2, 1, VK_FORMAT_R16_UNORM } } } },
1291     { VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,                { { { 1, 1, VK_FORMAT_R16_UNORM },
1292                                                                 { 2, 1, VK_FORMAT_R16G16_UNORM },
1293                                                                 { 1, 1, VK_FORMAT_UNDEFINED } } } },
1294     { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,               { { { 1, 1, VK_FORMAT_R16_UNORM },
1295                                                                 { 1, 1, VK_FORMAT_R16_UNORM },
1296                                                                 { 1, 1, VK_FORMAT_R16_UNORM } } } }
1297 };
1298 // clang-format on
1299 
GetPlaneIndex(VkImageAspectFlags aspect)1300 uint32_t GetPlaneIndex(VkImageAspectFlags aspect) {
1301     // Returns an out of bounds index on error
1302     switch (aspect) {
1303         case VK_IMAGE_ASPECT_PLANE_0_BIT:
1304             return 0;
1305             break;
1306         case VK_IMAGE_ASPECT_PLANE_1_BIT:
1307             return 1;
1308             break;
1309         case VK_IMAGE_ASPECT_PLANE_2_BIT:
1310             return 2;
1311             break;
1312         default:
1313             // If more than one plane bit is set, return error condition
1314             return VK_MULTIPLANE_FORMAT_MAX_PLANES;
1315             break;
1316     }
1317 }
1318 
FindMultiplaneCompatibleFormat(VkFormat mp_fmt,VkImageAspectFlags plane_aspect)1319 VK_LAYER_EXPORT VkFormat FindMultiplaneCompatibleFormat(VkFormat mp_fmt, VkImageAspectFlags plane_aspect) {
1320     uint32_t plane_idx = GetPlaneIndex(plane_aspect);
1321     auto it = vk_multiplane_compatibility_map.find(mp_fmt);
1322     if ((it == vk_multiplane_compatibility_map.end()) || (plane_idx >= VK_MULTIPLANE_FORMAT_MAX_PLANES)) {
1323         return VK_FORMAT_UNDEFINED;
1324     }
1325 
1326     return it->second.per_plane[plane_idx].compatible_format;
1327 }
1328 
FindMultiplaneExtentDivisors(VkFormat mp_fmt,VkImageAspectFlags plane_aspect)1329 VK_LAYER_EXPORT VkExtent2D FindMultiplaneExtentDivisors(VkFormat mp_fmt, VkImageAspectFlags plane_aspect) {
1330     VkExtent2D divisors = {1, 1};
1331     uint32_t plane_idx = GetPlaneIndex(plane_aspect);
1332     auto it = vk_multiplane_compatibility_map.find(mp_fmt);
1333     if ((it == vk_multiplane_compatibility_map.end()) || (plane_idx >= VK_MULTIPLANE_FORMAT_MAX_PLANES)) {
1334         return divisors;
1335     }
1336 
1337     divisors.width = it->second.per_plane[plane_idx].width_divisor;
1338     divisors.height = it->second.per_plane[plane_idx].height_divisor;
1339     return divisors;
1340 }
1341 
FormatSizesAreEqual(VkFormat srcFormat,VkFormat dstFormat,uint32_t region_count,const VkImageCopy * regions)1342 VK_LAYER_EXPORT bool FormatSizesAreEqual(VkFormat srcFormat, VkFormat dstFormat, uint32_t region_count,
1343                                          const VkImageCopy *regions) {
1344     size_t srcSize = 0, dstSize = 0;
1345 
1346     if (FormatIsMultiplane(srcFormat) || FormatIsMultiplane(dstFormat)) {
1347         for (uint32_t i = 0; i < region_count; i++) {
1348             if (FormatIsMultiplane(srcFormat)) {
1349                 VkFormat planeFormat = FindMultiplaneCompatibleFormat(srcFormat, regions[i].srcSubresource.aspectMask);
1350                 srcSize = FormatElementSize(planeFormat);
1351             } else {
1352                 srcSize = FormatElementSize(srcFormat);
1353             }
1354             if (FormatIsMultiplane(dstFormat)) {
1355                 VkFormat planeFormat = FindMultiplaneCompatibleFormat(dstFormat, regions[i].dstSubresource.aspectMask);
1356                 dstSize = FormatElementSize(planeFormat);
1357             } else {
1358                 dstSize = FormatElementSize(dstFormat);
1359             }
1360             if (dstSize != srcSize) return false;
1361         }
1362         return true;
1363     } else {
1364         srcSize = FormatElementSize(srcFormat);
1365         dstSize = FormatElementSize(dstFormat);
1366         return (dstSize == srcSize);
1367     }
1368 }
1369 
FormatRequiresYcbcrConversion(VkFormat format)1370 VK_LAYER_EXPORT bool FormatRequiresYcbcrConversion(VkFormat format) {
1371     return format >= VK_FORMAT_G8B8G8R8_422_UNORM && format <= VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM;
1372 }
1373