Path: blob/master/servers/rendering/rendering_device_commons.cpp
10277 views
/**************************************************************************/1/* rendering_device_commons.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "rendering_device_commons.h"3132#include "thirdparty/spirv-reflect/spirv_reflect.h"3334/*****************/35/**** GENERIC ****/36/*****************/3738const char *const RenderingDeviceCommons::FORMAT_NAMES[DATA_FORMAT_MAX] = {39"R4G4_Unorm_Pack8",40"R4G4B4A4_Unorm_Pack16",41"B4G4R4A4_Unorm_Pack16",42"R5G6B5_Unorm_Pack16",43"B5G6R5_Unorm_Pack16",44"R5G5B5A1_Unorm_Pack16",45"B5G5R5A1_Unorm_Pack16",46"A1R5G5B5_Unorm_Pack16",47"R8_Unorm",48"R8_Snorm",49"R8_Uscaled",50"R8_Sscaled",51"R8_Uint",52"R8_Sint",53"R8_Srgb",54"R8G8_Unorm",55"R8G8_Snorm",56"R8G8_Uscaled",57"R8G8_Sscaled",58"R8G8_Uint",59"R8G8_Sint",60"R8G8_Srgb",61"R8G8B8_Unorm",62"R8G8B8_Snorm",63"R8G8B8_Uscaled",64"R8G8B8_Sscaled",65"R8G8B8_Uint",66"R8G8B8_Sint",67"R8G8B8_Srgb",68"B8G8R8_Unorm",69"B8G8R8_Snorm",70"B8G8R8_Uscaled",71"B8G8R8_Sscaled",72"B8G8R8_Uint",73"B8G8R8_Sint",74"B8G8R8_Srgb",75"R8G8B8A8_Unorm",76"R8G8B8A8_Snorm",77"R8G8B8A8_Uscaled",78"R8G8B8A8_Sscaled",79"R8G8B8A8_Uint",80"R8G8B8A8_Sint",81"R8G8B8A8_Srgb",82"B8G8R8A8_Unorm",83"B8G8R8A8_Snorm",84"B8G8R8A8_Uscaled",85"B8G8R8A8_Sscaled",86"B8G8R8A8_Uint",87"B8G8R8A8_Sint",88"B8G8R8A8_Srgb",89"A8B8G8R8_Unorm_Pack32",90"A8B8G8R8_Snorm_Pack32",91"A8B8G8R8_Uscaled_Pack32",92"A8B8G8R8_Sscaled_Pack32",93"A8B8G8R8_Uint_Pack32",94"A8B8G8R8_Sint_Pack32",95"A8B8G8R8_Srgb_Pack32",96"A2R10G10B10_Unorm_Pack32",97"A2R10G10B10_Snorm_Pack32",98"A2R10G10B10_Uscaled_Pack32",99"A2R10G10B10_Sscaled_Pack32",100"A2R10G10B10_Uint_Pack32",101"A2R10G10B10_Sint_Pack32",102"A2B10G10R10_Unorm_Pack32",103"A2B10G10R10_Snorm_Pack32",104"A2B10G10R10_Uscaled_Pack32",105"A2B10G10R10_Sscaled_Pack32",106"A2B10G10R10_Uint_Pack32",107"A2B10G10R10_Sint_Pack32",108"R16_Unorm",109"R16_Snorm",110"R16_Uscaled",111"R16_Sscaled",112"R16_Uint",113"R16_Sint",114"R16_Sfloat",115"R16G16_Unorm",116"R16G16_Snorm",117"R16G16_Uscaled",118"R16G16_Sscaled",119"R16G16_Uint",120"R16G16_Sint",121"R16G16_Sfloat",122"R16G16B16_Unorm",123"R16G16B16_Snorm",124"R16G16B16_Uscaled",125"R16G16B16_Sscaled",126"R16G16B16_Uint",127"R16G16B16_Sint",128"R16G16B16_Sfloat",129"R16G16B16A16_Unorm",130"R16G16B16A16_Snorm",131"R16G16B16A16_Uscaled",132"R16G16B16A16_Sscaled",133"R16G16B16A16_Uint",134"R16G16B16A16_Sint",135"R16G16B16A16_Sfloat",136"R32_Uint",137"R32_Sint",138"R32_Sfloat",139"R32G32_Uint",140"R32G32_Sint",141"R32G32_Sfloat",142"R32G32B32_Uint",143"R32G32B32_Sint",144"R32G32B32_Sfloat",145"R32G32B32A32_Uint",146"R32G32B32A32_Sint",147"R32G32B32A32_Sfloat",148"R64_Uint",149"R64_Sint",150"R64_Sfloat",151"R64G64_Uint",152"R64G64_Sint",153"R64G64_Sfloat",154"R64G64B64_Uint",155"R64G64B64_Sint",156"R64G64B64_Sfloat",157"R64G64B64A64_Uint",158"R64G64B64A64_Sint",159"R64G64B64A64_Sfloat",160"B10G11R11_Ufloat_Pack32",161"E5B9G9R9_Ufloat_Pack32",162"D16_Unorm",163"X8_D24_Unorm_Pack32",164"D32_Sfloat",165"S8_Uint",166"D16_Unorm_S8_Uint",167"D24_Unorm_S8_Uint",168"D32_Sfloat_S8_Uint",169"Bc1_Rgb_Unorm_Block",170"Bc1_Rgb_Srgb_Block",171"Bc1_Rgba_Unorm_Block",172"Bc1_Rgba_Srgb_Block",173"Bc2_Unorm_Block",174"Bc2_Srgb_Block",175"Bc3_Unorm_Block",176"Bc3_Srgb_Block",177"Bc4_Unorm_Block",178"Bc4_Snorm_Block",179"Bc5_Unorm_Block",180"Bc5_Snorm_Block",181"Bc6H_Ufloat_Block",182"Bc6H_Sfloat_Block",183"Bc7_Unorm_Block",184"Bc7_Srgb_Block",185"Etc2_R8G8B8_Unorm_Block",186"Etc2_R8G8B8_Srgb_Block",187"Etc2_R8G8B8A1_Unorm_Block",188"Etc2_R8G8B8A1_Srgb_Block",189"Etc2_R8G8B8A8_Unorm_Block",190"Etc2_R8G8B8A8_Srgb_Block",191"Eac_R11_Unorm_Block",192"Eac_R11_Snorm_Block",193"Eac_R11G11_Unorm_Block",194"Eac_R11G11_Snorm_Block",195"Astc_4X4_Unorm_Block",196"Astc_4X4_Srgb_Block",197"Astc_5X4_Unorm_Block",198"Astc_5X4_Srgb_Block",199"Astc_5X5_Unorm_Block",200"Astc_5X5_Srgb_Block",201"Astc_6X5_Unorm_Block",202"Astc_6X5_Srgb_Block",203"Astc_6X6_Unorm_Block",204"Astc_6X6_Srgb_Block",205"Astc_8X5_Unorm_Block",206"Astc_8X5_Srgb_Block",207"Astc_8X6_Unorm_Block",208"Astc_8X6_Srgb_Block",209"Astc_8X8_Unorm_Block",210"Astc_8X8_Srgb_Block",211"Astc_10X5_Unorm_Block",212"Astc_10X5_Srgb_Block",213"Astc_10X6_Unorm_Block",214"Astc_10X6_Srgb_Block",215"Astc_10X8_Unorm_Block",216"Astc_10X8_Srgb_Block",217"Astc_10X10_Unorm_Block",218"Astc_10X10_Srgb_Block",219"Astc_12X10_Unorm_Block",220"Astc_12X10_Srgb_Block",221"Astc_12X12_Unorm_Block",222"Astc_12X12_Srgb_Block",223"G8B8G8R8_422_Unorm",224"B8G8R8G8_422_Unorm",225"G8_B8_R8_3Plane_420_Unorm",226"G8_B8R8_2Plane_420_Unorm",227"G8_B8_R8_3Plane_422_Unorm",228"G8_B8R8_2Plane_422_Unorm",229"G8_B8_R8_3Plane_444_Unorm",230"R10X6_Unorm_Pack16",231"R10X6G10X6_Unorm_2Pack16",232"R10X6G10X6B10X6A10X6_Unorm_4Pack16",233"G10X6B10X6G10X6R10X6_422_Unorm_4Pack16",234"B10X6G10X6R10X6G10X6_422_Unorm_4Pack16",235"G10X6_B10X6_R10X6_3Plane_420_Unorm_3Pack16",236"G10X6_B10X6R10X6_2Plane_420_Unorm_3Pack16",237"G10X6_B10X6_R10X6_3Plane_422_Unorm_3Pack16",238"G10X6_B10X6R10X6_2Plane_422_Unorm_3Pack16",239"G10X6_B10X6_R10X6_3Plane_444_Unorm_3Pack16",240"R12X4_Unorm_Pack16",241"R12X4G12X4_Unorm_2Pack16",242"R12X4G12X4B12X4A12X4_Unorm_4Pack16",243"G12X4B12X4G12X4R12X4_422_Unorm_4Pack16",244"B12X4G12X4R12X4G12X4_422_Unorm_4Pack16",245"G12X4_B12X4_R12X4_3Plane_420_Unorm_3Pack16",246"G12X4_B12X4R12X4_2Plane_420_Unorm_3Pack16",247"G12X4_B12X4_R12X4_3Plane_422_Unorm_3Pack16",248"G12X4_B12X4R12X4_2Plane_422_Unorm_3Pack16",249"G12X4_B12X4_R12X4_3Plane_444_Unorm_3Pack16",250"G16B16G16R16_422_Unorm",251"B16G16R16G16_422_Unorm",252"G16_B16_R16_3Plane_420_Unorm",253"G16_B16R16_2Plane_420_Unorm",254"G16_B16_R16_3Plane_422_Unorm",255"G16_B16R16_2Plane_422_Unorm",256"G16_B16_R16_3Plane_444_Unorm",257"Astc_4X4_Sfloat_Block",258"Astc_5X4_Sfloat_Block",259"Astc_5X5_Sfloat_Block",260"Astc_6X5_Sfloat_Block",261"Astc_6X6_Sfloat_Block",262"Astc_8X5_Sfloat_Block",263"Astc_8X6_Sfloat_Block",264"Astc_8X8_Sfloat_Block",265"Astc_10X5_Sfloat_Block",266"Astc_10X6_Sfloat_Block",267"Astc_10X8_Sfloat_Block",268"Astc_10X10_Sfloat_Block",269"Astc_12X10_Sfloat_Block",270"Astc_12X12_Sfloat_Block",271};272273/*****************/274/**** TEXTURE ****/275/*****************/276277const uint32_t RenderingDeviceCommons::TEXTURE_SAMPLES_COUNT[TEXTURE_SAMPLES_MAX] = { 1, 2, 4, 8, 16, 32, 64 };278279uint32_t RenderingDeviceCommons::get_image_format_pixel_size(DataFormat p_format) {280switch (p_format) {281case DATA_FORMAT_R4G4_UNORM_PACK8:282return 1;283case DATA_FORMAT_R4G4B4A4_UNORM_PACK16:284case DATA_FORMAT_B4G4R4A4_UNORM_PACK16:285case DATA_FORMAT_R5G6B5_UNORM_PACK16:286case DATA_FORMAT_B5G6R5_UNORM_PACK16:287case DATA_FORMAT_R5G5B5A1_UNORM_PACK16:288case DATA_FORMAT_B5G5R5A1_UNORM_PACK16:289case DATA_FORMAT_A1R5G5B5_UNORM_PACK16:290return 2;291case DATA_FORMAT_R8_UNORM:292case DATA_FORMAT_R8_SNORM:293case DATA_FORMAT_R8_USCALED:294case DATA_FORMAT_R8_SSCALED:295case DATA_FORMAT_R8_UINT:296case DATA_FORMAT_R8_SINT:297case DATA_FORMAT_R8_SRGB:298return 1;299case DATA_FORMAT_R8G8_UNORM:300case DATA_FORMAT_R8G8_SNORM:301case DATA_FORMAT_R8G8_USCALED:302case DATA_FORMAT_R8G8_SSCALED:303case DATA_FORMAT_R8G8_UINT:304case DATA_FORMAT_R8G8_SINT:305case DATA_FORMAT_R8G8_SRGB:306return 2;307case DATA_FORMAT_R8G8B8_UNORM:308case DATA_FORMAT_R8G8B8_SNORM:309case DATA_FORMAT_R8G8B8_USCALED:310case DATA_FORMAT_R8G8B8_SSCALED:311case DATA_FORMAT_R8G8B8_UINT:312case DATA_FORMAT_R8G8B8_SINT:313case DATA_FORMAT_R8G8B8_SRGB:314case DATA_FORMAT_B8G8R8_UNORM:315case DATA_FORMAT_B8G8R8_SNORM:316case DATA_FORMAT_B8G8R8_USCALED:317case DATA_FORMAT_B8G8R8_SSCALED:318case DATA_FORMAT_B8G8R8_UINT:319case DATA_FORMAT_B8G8R8_SINT:320case DATA_FORMAT_B8G8R8_SRGB:321return 3;322case DATA_FORMAT_R8G8B8A8_UNORM:323case DATA_FORMAT_R8G8B8A8_SNORM:324case DATA_FORMAT_R8G8B8A8_USCALED:325case DATA_FORMAT_R8G8B8A8_SSCALED:326case DATA_FORMAT_R8G8B8A8_UINT:327case DATA_FORMAT_R8G8B8A8_SINT:328case DATA_FORMAT_R8G8B8A8_SRGB:329case DATA_FORMAT_B8G8R8A8_UNORM:330case DATA_FORMAT_B8G8R8A8_SNORM:331case DATA_FORMAT_B8G8R8A8_USCALED:332case DATA_FORMAT_B8G8R8A8_SSCALED:333case DATA_FORMAT_B8G8R8A8_UINT:334case DATA_FORMAT_B8G8R8A8_SINT:335case DATA_FORMAT_B8G8R8A8_SRGB:336return 4;337case DATA_FORMAT_A8B8G8R8_UNORM_PACK32:338case DATA_FORMAT_A8B8G8R8_SNORM_PACK32:339case DATA_FORMAT_A8B8G8R8_USCALED_PACK32:340case DATA_FORMAT_A8B8G8R8_SSCALED_PACK32:341case DATA_FORMAT_A8B8G8R8_UINT_PACK32:342case DATA_FORMAT_A8B8G8R8_SINT_PACK32:343case DATA_FORMAT_A8B8G8R8_SRGB_PACK32:344case DATA_FORMAT_A2R10G10B10_UNORM_PACK32:345case DATA_FORMAT_A2R10G10B10_SNORM_PACK32:346case DATA_FORMAT_A2R10G10B10_USCALED_PACK32:347case DATA_FORMAT_A2R10G10B10_SSCALED_PACK32:348case DATA_FORMAT_A2R10G10B10_UINT_PACK32:349case DATA_FORMAT_A2R10G10B10_SINT_PACK32:350case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:351case DATA_FORMAT_A2B10G10R10_SNORM_PACK32:352case DATA_FORMAT_A2B10G10R10_USCALED_PACK32:353case DATA_FORMAT_A2B10G10R10_SSCALED_PACK32:354case DATA_FORMAT_A2B10G10R10_UINT_PACK32:355case DATA_FORMAT_A2B10G10R10_SINT_PACK32:356return 4;357case DATA_FORMAT_R16_UNORM:358case DATA_FORMAT_R16_SNORM:359case DATA_FORMAT_R16_USCALED:360case DATA_FORMAT_R16_SSCALED:361case DATA_FORMAT_R16_UINT:362case DATA_FORMAT_R16_SINT:363case DATA_FORMAT_R16_SFLOAT:364return 2;365case DATA_FORMAT_R16G16_UNORM:366case DATA_FORMAT_R16G16_SNORM:367case DATA_FORMAT_R16G16_USCALED:368case DATA_FORMAT_R16G16_SSCALED:369case DATA_FORMAT_R16G16_UINT:370case DATA_FORMAT_R16G16_SINT:371case DATA_FORMAT_R16G16_SFLOAT:372return 4;373case DATA_FORMAT_R16G16B16_UNORM:374case DATA_FORMAT_R16G16B16_SNORM:375case DATA_FORMAT_R16G16B16_USCALED:376case DATA_FORMAT_R16G16B16_SSCALED:377case DATA_FORMAT_R16G16B16_UINT:378case DATA_FORMAT_R16G16B16_SINT:379case DATA_FORMAT_R16G16B16_SFLOAT:380return 6;381case DATA_FORMAT_R16G16B16A16_UNORM:382case DATA_FORMAT_R16G16B16A16_SNORM:383case DATA_FORMAT_R16G16B16A16_USCALED:384case DATA_FORMAT_R16G16B16A16_SSCALED:385case DATA_FORMAT_R16G16B16A16_UINT:386case DATA_FORMAT_R16G16B16A16_SINT:387case DATA_FORMAT_R16G16B16A16_SFLOAT:388return 8;389case DATA_FORMAT_R32_UINT:390case DATA_FORMAT_R32_SINT:391case DATA_FORMAT_R32_SFLOAT:392return 4;393case DATA_FORMAT_R32G32_UINT:394case DATA_FORMAT_R32G32_SINT:395case DATA_FORMAT_R32G32_SFLOAT:396return 8;397case DATA_FORMAT_R32G32B32_UINT:398case DATA_FORMAT_R32G32B32_SINT:399case DATA_FORMAT_R32G32B32_SFLOAT:400return 12;401case DATA_FORMAT_R32G32B32A32_UINT:402case DATA_FORMAT_R32G32B32A32_SINT:403case DATA_FORMAT_R32G32B32A32_SFLOAT:404return 16;405case DATA_FORMAT_R64_UINT:406case DATA_FORMAT_R64_SINT:407case DATA_FORMAT_R64_SFLOAT:408return 8;409case DATA_FORMAT_R64G64_UINT:410case DATA_FORMAT_R64G64_SINT:411case DATA_FORMAT_R64G64_SFLOAT:412return 16;413case DATA_FORMAT_R64G64B64_UINT:414case DATA_FORMAT_R64G64B64_SINT:415case DATA_FORMAT_R64G64B64_SFLOAT:416return 24;417case DATA_FORMAT_R64G64B64A64_UINT:418case DATA_FORMAT_R64G64B64A64_SINT:419case DATA_FORMAT_R64G64B64A64_SFLOAT:420return 32;421case DATA_FORMAT_B10G11R11_UFLOAT_PACK32:422case DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32:423return 4;424case DATA_FORMAT_D16_UNORM:425return 2;426case DATA_FORMAT_X8_D24_UNORM_PACK32:427return 4;428case DATA_FORMAT_D32_SFLOAT:429return 4;430case DATA_FORMAT_S8_UINT:431return 1;432case DATA_FORMAT_D16_UNORM_S8_UINT:433return 4;434case DATA_FORMAT_D24_UNORM_S8_UINT:435return 4;436case DATA_FORMAT_D32_SFLOAT_S8_UINT:437return 5; // ?438case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:439case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:440case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:441case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:442case DATA_FORMAT_BC2_UNORM_BLOCK:443case DATA_FORMAT_BC2_SRGB_BLOCK:444case DATA_FORMAT_BC3_UNORM_BLOCK:445case DATA_FORMAT_BC3_SRGB_BLOCK:446case DATA_FORMAT_BC4_UNORM_BLOCK:447case DATA_FORMAT_BC4_SNORM_BLOCK:448case DATA_FORMAT_BC5_UNORM_BLOCK:449case DATA_FORMAT_BC5_SNORM_BLOCK:450case DATA_FORMAT_BC6H_UFLOAT_BLOCK:451case DATA_FORMAT_BC6H_SFLOAT_BLOCK:452case DATA_FORMAT_BC7_UNORM_BLOCK:453case DATA_FORMAT_BC7_SRGB_BLOCK:454return 1;455case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:456case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:457case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:458case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:459case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:460case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:461return 1;462case DATA_FORMAT_EAC_R11_UNORM_BLOCK:463case DATA_FORMAT_EAC_R11_SNORM_BLOCK:464case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:465case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:466return 1;467case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK:468case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:469case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:470case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:471case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:472case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:473case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:474case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:475case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:476case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:477case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:478case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:479case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:480case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:481case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:482case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:483case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK:484case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:485case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:486case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:487case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:488case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:489case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:490case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:491case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:492case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:493case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:494case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:495case DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK:496case DATA_FORMAT_ASTC_5x4_SFLOAT_BLOCK:497case DATA_FORMAT_ASTC_5x5_SFLOAT_BLOCK:498case DATA_FORMAT_ASTC_6x5_SFLOAT_BLOCK:499case DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK:500case DATA_FORMAT_ASTC_8x5_SFLOAT_BLOCK:501case DATA_FORMAT_ASTC_8x6_SFLOAT_BLOCK:502case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK:503case DATA_FORMAT_ASTC_10x5_SFLOAT_BLOCK:504case DATA_FORMAT_ASTC_10x6_SFLOAT_BLOCK:505case DATA_FORMAT_ASTC_10x8_SFLOAT_BLOCK:506case DATA_FORMAT_ASTC_10x10_SFLOAT_BLOCK:507case DATA_FORMAT_ASTC_12x10_SFLOAT_BLOCK:508case DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK:509return 1;510case DATA_FORMAT_G8B8G8R8_422_UNORM:511case DATA_FORMAT_B8G8R8G8_422_UNORM:512return 4;513case DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM:514case DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM:515case DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM:516case DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM:517case DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM:518return 4;519case DATA_FORMAT_R10X6_UNORM_PACK16:520case DATA_FORMAT_R10X6G10X6_UNORM_2PACK16:521case DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:522case DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:523case DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:524case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:525case DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:526case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:527case DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:528case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:529case DATA_FORMAT_R12X4_UNORM_PACK16:530case DATA_FORMAT_R12X4G12X4_UNORM_2PACK16:531case DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:532case DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:533case DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:534case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:535case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:536case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:537case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:538case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:539return 2;540case DATA_FORMAT_G16B16G16R16_422_UNORM:541case DATA_FORMAT_B16G16R16G16_422_UNORM:542case DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM:543case DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM:544case DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM:545case DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM:546case DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM:547return 8;548default: {549ERR_PRINT("Format not handled, bug");550}551}552553return 1;554}555556// https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.pdf557void RenderingDeviceCommons::get_compressed_image_format_block_dimensions(DataFormat p_format, uint32_t &r_w, uint32_t &r_h) {558switch (p_format) {559case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:560case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:561case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:562case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:563case DATA_FORMAT_BC2_UNORM_BLOCK:564case DATA_FORMAT_BC2_SRGB_BLOCK:565case DATA_FORMAT_BC3_UNORM_BLOCK:566case DATA_FORMAT_BC3_SRGB_BLOCK:567case DATA_FORMAT_BC4_UNORM_BLOCK:568case DATA_FORMAT_BC4_SNORM_BLOCK:569case DATA_FORMAT_BC5_UNORM_BLOCK:570case DATA_FORMAT_BC5_SNORM_BLOCK:571case DATA_FORMAT_BC6H_UFLOAT_BLOCK:572case DATA_FORMAT_BC6H_SFLOAT_BLOCK:573case DATA_FORMAT_BC7_UNORM_BLOCK:574case DATA_FORMAT_BC7_SRGB_BLOCK:575case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:576case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:577case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:578case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:579case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:580case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:581case DATA_FORMAT_EAC_R11_UNORM_BLOCK:582case DATA_FORMAT_EAC_R11_SNORM_BLOCK:583case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:584case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:585case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: // Again, not sure about astc.586case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:587case DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK: {588r_w = 4;589r_h = 4;590} break;591case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK: // Unsupported592case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:593case DATA_FORMAT_ASTC_5x4_SFLOAT_BLOCK:594case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:595case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:596case DATA_FORMAT_ASTC_5x5_SFLOAT_BLOCK:597case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:598case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:599case DATA_FORMAT_ASTC_6x5_SFLOAT_BLOCK:600case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:601case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:602case DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK:603case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:604case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:605case DATA_FORMAT_ASTC_8x5_SFLOAT_BLOCK:606case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:607case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:608case DATA_FORMAT_ASTC_8x6_SFLOAT_BLOCK: {609r_w = 4;610r_h = 4;611} break;612case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:613case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:614case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK: {615r_w = 8;616r_h = 8;617} break;618case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK: // Unsupported619case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:620case DATA_FORMAT_ASTC_10x5_SFLOAT_BLOCK:621case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:622case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:623case DATA_FORMAT_ASTC_10x6_SFLOAT_BLOCK:624case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:625case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:626case DATA_FORMAT_ASTC_10x8_SFLOAT_BLOCK:627case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:628case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:629case DATA_FORMAT_ASTC_10x10_SFLOAT_BLOCK:630case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:631case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:632case DATA_FORMAT_ASTC_12x10_SFLOAT_BLOCK:633case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:634case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:635case DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK:636r_w = 4;637r_h = 4;638return;639default: {640r_w = 1;641r_h = 1;642}643}644}645646uint32_t RenderingDeviceCommons::get_compressed_image_format_block_byte_size(DataFormat p_format) const {647switch (p_format) {648case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:649case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:650case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:651case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:652return 8;653case DATA_FORMAT_BC2_UNORM_BLOCK:654case DATA_FORMAT_BC2_SRGB_BLOCK:655return 16;656case DATA_FORMAT_BC3_UNORM_BLOCK:657case DATA_FORMAT_BC3_SRGB_BLOCK:658return 16;659case DATA_FORMAT_BC4_UNORM_BLOCK:660case DATA_FORMAT_BC4_SNORM_BLOCK:661return 8;662case DATA_FORMAT_BC5_UNORM_BLOCK:663case DATA_FORMAT_BC5_SNORM_BLOCK:664return 16;665case DATA_FORMAT_BC6H_UFLOAT_BLOCK:666case DATA_FORMAT_BC6H_SFLOAT_BLOCK:667return 16;668case DATA_FORMAT_BC7_UNORM_BLOCK:669case DATA_FORMAT_BC7_SRGB_BLOCK:670return 16;671case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:672case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:673return 8;674case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:675case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:676return 8;677case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:678case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:679return 16;680case DATA_FORMAT_EAC_R11_UNORM_BLOCK:681case DATA_FORMAT_EAC_R11_SNORM_BLOCK:682return 8;683case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:684case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:685return 16;686case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: // Again, not sure about astc.687case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:688case DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK:689case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:690case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:691case DATA_FORMAT_ASTC_5x4_SFLOAT_BLOCK:692case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:693case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:694case DATA_FORMAT_ASTC_5x5_SFLOAT_BLOCK:695case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:696case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:697case DATA_FORMAT_ASTC_6x5_SFLOAT_BLOCK:698case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:699case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:700case DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK:701case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:702case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:703case DATA_FORMAT_ASTC_8x5_SFLOAT_BLOCK:704case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:705case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:706case DATA_FORMAT_ASTC_8x6_SFLOAT_BLOCK:707case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:708case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:709case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK:710case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK:711case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:712case DATA_FORMAT_ASTC_10x5_SFLOAT_BLOCK:713case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:714case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:715case DATA_FORMAT_ASTC_10x6_SFLOAT_BLOCK:716case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:717case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:718case DATA_FORMAT_ASTC_10x8_SFLOAT_BLOCK:719case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:720case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:721case DATA_FORMAT_ASTC_10x10_SFLOAT_BLOCK:722case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:723case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:724case DATA_FORMAT_ASTC_12x10_SFLOAT_BLOCK:725case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:726case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:727case DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK:728return 16;729default: {730}731}732return 1;733}734735uint32_t RenderingDeviceCommons::get_compressed_image_format_pixel_rshift(DataFormat p_format) {736switch (p_format) {737case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: // These formats are half byte size, so rshift is 1.738case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:739case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:740case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:741case DATA_FORMAT_BC4_UNORM_BLOCK:742case DATA_FORMAT_BC4_SNORM_BLOCK:743case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:744case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:745case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:746case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:747case DATA_FORMAT_EAC_R11_UNORM_BLOCK:748case DATA_FORMAT_EAC_R11_SNORM_BLOCK:749return 1;750case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:751case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:752case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK: {753return 2;754}755default: {756}757}758759return 0;760}761762uint32_t RenderingDeviceCommons::get_image_format_required_size(DataFormat p_format, uint32_t p_width, uint32_t p_height, uint32_t p_depth, uint32_t p_mipmaps, uint32_t *r_blockw, uint32_t *r_blockh, uint32_t *r_depth) {763ERR_FAIL_COND_V(p_mipmaps == 0, 0);764uint32_t w = p_width;765uint32_t h = p_height;766uint32_t d = p_depth;767768uint32_t size = 0;769770uint32_t pixel_size = get_image_format_pixel_size(p_format);771uint32_t pixel_rshift = get_compressed_image_format_pixel_rshift(p_format);772uint32_t blockw = 0;773uint32_t blockh = 0;774get_compressed_image_format_block_dimensions(p_format, blockw, blockh);775776for (uint32_t i = 0; i < p_mipmaps; i++) {777uint32_t bw = STEPIFY(w, blockw);778uint32_t bh = STEPIFY(h, blockh);779780uint32_t s = bw * bh;781782s *= pixel_size;783s >>= pixel_rshift;784size += s * d;785if (r_blockw) {786*r_blockw = bw;787}788if (r_blockh) {789*r_blockh = bh;790}791if (r_depth) {792*r_depth = d;793}794w = MAX(blockw, w >> 1);795h = MAX(blockh, h >> 1);796d = MAX(1u, d >> 1);797}798799return size;800}801802uint32_t RenderingDeviceCommons::get_image_required_mipmaps(uint32_t p_width, uint32_t p_height, uint32_t p_depth) {803// Formats and block size don't really matter here since they can all go down to 1px (even if block is larger).804uint32_t w = p_width;805uint32_t h = p_height;806uint32_t d = p_depth;807808uint32_t mipmaps = 1;809810while (true) {811if (w == 1 && h == 1 && d == 1) {812break;813}814815w = MAX(1u, w >> 1);816h = MAX(1u, h >> 1);817d = MAX(1u, d >> 1);818819mipmaps++;820}821822return mipmaps;823}824825bool RenderingDeviceCommons::format_has_stencil(DataFormat p_format) {826switch (p_format) {827case DATA_FORMAT_S8_UINT:828case DATA_FORMAT_D16_UNORM_S8_UINT:829case DATA_FORMAT_D24_UNORM_S8_UINT:830case DATA_FORMAT_D32_SFLOAT_S8_UINT: {831return true;832}833default: {834}835}836return false;837}838839uint32_t RenderingDeviceCommons::format_get_plane_count(DataFormat p_format) {840uint32_t planes = 1;841switch (p_format) {842case DATA_FORMAT_D16_UNORM_S8_UINT:843case DATA_FORMAT_D24_UNORM_S8_UINT:844case DATA_FORMAT_D32_SFLOAT_S8_UINT: {845planes = 2;846break;847}848default: {849}850}851DEV_ASSERT(planes <= MAX_IMAGE_FORMAT_PLANES);852return planes;853}854855/*****************/856/**** SAMPLER ****/857/*****************/858859const Color RenderingDeviceCommons::SAMPLER_BORDER_COLOR_VALUE[SAMPLER_BORDER_COLOR_MAX] = {860Color(0, 0, 0, 0),861Color(0, 0, 0, 0),862Color(0, 0, 0, 1),863Color(0, 0, 0, 1),864Color(1, 1, 1, 1),865Color(1, 1, 1, 1),866};867868/**********************/869/**** VERTEX ARRAY ****/870/**********************/871872uint32_t RenderingDeviceCommons::get_format_vertex_size(DataFormat p_format) {873switch (p_format) {874case DATA_FORMAT_R8_UNORM:875case DATA_FORMAT_R8_SNORM:876case DATA_FORMAT_R8_UINT:877case DATA_FORMAT_R8_SINT:878case DATA_FORMAT_R8G8_UNORM:879case DATA_FORMAT_R8G8_SNORM:880case DATA_FORMAT_R8G8_UINT:881case DATA_FORMAT_R8G8_SINT:882case DATA_FORMAT_R8G8B8_UNORM:883case DATA_FORMAT_R8G8B8_SNORM:884case DATA_FORMAT_R8G8B8_UINT:885case DATA_FORMAT_R8G8B8_SINT:886case DATA_FORMAT_B8G8R8_UNORM:887case DATA_FORMAT_B8G8R8_SNORM:888case DATA_FORMAT_B8G8R8_UINT:889case DATA_FORMAT_B8G8R8_SINT:890case DATA_FORMAT_R8G8B8A8_UNORM:891case DATA_FORMAT_R8G8B8A8_SNORM:892case DATA_FORMAT_R8G8B8A8_UINT:893case DATA_FORMAT_R8G8B8A8_SINT:894case DATA_FORMAT_B8G8R8A8_UNORM:895case DATA_FORMAT_B8G8R8A8_SNORM:896case DATA_FORMAT_B8G8R8A8_UINT:897case DATA_FORMAT_B8G8R8A8_SINT:898case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:899return 4;900case DATA_FORMAT_R16_UNORM:901case DATA_FORMAT_R16_SNORM:902case DATA_FORMAT_R16_UINT:903case DATA_FORMAT_R16_SINT:904case DATA_FORMAT_R16_SFLOAT:905return 4;906case DATA_FORMAT_R16G16_UNORM:907case DATA_FORMAT_R16G16_SNORM:908case DATA_FORMAT_R16G16_UINT:909case DATA_FORMAT_R16G16_SINT:910case DATA_FORMAT_R16G16_SFLOAT:911return 4;912case DATA_FORMAT_R16G16B16_UNORM:913case DATA_FORMAT_R16G16B16_SNORM:914case DATA_FORMAT_R16G16B16_UINT:915case DATA_FORMAT_R16G16B16_SINT:916case DATA_FORMAT_R16G16B16_SFLOAT:917return 8;918case DATA_FORMAT_R16G16B16A16_UNORM:919case DATA_FORMAT_R16G16B16A16_SNORM:920case DATA_FORMAT_R16G16B16A16_UINT:921case DATA_FORMAT_R16G16B16A16_SINT:922case DATA_FORMAT_R16G16B16A16_SFLOAT:923return 8;924case DATA_FORMAT_R32_UINT:925case DATA_FORMAT_R32_SINT:926case DATA_FORMAT_R32_SFLOAT:927return 4;928case DATA_FORMAT_R32G32_UINT:929case DATA_FORMAT_R32G32_SINT:930case DATA_FORMAT_R32G32_SFLOAT:931return 8;932case DATA_FORMAT_R32G32B32_UINT:933case DATA_FORMAT_R32G32B32_SINT:934case DATA_FORMAT_R32G32B32_SFLOAT:935return 12;936case DATA_FORMAT_R32G32B32A32_UINT:937case DATA_FORMAT_R32G32B32A32_SINT:938case DATA_FORMAT_R32G32B32A32_SFLOAT:939return 16;940case DATA_FORMAT_R64_UINT:941case DATA_FORMAT_R64_SINT:942case DATA_FORMAT_R64_SFLOAT:943return 8;944case DATA_FORMAT_R64G64_UINT:945case DATA_FORMAT_R64G64_SINT:946case DATA_FORMAT_R64G64_SFLOAT:947return 16;948case DATA_FORMAT_R64G64B64_UINT:949case DATA_FORMAT_R64G64B64_SINT:950case DATA_FORMAT_R64G64B64_SFLOAT:951return 24;952case DATA_FORMAT_R64G64B64A64_UINT:953case DATA_FORMAT_R64G64B64A64_SINT:954case DATA_FORMAT_R64G64B64A64_SFLOAT:955return 32;956default:957return 0;958}959}960961/****************/962/**** SHADER ****/963/****************/964965const char *RenderingDeviceCommons::SHADER_STAGE_NAMES[SHADER_STAGE_MAX] = {966"Vertex",967"Fragment",968"TesselationControl",969"TesselationEvaluation",970"Compute",971};972973Error RenderingDeviceCommons::reflect_spirv(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection) {974r_reflection = {};975976const uint32_t spirv_size = p_spirv.size();977for (uint32_t i = 0; i < spirv_size; i++) {978ShaderStage stage = p_spirv[i].shader_stage;979ShaderStage stage_flag = (ShaderStage)(1 << p_spirv[i].shader_stage);980981if (p_spirv[i].shader_stage == SHADER_STAGE_COMPUTE) {982r_reflection.is_compute = true;983ERR_FAIL_COND_V_MSG(spirv_size != 1, FAILED,984"Compute shaders can only receive one stage, dedicated to compute.");985}986ERR_FAIL_COND_V_MSG(r_reflection.stages_bits.has_flag(stage_flag), FAILED,987"Stage " + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + " submitted more than once.");988989{990SpvReflectShaderModule module;991const uint8_t *spirv = p_spirv[i].spirv.ptr();992SpvReflectResult result = spvReflectCreateShaderModule(p_spirv[i].spirv.size(), spirv, &module);993ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,994"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed parsing shader.");995996if (r_reflection.is_compute) {997r_reflection.compute_local_size[0] = module.entry_points->local_size.x;998r_reflection.compute_local_size[1] = module.entry_points->local_size.y;999r_reflection.compute_local_size[2] = module.entry_points->local_size.z;1000}1001uint32_t binding_count = 0;1002result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr);1003ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1004"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating descriptor bindings.");10051006if (binding_count > 0) {1007// Parse bindings.10081009Vector<SpvReflectDescriptorBinding *> bindings;1010bindings.resize(binding_count);1011result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.ptrw());10121013ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1014"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings.");10151016for (uint32_t j = 0; j < binding_count; j++) {1017const SpvReflectDescriptorBinding &binding = *bindings[j];10181019ShaderUniform uniform;10201021bool need_array_dimensions = false;1022bool need_block_size = false;1023bool may_be_writable = false;10241025switch (binding.descriptor_type) {1026case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: {1027uniform.type = UNIFORM_TYPE_SAMPLER;1028need_array_dimensions = true;1029} break;1030case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {1031uniform.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;1032need_array_dimensions = true;1033} break;1034case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {1035uniform.type = UNIFORM_TYPE_TEXTURE;1036need_array_dimensions = true;1037} break;1038case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: {1039uniform.type = UNIFORM_TYPE_IMAGE;1040need_array_dimensions = true;1041may_be_writable = true;1042} break;1043case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {1044uniform.type = UNIFORM_TYPE_TEXTURE_BUFFER;1045need_array_dimensions = true;1046} break;1047case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {1048uniform.type = UNIFORM_TYPE_IMAGE_BUFFER;1049need_array_dimensions = true;1050may_be_writable = true;1051} break;1052case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {1053uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER;1054need_block_size = true;1055} break;1056case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: {1057uniform.type = UNIFORM_TYPE_STORAGE_BUFFER;1058need_block_size = true;1059may_be_writable = true;1060} break;1061case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {1062ERR_PRINT("Dynamic uniform buffer not supported.");1063continue;1064} break;1065case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {1066ERR_PRINT("Dynamic storage buffer not supported.");1067continue;1068} break;1069case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {1070uniform.type = UNIFORM_TYPE_INPUT_ATTACHMENT;1071need_array_dimensions = true;1072} break;1073case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {1074ERR_PRINT("Acceleration structure not supported.");1075continue;1076} break;1077}10781079if (need_array_dimensions) {1080if (binding.array.dims_count == 0) {1081uniform.length = 1;1082} else {1083for (uint32_t k = 0; k < binding.array.dims_count; k++) {1084if (k == 0) {1085uniform.length = binding.array.dims[0];1086} else {1087uniform.length *= binding.array.dims[k];1088}1089}1090}10911092} else if (need_block_size) {1093uniform.length = binding.block.size;1094} else {1095uniform.length = 0;1096}10971098if (may_be_writable) {1099if (binding.descriptor_type == SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE) {1100uniform.writable = !(binding.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);1101} else {1102uniform.writable = !(binding.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);1103}1104} else {1105uniform.writable = false;1106}11071108uniform.binding = binding.binding;1109uint32_t set = binding.set;11101111ERR_FAIL_COND_V_MSG(set >= MAX_UNIFORM_SETS, FAILED,1112"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ").");11131114if (set < (uint32_t)r_reflection.uniform_sets.size()) {1115// Check if this already exists.1116bool exists = false;1117for (int k = 0; k < r_reflection.uniform_sets[set].size(); k++) {1118if (r_reflection.uniform_sets[set][k].binding == uniform.binding) {1119// Already exists, verify that it's the same type.1120ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].type != uniform.type, FAILED,1121"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform type.");11221123// Also, verify that it's the same size.1124ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].length != uniform.length, FAILED,1125"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform size.");11261127// Also, verify that it has the same writability.1128ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].writable != uniform.writable, FAILED,1129"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different writability.");11301131// Just append stage mask and return.1132r_reflection.uniform_sets.write[set].write[k].stages.set_flag(stage_flag);1133exists = true;1134break;1135}1136}11371138if (exists) {1139continue; // Merged.1140}1141}11421143uniform.stages.set_flag(stage_flag);11441145if (set >= (uint32_t)r_reflection.uniform_sets.size()) {1146r_reflection.uniform_sets.resize(set + 1);1147}11481149r_reflection.uniform_sets.write[set].push_back(uniform);1150}1151}11521153{1154// Specialization constants.11551156uint32_t sc_count = 0;1157result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr);1158ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1159"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating specialization constants.");11601161if (sc_count) {1162Vector<SpvReflectSpecializationConstant *> spec_constants;1163spec_constants.resize(sc_count);11641165result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw());1166ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1167"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining specialization constants.");11681169for (uint32_t j = 0; j < sc_count; j++) {1170int32_t existing = -1;1171ShaderSpecializationConstant sconst;1172SpvReflectSpecializationConstant *spc = spec_constants[j];11731174sconst.constant_id = spc->constant_id;1175sconst.int_value = 0; // Clear previous value JIC.1176switch (spc->constant_type) {1177case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: {1178sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;1179sconst.bool_value = spc->default_value.int_bool_value != 0;1180} break;1181case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: {1182sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;1183sconst.int_value = spc->default_value.int_bool_value;1184} break;1185case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: {1186sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;1187sconst.float_value = spc->default_value.float_value;1188} break;1189}1190sconst.stages.set_flag(stage_flag);11911192for (int k = 0; k < r_reflection.specialization_constants.size(); k++) {1193if (r_reflection.specialization_constants[k].constant_id == sconst.constant_id) {1194ERR_FAIL_COND_V_MSG(r_reflection.specialization_constants[k].type != sconst.type, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their types differ.");1195ERR_FAIL_COND_V_MSG(r_reflection.specialization_constants[k].int_value != sconst.int_value, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their default values differ.");1196existing = k;1197break;1198}1199}12001201if (existing >= 0) {1202r_reflection.specialization_constants.write[existing].stages.set_flag(stage_flag);1203} else {1204r_reflection.specialization_constants.push_back(sconst);1205}1206}12071208r_reflection.specialization_constants.sort();1209}1210}12111212if (stage == SHADER_STAGE_VERTEX || stage == SHADER_STAGE_FRAGMENT) {1213uint32_t iv_count = 0;1214result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr);1215ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1216"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating input variables.");12171218if (iv_count) {1219Vector<SpvReflectInterfaceVariable *> input_vars;1220input_vars.resize(iv_count);12211222result = spvReflectEnumerateInputVariables(&module, &iv_count, input_vars.ptrw());1223ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1224"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining input variables.");12251226for (const SpvReflectInterfaceVariable *v : input_vars) {1227if (!v) {1228continue;1229}1230if (stage == SHADER_STAGE_VERTEX) {1231if (v->decoration_flags == 0) { // Regular input.1232r_reflection.vertex_input_mask |= (((uint64_t)1) << v->location);1233}1234}1235if (v->built_in == SpvBuiltInViewIndex) {1236r_reflection.has_multiview = true;1237}1238}1239}1240}12411242if (stage == SHADER_STAGE_FRAGMENT) {1243uint32_t ov_count = 0;1244result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr);1245ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1246"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating output variables.");12471248if (ov_count) {1249Vector<SpvReflectInterfaceVariable *> output_vars;1250output_vars.resize(ov_count);12511252result = spvReflectEnumerateOutputVariables(&module, &ov_count, output_vars.ptrw());1253ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1254"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining output variables.");12551256for (const SpvReflectInterfaceVariable *refvar : output_vars) {1257if (!refvar) {1258continue;1259}1260if (refvar->built_in != SpvBuiltInFragDepth) {1261r_reflection.fragment_output_mask |= 1 << refvar->location;1262}1263}1264}1265}12661267uint32_t pc_count = 0;1268result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr);1269ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1270"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating push constants.");12711272if (pc_count) {1273ERR_FAIL_COND_V_MSG(pc_count > 1, FAILED,1274"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Only one push constant is supported, which should be the same across shader stages.");12751276Vector<SpvReflectBlockVariable *> pconstants;1277pconstants.resize(pc_count);1278result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, pconstants.ptrw());1279ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,1280"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining push constants.");1281#if 01282if (pconstants[0] == nullptr) {1283Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE);1284f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t));1285}1286#endif12871288ERR_FAIL_COND_V_MSG(r_reflection.push_constant_size && r_reflection.push_constant_size != pconstants[0]->size, FAILED,1289"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Push constant block must be the same across shader stages.");12901291r_reflection.push_constant_size = pconstants[0]->size;1292r_reflection.push_constant_stages.set_flag(stage_flag);12931294//print_line("Stage: " + String(SHADER_STAGE_NAMES[stage]) + " push constant of size=" + itos(push_constant.push_constant_size));1295}12961297// Destroy the reflection data when no longer required.1298spvReflectDestroyShaderModule(&module);1299}13001301r_reflection.stages_bits.set_flag(stage_flag);1302}13031304// Sort all uniform_sets by binding.1305for (uint32_t i = 0; i < r_reflection.uniform_sets.size(); i++) {1306r_reflection.uniform_sets.write[i].sort();1307}13081309return OK;1310}131113121313