1 /* 2 * Copyright 2011-2019 Branimir Karadzic. All rights reserved. 3 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause 4 */ 5 6 #include "bgfx_p.h" 7 8 #if BGFX_CONFIG_RENDERER_VULKAN 9 # include "renderer_vk.h" 10 11 #if BX_PLATFORM_OSX 12 # import <Cocoa/Cocoa.h> 13 # import <Foundation/Foundation.h> 14 # import <QuartzCore/QuartzCore.h> 15 # import <Metal/Metal.h> 16 #endif // BX_PLATFORM_OSX 17 18 namespace bgfx { namespace vk 19 { 20 static char s_viewName[BGFX_CONFIG_MAX_VIEWS][256]; 21 22 struct PrimInfo 23 { 24 VkPrimitiveTopology m_topology; 25 uint32_t m_min; 26 uint32_t m_div; 27 uint32_t m_sub; 28 }; 29 30 static const PrimInfo s_primInfo[] = 31 { 32 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 3, 3, 0 }, 33 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 1, 2 }, 34 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, 2, 2, 0 }, 35 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 1, 1 }, 36 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 1, 1, 0 }, 37 { VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, 0, 0, 0 }, 38 }; 39 BX_STATIC_ASSERT(Topology::Count == BX_COUNTOF(s_primInfo)-1); 40 41 static const uint32_t s_checkMsaa[] = 42 { 43 0, 44 2, 45 4, 46 8, 47 16, 48 }; 49 50 // static DXGI_SAMPLE_DESC s_msaa[] = 51 // { 52 // { 1, 0 }, 53 // { 2, 0 }, 54 // { 4, 0 }, 55 // { 8, 0 }, 56 // { 16, 0 }, 57 // }; 58 59 static const VkBlendFactor s_blendFactor[][2] = 60 { 61 { VkBlendFactor(0), VkBlendFactor(0) }, // ignored 62 { VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO }, // ZERO 63 { VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE }, // ONE 64 { VK_BLEND_FACTOR_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA }, // SRC_COLOR 65 { VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA }, // INV_SRC_COLOR 66 { VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_SRC_ALPHA }, // SRC_ALPHA 67 { VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA }, // INV_SRC_ALPHA 68 { VK_BLEND_FACTOR_DST_ALPHA, VK_BLEND_FACTOR_DST_ALPHA }, // DST_ALPHA 69 { VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA }, // INV_DST_ALPHA 70 { VK_BLEND_FACTOR_DST_COLOR, VK_BLEND_FACTOR_DST_ALPHA }, // DST_COLOR 71 { VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA }, // INV_DST_COLOR 72 { VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE }, // SRC_ALPHA_SAT 73 { VK_BLEND_FACTOR_CONSTANT_COLOR, VK_BLEND_FACTOR_CONSTANT_COLOR }, // FACTOR 74 { VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR }, // INV_FACTOR 75 }; 76 77 static const VkBlendOp s_blendEquation[] = 78 { 79 VK_BLEND_OP_ADD, 80 VK_BLEND_OP_SUBTRACT, 81 VK_BLEND_OP_REVERSE_SUBTRACT, 82 VK_BLEND_OP_MIN, 83 VK_BLEND_OP_MAX, 84 }; 85 86 static const VkCompareOp s_cmpFunc[] = 87 { 88 VkCompareOp(0), // ignored 89 VK_COMPARE_OP_LESS, 90 VK_COMPARE_OP_LESS_OR_EQUAL, 91 VK_COMPARE_OP_EQUAL, 92 VK_COMPARE_OP_GREATER_OR_EQUAL, 93 VK_COMPARE_OP_GREATER, 94 VK_COMPARE_OP_NOT_EQUAL, 95 VK_COMPARE_OP_NEVER, 96 VK_COMPARE_OP_ALWAYS, 97 }; 98 99 static const VkStencilOp s_stencilOp[] = 100 { 101 VK_STENCIL_OP_ZERO, 102 VK_STENCIL_OP_KEEP, 103 VK_STENCIL_OP_REPLACE, 104 VK_STENCIL_OP_INCREMENT_AND_WRAP, 105 VK_STENCIL_OP_INCREMENT_AND_CLAMP, 106 VK_STENCIL_OP_DECREMENT_AND_WRAP, 107 VK_STENCIL_OP_DECREMENT_AND_CLAMP, 108 VK_STENCIL_OP_INVERT, 109 }; 110 111 static const VkCullModeFlagBits s_cullMode[] = 112 { 113 VK_CULL_MODE_NONE, 114 VK_CULL_MODE_FRONT_BIT, 115 VK_CULL_MODE_BACK_BIT, 116 }; 117 118 static const VkSamplerAddressMode s_textureAddress[] = 119 { 120 VK_SAMPLER_ADDRESS_MODE_REPEAT, 121 VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, 122 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, 123 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, 124 }; 125 126 #define VK_IMPORT_FUNC(_optional, _func) PFN_##_func _func 127 #define VK_IMPORT_INSTANCE_FUNC VK_IMPORT_FUNC 128 #define VK_IMPORT_DEVICE_FUNC VK_IMPORT_FUNC 129 VK_IMPORT 130 VK_IMPORT_INSTANCE 131 VK_IMPORT_DEVICE 132 #undef VK_IMPORT_DEVICE_FUNC 133 #undef VK_IMPORT_INSTANCE_FUNC 134 #undef VK_IMPORT_FUNC 135 136 struct TextureFormatInfo 137 { 138 VkFormat m_fmt; 139 VkFormat m_fmtSrv; 140 VkFormat m_fmtDsv; 141 VkFormat m_fmtSrgb; 142 }; 143 144 static const TextureFormatInfo s_textureFormat[] = 145 { 146 { VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC1_RGB_SRGB_BLOCK }, // BC1 147 { VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC2_SRGB_BLOCK }, // BC2 148 { VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC3_SRGB_BLOCK }, // BC3 149 { VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // BC4 150 { VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // BC5 151 { VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // BC6H 152 { VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_BC7_SRGB_BLOCK }, // BC7 153 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ETC1 154 { VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK }, // ETC2 155 { VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK }, // ETC2A 156 { VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK }, // ETC2A1 157 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // PTC12 158 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // PTC14 159 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // PTC12A 160 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // PTC14A 161 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // PTC22 162 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // PTC24 163 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ATC 164 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ATCE 165 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ATCI 166 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ASTC4x4 167 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ASTC5x5 168 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ASTC6x6 169 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ASTC8x5 170 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ASTC8x6 171 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // ASTC10x5 172 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // Unknown 173 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R1 174 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // A8 175 { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8_SRGB }, // R8 176 { VK_FORMAT_R8_SINT, VK_FORMAT_R8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R8I 177 { VK_FORMAT_R8_UINT, VK_FORMAT_R8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R8U 178 { VK_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R8S 179 { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R16 180 { VK_FORMAT_R16_SINT, VK_FORMAT_R16_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R16I 181 { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R16U 182 { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R16F 183 { VK_FORMAT_R16_SNORM, VK_FORMAT_R16_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R16S 184 { VK_FORMAT_R32_SINT, VK_FORMAT_R32_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R32I 185 { VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R32U 186 { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R32F 187 { VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8_SRGB }, // RG8 188 { VK_FORMAT_R8G8_SINT, VK_FORMAT_R8G8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG8I 189 { VK_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG8U 190 { VK_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG8S 191 { VK_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG16 192 { VK_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG16I 193 { VK_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG16U 194 { VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG16F 195 { VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG16S 196 { VK_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG32I 197 { VK_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG32U 198 { VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG32F 199 { VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8_SRGB }, // RGB8 200 { VK_FORMAT_R8G8B8_SINT, VK_FORMAT_R8G8B8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8_SRGB }, // RGB8I 201 { VK_FORMAT_R8G8B8_UINT, VK_FORMAT_R8G8B8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8_SRGB }, // RGB8U 202 { VK_FORMAT_R8G8B8_SNORM, VK_FORMAT_R8G8B8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGB8S 203 { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGB9E5F 204 { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_B8G8R8A8_SRGB }, // BGRA8 205 { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8A8_SRGB }, // RGBA8 206 { VK_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8A8_SRGB }, // RGBA8I 207 { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_R8G8B8A8_SRGB }, // RGBA8U 208 { VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA8S 209 { VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA16 210 { VK_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA16I 211 { VK_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA16U 212 { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA16F 213 { VK_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA16S 214 { VK_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA32I 215 { VK_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA32U 216 { VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA32F 217 { VK_FORMAT_B5G6R5_UNORM_PACK16, VK_FORMAT_B5G6R5_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // R5G6B5 218 { VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGBA4 219 { VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGB5A1 220 { VK_FORMAT_A2R10G10B10_UNORM_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RGB10A2 221 { VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // RG11B10F 222 { VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED }, // UnknownDepth 223 { VK_FORMAT_UNDEFINED, VK_FORMAT_R16_UNORM, VK_FORMAT_D16_UNORM, VK_FORMAT_UNDEFINED }, // D16 224 { VK_FORMAT_UNDEFINED, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED }, // D24 225 { VK_FORMAT_UNDEFINED, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED }, // D24S8 226 { VK_FORMAT_UNDEFINED, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED }, // D32 227 { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_UNDEFINED }, // D16F 228 { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_UNDEFINED }, // D24F 229 { VK_FORMAT_UNDEFINED, VK_FORMAT_R32_SFLOAT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_UNDEFINED }, // D32F 230 { VK_FORMAT_UNDEFINED, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED }, // D0S8 231 }; 232 BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) ); 233 234 struct Extension 235 { 236 enum Enum 237 { 238 EXT_debug_utils, 239 EXT_debug_report, 240 EXT_memory_budget, 241 KHR_get_physical_device_properties2, 242 243 Count 244 }; 245 246 const char* m_name; 247 uint32_t m_minVersion; 248 bool m_instanceExt; 249 bool m_supported; 250 bool m_initialize; 251 }; 252 253 // Extension registry 254 // 255 static Extension s_extension[] = 256 { 257 { "VK_EXT_debug_utils", 1, false, false, BGFX_CONFIG_DEBUG_OBJECT_NAME }, 258 { "VK_EXT_debug_report", 1, false, false, BGFX_CONFIG_DEBUG }, 259 { "VK_EXT_memory_budget", 1, false, false, true }, 260 { "VK_KHR_get_physical_device_properties2", 1, false, false, true }, 261 }; 262 BX_STATIC_ASSERT(Extension::Count == BX_COUNTOF(s_extension) ); 263 updateExtension(const char * _name,uint32_t _version,bool _instanceExt)264 void updateExtension(const char* _name, uint32_t _version, bool _instanceExt) 265 { 266 bx::StringView ext(_name); 267 268 bool supported = false; 269 for (uint32_t ii = 0; ii < Extension::Count; ++ii) 270 { 271 Extension& extension = s_extension[ii]; 272 if (!extension.m_supported 273 && extension.m_initialize) 274 { 275 if ( 0 == bx::strCmp(ext, extension.m_name) 276 && _version >= extension.m_minVersion) 277 { 278 extension.m_supported = true; 279 extension.m_instanceExt = _instanceExt; 280 supported = true; 281 break; 282 } 283 } 284 } 285 286 BX_TRACE("\tv%-3d %s%s" 287 , _version 288 , _name 289 , supported ? " (supported)" : "", _name 290 ); 291 292 BX_UNUSED(supported); 293 } 294 295 static const VkFormat s_attribType[][4][2] = 296 { 297 { // Uint8 298 { VK_FORMAT_R8_UINT, VK_FORMAT_R8_UNORM }, 299 { VK_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UNORM }, 300 { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UNORM }, 301 { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UNORM }, 302 }, 303 { // Uint10 304 { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 }, 305 { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 }, 306 { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 }, 307 { VK_FORMAT_A2R10G10B10_UINT_PACK32, VK_FORMAT_A2R10G10B10_UNORM_PACK32 }, 308 }, 309 { // Int16 310 { VK_FORMAT_R16_SINT, VK_FORMAT_R16_SNORM }, 311 { VK_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SNORM }, 312 { VK_FORMAT_R16G16B16_SINT, VK_FORMAT_R16G16B16_SNORM }, 313 { VK_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SNORM }, 314 }, 315 { // Half 316 { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT }, 317 { VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_R16G16_SFLOAT }, 318 { VK_FORMAT_R16G16B16_SFLOAT, VK_FORMAT_R16G16B16_SFLOAT }, 319 { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R16G16B16A16_SFLOAT }, 320 }, 321 { // Float 322 { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT }, 323 { VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32_SFLOAT }, 324 { VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT }, 325 { VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT }, 326 }, 327 }; 328 BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); 329 fillVertexLayout(const ShaderVK * _vsh,VkPipelineVertexInputStateCreateInfo & _vertexInputState,const VertexLayout & _layout)330 void fillVertexLayout(const ShaderVK* _vsh, VkPipelineVertexInputStateCreateInfo& _vertexInputState, const VertexLayout& _layout) 331 { 332 uint32_t numBindings = _vertexInputState.vertexBindingDescriptionCount; 333 uint32_t numAttribs = _vertexInputState.vertexAttributeDescriptionCount; 334 VkVertexInputBindingDescription* inputBinding = const_cast<VkVertexInputBindingDescription*>(_vertexInputState.pVertexBindingDescriptions + numBindings); 335 VkVertexInputAttributeDescription* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs); 336 337 inputBinding->binding = numBindings; 338 inputBinding->stride = _layout.m_stride; 339 inputBinding->inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 340 341 for (uint32_t attr = 0; attr < Attrib::Count; ++attr) 342 { 343 if (UINT16_MAX != _layout.m_attributes[attr]) 344 { 345 inputAttrib->location = _vsh->m_attrRemap[attr]; 346 inputAttrib->binding = numBindings; 347 348 uint8_t num; 349 AttribType::Enum type; 350 bool normalized; 351 bool asInt; 352 _layout.decode(Attrib::Enum(attr), num, type, normalized, asInt); 353 inputAttrib->format = s_attribType[type][num-1][normalized]; 354 inputAttrib->offset = _layout.m_offset[attr]; 355 356 ++inputAttrib; 357 ++numAttribs; 358 } 359 } 360 361 _vertexInputState.vertexBindingDescriptionCount = numBindings + 1; 362 _vertexInputState.vertexAttributeDescriptionCount = numAttribs; 363 } 364 fillInstanceBinding(const ShaderVK * _vsh,VkPipelineVertexInputStateCreateInfo & _vertexInputState,uint32_t _numInstanceData)365 void fillInstanceBinding(const ShaderVK* _vsh, VkPipelineVertexInputStateCreateInfo& _vertexInputState, uint32_t _numInstanceData) 366 { 367 BX_UNUSED(_vsh); 368 369 uint32_t numBindings = _vertexInputState.vertexBindingDescriptionCount; 370 uint32_t numAttribs = _vertexInputState.vertexAttributeDescriptionCount; 371 VkVertexInputBindingDescription* inputBinding = const_cast<VkVertexInputBindingDescription*>(_vertexInputState.pVertexBindingDescriptions + numBindings); 372 VkVertexInputAttributeDescription* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs); 373 374 inputBinding->binding = numBindings; 375 inputBinding->stride = _numInstanceData * 16; 376 inputBinding->inputRate = VK_VERTEX_INPUT_RATE_INSTANCE; 377 378 for (uint32_t inst = 0; inst < _numInstanceData; ++inst) 379 { 380 inputAttrib->location = numAttribs; 381 inputAttrib->binding = numBindings; 382 inputAttrib->format = VK_FORMAT_R32G32B32A32_SFLOAT; 383 inputAttrib->offset = inst * 16; 384 385 ++numAttribs; 386 ++inputAttrib; 387 } 388 389 _vertexInputState.vertexBindingDescriptionCount = numBindings + 1; 390 _vertexInputState.vertexAttributeDescriptionCount = numAttribs; 391 } 392 393 static const char* s_deviceTypeName[] = 394 { 395 "Other", 396 "Integrated GPU", 397 "Discrete GPU", 398 "Virtual GPU", 399 "CPU", 400 401 "Unknown?!" 402 }; 403 getName(VkPhysicalDeviceType _type)404 const char* getName(VkPhysicalDeviceType _type) 405 { 406 return s_deviceTypeName[bx::min<int32_t>(_type, BX_COUNTOF(s_deviceTypeName) )]; 407 } 408 409 static const char* s_allocScopeName[] = 410 { 411 "vkCommand", 412 "vkObject", 413 "vkCache", 414 "vkDevice", 415 "vkInstance", 416 }; 417 BX_STATIC_ASSERT(VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE == BX_COUNTOF(s_allocScopeName) ); 418 allocationFunction(void * _userData,size_t _size,size_t _alignment,VkSystemAllocationScope _allocationScope)419 static void* VKAPI_PTR allocationFunction(void* _userData, size_t _size, size_t _alignment, VkSystemAllocationScope _allocationScope) 420 { 421 BX_UNUSED(_userData, _allocationScope); 422 return bx::alignedAlloc(g_allocator, _size, _alignment, s_allocScopeName[_allocationScope]); 423 } 424 reallocationFunction(void * _userData,void * _original,size_t _size,size_t _alignment,VkSystemAllocationScope _allocationScope)425 static void* VKAPI_PTR reallocationFunction(void* _userData, void* _original, size_t _size, size_t _alignment, VkSystemAllocationScope _allocationScope) 426 { 427 BX_UNUSED(_userData, _allocationScope); 428 return bx::alignedRealloc(g_allocator, _original, _size, _alignment, s_allocScopeName[_allocationScope]); 429 } 430 freeFunction(void * _userData,void * _memory)431 static void VKAPI_PTR freeFunction(void* _userData, void* _memory) 432 { 433 BX_UNUSED(_userData); 434 435 if (NULL == _memory) 436 { 437 return; 438 } 439 440 bx::alignedFree(g_allocator, _memory, 8); 441 } 442 internalAllocationNotification(void * _userData,size_t _size,VkInternalAllocationType _allocationType,VkSystemAllocationScope _allocationScope)443 static void VKAPI_PTR internalAllocationNotification(void* _userData, size_t _size, VkInternalAllocationType _allocationType, VkSystemAllocationScope _allocationScope) 444 { 445 BX_UNUSED(_userData, _size, _allocationType, _allocationScope); 446 } 447 internalFreeNotification(void * _userData,size_t _size,VkInternalAllocationType _allocationType,VkSystemAllocationScope _allocationScope)448 static void VKAPI_PTR internalFreeNotification(void* _userData, size_t _size, VkInternalAllocationType _allocationType, VkSystemAllocationScope _allocationScope) 449 { 450 BX_UNUSED(_userData, _size, _allocationType, _allocationScope); 451 } 452 453 static VkAllocationCallbacks s_allocationCb = 454 { 455 NULL, 456 allocationFunction, 457 reallocationFunction, 458 freeFunction, 459 internalAllocationNotification, 460 internalFreeNotification, 461 }; 462 stubSetDebugUtilsObjectNameEXT(VkDevice _device,const VkDebugUtilsObjectNameInfoEXT * _nameInfo)463 VkResult VKAPI_PTR stubSetDebugUtilsObjectNameEXT(VkDevice _device, const VkDebugUtilsObjectNameInfoEXT* _nameInfo) 464 { 465 BX_UNUSED(_device, _nameInfo); 466 return VK_SUCCESS; 467 } 468 stubCmdInsertDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer,const VkDebugUtilsLabelEXT * _labelInfo)469 void VKAPI_PTR stubCmdInsertDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer, const VkDebugUtilsLabelEXT* _labelInfo) 470 { 471 BX_UNUSED(_commandBuffer, _labelInfo); 472 } 473 stubCmdBeginDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer,const VkDebugUtilsLabelEXT * _labelInfo)474 void VKAPI_PTR stubCmdBeginDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer, const VkDebugUtilsLabelEXT* _labelInfo) 475 { 476 BX_UNUSED(_commandBuffer, _labelInfo); 477 } 478 stubCmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer)479 void VKAPI_PTR stubCmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer) 480 { 481 BX_UNUSED(_commandBuffer); 482 } 483 484 static const char* s_debugReportObjectType[] = 485 { 486 "Unknown", 487 "Instance", 488 "PhysicalDevice", 489 "Device", 490 "Queue", 491 "Semaphore", 492 "CommandBuffer", 493 "Fence", 494 "DeviceMemory", 495 "Buffer", 496 "Image", 497 "Event", 498 "QueryPool", 499 "BufferView", 500 "ImageView", 501 "ShaderModule", 502 "PipelineCache", 503 "PipelineLayout", 504 "RenderPass", 505 "Pipeline", 506 "DescriptorSetLayout", 507 "Sampler", 508 "DescriptorPool", 509 "DescriptorSet", 510 "Framebuffer", 511 "CommandPool", 512 "SurfaceKHR", 513 "SwapchainKHR", 514 "DebugReport", 515 }; 516 debugReportCb(VkDebugReportFlagsEXT _flags,VkDebugReportObjectTypeEXT _objectType,uint64_t _object,size_t _location,int32_t _messageCode,const char * _layerPrefix,const char * _message,void * _userData)517 VkBool32 VKAPI_PTR debugReportCb( 518 VkDebugReportFlagsEXT _flags, 519 VkDebugReportObjectTypeEXT _objectType, 520 uint64_t _object, 521 size_t _location, 522 int32_t _messageCode, 523 const char* _layerPrefix, 524 const char* _message, 525 void* _userData 526 ) 527 { 528 BX_UNUSED(_flags 529 , _objectType 530 , _object 531 , _location 532 , _messageCode 533 , _layerPrefix 534 , _message 535 , _userData 536 , s_debugReportObjectType 537 ); 538 if (!bx::strFind(_message, "PointSizeMissing").isEmpty() 539 || !bx::strFind(_message, "SwapchainTooManyImages").isEmpty() 540 || !bx::strFind(_message, "SwapchainImageNotAcquired").isEmpty()) 541 { 542 return VK_FALSE; 543 } 544 BX_TRACE("%c%c%c%c%c %19s, %s, %d: %s" 545 , 0 != (_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT ) ? 'I' : '-' 546 , 0 != (_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT ) ? 'W' : '-' 547 , 0 != (_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) ? 'P' : '-' 548 , 0 != (_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT ) ? 'E' : '-' 549 , 0 != (_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT ) ? 'D' : '-' 550 , s_debugReportObjectType[_objectType] 551 , _layerPrefix 552 , _messageCode 553 , _message 554 ); 555 return VK_TRUE; 556 } 557 enumerateLayerProperties(VkPhysicalDevice _physicalDevice,uint32_t * _propertyCount,VkLayerProperties * _properties)558 VkResult enumerateLayerProperties(VkPhysicalDevice _physicalDevice, uint32_t* _propertyCount, VkLayerProperties* _properties) 559 { 560 return (VK_NULL_HANDLE == _physicalDevice) 561 ? vkEnumerateInstanceLayerProperties(_propertyCount, _properties) 562 : vkEnumerateDeviceLayerProperties(_physicalDevice, _propertyCount, _properties) 563 ; 564 } 565 enumerateExtensionProperties(VkPhysicalDevice _physicalDevice,const char * _layerName,uint32_t * _propertyCount,VkExtensionProperties * _properties)566 VkResult enumerateExtensionProperties(VkPhysicalDevice _physicalDevice, const char* _layerName, uint32_t* _propertyCount, VkExtensionProperties* _properties) 567 { 568 return (VK_NULL_HANDLE == _physicalDevice) 569 ? vkEnumerateInstanceExtensionProperties(_layerName, _propertyCount, _properties) 570 : vkEnumerateDeviceExtensionProperties(_physicalDevice, _layerName, _propertyCount, _properties) 571 ; 572 } 573 dumpExtensions(VkPhysicalDevice _physicalDevice=VK_NULL_HANDLE)574 void dumpExtensions(VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE) 575 { 576 { // Global extensions. 577 uint32_t numExtensionProperties; 578 VkResult result = enumerateExtensionProperties(_physicalDevice 579 , NULL 580 , &numExtensionProperties 581 , NULL 582 ); 583 584 if (VK_SUCCESS == result 585 && 0 < numExtensionProperties) 586 { 587 VkExtensionProperties extensionProperties[64]; 588 numExtensionProperties = bx::min<uint32_t>(numExtensionProperties, BX_COUNTOF(extensionProperties) ); 589 result = enumerateExtensionProperties(_physicalDevice 590 , NULL 591 , &numExtensionProperties 592 , extensionProperties 593 ); 594 595 BX_TRACE("Global extensions (%d):" 596 , numExtensionProperties 597 ); 598 599 for (uint32_t extension = 0; extension < numExtensionProperties; ++extension) 600 { 601 updateExtension( 602 extensionProperties[extension].extensionName 603 , extensionProperties[extension].specVersion 604 , VK_NULL_HANDLE == _physicalDevice 605 ); 606 } 607 } 608 } 609 610 // Layer extensions. 611 uint32_t numLayerProperties; 612 VkResult result = enumerateLayerProperties(_physicalDevice, &numLayerProperties, NULL); 613 614 if (VK_SUCCESS == result 615 && 0 < numLayerProperties) 616 { 617 VkLayerProperties layerProperties[64]; 618 numLayerProperties = bx::min<uint32_t>(numLayerProperties, BX_COUNTOF(layerProperties) ); 619 result = enumerateLayerProperties(_physicalDevice, &numLayerProperties, layerProperties); 620 621 char indent = VK_NULL_HANDLE == _physicalDevice ? '\0' : '\t'; 622 BX_UNUSED(indent); 623 624 BX_TRACE("%cLayer extensions (%d):" 625 , indent 626 , numLayerProperties 627 ); 628 for (uint32_t layer = 0; layer < numLayerProperties; ++layer) 629 { 630 BX_TRACE("%c\t%s (s: 0x%08x, i: 0x%08x), %s" 631 , indent 632 , layerProperties[layer].layerName 633 , layerProperties[layer].specVersion 634 , layerProperties[layer].implementationVersion 635 , layerProperties[layer].description 636 ); 637 uint32_t numExtensionProperties; 638 result = enumerateExtensionProperties(_physicalDevice 639 , layerProperties[layer].layerName 640 , &numExtensionProperties 641 , NULL 642 ); 643 644 if (VK_SUCCESS == result 645 && 0 < numExtensionProperties) 646 { 647 VkExtensionProperties extensionProperties[64]; 648 numExtensionProperties = bx::min<uint32_t>(numExtensionProperties, BX_COUNTOF(extensionProperties) ); 649 result = enumerateExtensionProperties(_physicalDevice 650 , layerProperties[layer].layerName 651 , &numExtensionProperties 652 , extensionProperties 653 ); 654 655 for (uint32_t extension = 0; extension < numExtensionProperties; ++extension) 656 { 657 BX_TRACE("%c\t\t%s (s: 0x%08x)" 658 , indent 659 , extensionProperties[extension].extensionName 660 , extensionProperties[extension].specVersion 661 ); 662 } 663 } 664 } 665 } 666 } 667 getName(VkResult _result)668 const char* getName(VkResult _result) 669 { 670 switch (_result) 671 { 672 #define VKENUM(_ty) case _ty: return #_ty 673 VKENUM(VK_SUCCESS); 674 VKENUM(VK_NOT_READY); 675 VKENUM(VK_TIMEOUT); 676 VKENUM(VK_EVENT_SET); 677 VKENUM(VK_EVENT_RESET); 678 VKENUM(VK_INCOMPLETE); 679 VKENUM(VK_ERROR_OUT_OF_HOST_MEMORY); 680 VKENUM(VK_ERROR_OUT_OF_DEVICE_MEMORY); 681 VKENUM(VK_ERROR_INITIALIZATION_FAILED); 682 VKENUM(VK_ERROR_DEVICE_LOST); 683 VKENUM(VK_ERROR_MEMORY_MAP_FAILED); 684 VKENUM(VK_ERROR_LAYER_NOT_PRESENT); 685 VKENUM(VK_ERROR_EXTENSION_NOT_PRESENT); 686 VKENUM(VK_ERROR_FEATURE_NOT_PRESENT); 687 VKENUM(VK_ERROR_INCOMPATIBLE_DRIVER); 688 VKENUM(VK_ERROR_TOO_MANY_OBJECTS); 689 VKENUM(VK_ERROR_FORMAT_NOT_SUPPORTED); 690 VKENUM(VK_ERROR_SURFACE_LOST_KHR); 691 VKENUM(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); 692 VKENUM(VK_SUBOPTIMAL_KHR); 693 VKENUM(VK_ERROR_OUT_OF_DATE_KHR); 694 VKENUM(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR); 695 VKENUM(VK_ERROR_VALIDATION_FAILED_EXT); 696 #undef VKENUM 697 default: break; 698 } 699 700 BX_WARN(false, "Unknown VkResult? %x", _result); 701 return "<VkResult?>"; 702 } 703 704 template<typename Ty> 705 VkObjectType getType(); 706 getType()707 template<> VkObjectType getType<VkBuffer >() { return VK_OBJECT_TYPE_BUFFER; } getType()708 template<> VkObjectType getType<VkShaderModule>() { return VK_OBJECT_TYPE_SHADER_MODULE; } 709 710 template<typename Ty> setDebugObjectName(VkDevice _device,Ty _object,const char * _format,...)711 static BX_NO_INLINE void setDebugObjectName(VkDevice _device, Ty _object, const char* _format, ...) 712 { 713 if (BX_ENABLED(BGFX_CONFIG_DEBUG_OBJECT_NAME) && s_extension[Extension::EXT_debug_utils].m_supported) 714 { 715 char temp[2048]; 716 va_list argList; 717 va_start(argList, _format); 718 int32_t size = bx::min<int32_t>(sizeof(temp)-1, bx::vsnprintf(temp, sizeof(temp), _format, argList) ); 719 va_end(argList); 720 temp[size] = '\0'; 721 722 VkDebugUtilsObjectNameInfoEXT ni; 723 ni.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; 724 ni.pNext = NULL; 725 ni.objectType = getType<Ty>(); 726 ni.objectHandle = uint64_t(_object.vk); 727 ni.pObjectName = temp; 728 729 VK_CHECK(vkSetDebugUtilsObjectNameEXT(_device, &ni) ); 730 } 731 } 732 setImageMemoryBarrier(VkCommandBuffer _commandBuffer,VkImage _image,VkImageAspectFlags _aspectMask,VkImageLayout _oldLayout,VkImageLayout _newLayout,uint32_t _levelCount,uint32_t _layerCount)733 void setImageMemoryBarrier(VkCommandBuffer _commandBuffer, VkImage _image, VkImageAspectFlags _aspectMask, VkImageLayout _oldLayout, VkImageLayout _newLayout, uint32_t _levelCount, uint32_t _layerCount) 734 { 735 BX_CHECK(true 736 && _newLayout != VK_IMAGE_LAYOUT_UNDEFINED 737 && _newLayout != VK_IMAGE_LAYOUT_PREINITIALIZED 738 , "_newLayout cannot use VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED." 739 ); 740 741 VkAccessFlags srcAccessMask = 0; 742 VkAccessFlags dstAccessMask = 0; 743 744 switch (_oldLayout) 745 { 746 case VK_IMAGE_LAYOUT_UNDEFINED: 747 // srcAccessMask |= VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 748 break; 749 750 case VK_IMAGE_LAYOUT_GENERAL: 751 break; 752 753 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 754 srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 755 break; 756 757 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 758 srcAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 759 break; 760 761 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 762 break; 763 764 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 765 srcAccessMask |= VK_ACCESS_SHADER_READ_BIT; 766 break; 767 768 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 769 srcAccessMask |= VK_ACCESS_TRANSFER_READ_BIT; 770 break; 771 772 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 773 break; 774 775 case VK_IMAGE_LAYOUT_PREINITIALIZED: 776 srcAccessMask |= VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 777 break; 778 779 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: 780 srcAccessMask |= VK_ACCESS_MEMORY_READ_BIT; 781 break; 782 783 default: 784 break; 785 } 786 787 switch (_newLayout) 788 { 789 case VK_IMAGE_LAYOUT_UNDEFINED: 790 break; 791 792 case VK_IMAGE_LAYOUT_GENERAL: 793 break; 794 795 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 796 dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 797 break; 798 799 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 800 dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 801 // aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 802 break; 803 804 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 805 break; 806 807 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 808 dstAccessMask |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; 809 break; 810 811 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 812 dstAccessMask |= VK_ACCESS_SHADER_READ_BIT; 813 break; 814 815 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 816 dstAccessMask |= VK_ACCESS_TRANSFER_READ_BIT; 817 break; 818 819 case VK_IMAGE_LAYOUT_PREINITIALIZED: 820 break; 821 822 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: 823 dstAccessMask |= VK_ACCESS_MEMORY_READ_BIT; 824 break; 825 826 default: 827 break; 828 } 829 830 VkImageMemoryBarrier imb; 831 imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 832 imb.pNext = NULL; 833 imb.srcAccessMask = srcAccessMask; 834 imb.dstAccessMask = dstAccessMask; 835 imb.oldLayout = _oldLayout; 836 imb.newLayout = _newLayout; 837 imb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 838 imb.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 839 imb.image = _image; 840 imb.subresourceRange.aspectMask = _aspectMask; 841 imb.subresourceRange.baseMipLevel = 0; 842 imb.subresourceRange.levelCount = _levelCount; 843 imb.subresourceRange.baseArrayLayer = 0; 844 imb.subresourceRange.layerCount = _layerCount; 845 vkCmdPipelineBarrier(_commandBuffer 846 , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT 847 , VK_PIPELINE_STAGE_ALL_COMMANDS_BIT 848 , 0 849 , 0 850 , NULL 851 , 0 852 , NULL 853 , 1 854 , &imb 855 ); 856 } 857 858 struct RendererContextVK : public RendererContextI 859 { RendererContextVKbgfx::vk::RendererContextVK860 RendererContextVK() 861 : m_allocatorCb(NULL) 862 , m_renderDocDll(NULL) 863 , m_vulkan1Dll(NULL) 864 , m_maxAnisotropy(1) 865 , m_depthClamp(false) 866 , m_wireframe(false) 867 { 868 } 869 ~RendererContextVKbgfx::vk::RendererContextVK870 ~RendererContextVK() 871 { 872 } 873 createSwapchainbgfx::vk::RendererContextVK874 VkResult createSwapchain() 875 { 876 VkResult result = VK_SUCCESS; 877 result = vkCreateSwapchainKHR(m_device, &m_sci, m_allocatorCb, &m_swapchain); 878 if (VK_SUCCESS != result) 879 { 880 BX_TRACE("Create swapchain error: vkCreateSwapchainKHR failed %d: %s.", result, getName(result)); 881 return result; 882 } 883 884 result = vkGetSwapchainImagesKHR(m_device, m_swapchain, &m_numSwapchainImages, NULL); 885 if (VK_SUCCESS != result) 886 { 887 BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s.", result, getName(result)); 888 return result; 889 } 890 891 if (m_numSwapchainImages < m_sci.minImageCount) 892 { 893 BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR: numSwapchainImages %d < minImageCount %d." 894 , m_numSwapchainImages 895 , m_sci.minImageCount 896 ); 897 return VK_ERROR_INITIALIZATION_FAILED; 898 } 899 900 result = vkGetSwapchainImagesKHR(m_device, m_swapchain, &m_numSwapchainImages, &m_backBufferColorImage[0]); 901 if (VK_SUCCESS != result && VK_INCOMPLETE != result) 902 { 903 BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s.", result, getName(result)); 904 return result; 905 } 906 907 VkImageCreateInfo ici; 908 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 909 ici.pNext = NULL; 910 ici.flags = 0; 911 ici.imageType = VK_IMAGE_TYPE_2D; 912 ici.format = m_backBufferDepthStencilFormat; 913 ici.extent.width = m_sci.imageExtent.width; 914 ici.extent.height = m_sci.imageExtent.height; 915 ici.extent.depth = 1; 916 ici.mipLevels = 1; 917 ici.arrayLayers = 1; 918 ici.samples = VK_SAMPLE_COUNT_1_BIT; 919 ici.tiling = VK_IMAGE_TILING_OPTIMAL; 920 ici.usage = 0 921 | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT 922 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT 923 ; 924 ici.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 925 ici.queueFamilyIndexCount = 0; //m_sci.queueFamilyIndexCount; 926 ici.pQueueFamilyIndices = NULL; //m_sci.pQueueFamilyIndices; 927 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 928 result = vkCreateImage(m_device, &ici, m_allocatorCb, &m_backBufferDepthStencilImage); 929 930 if (VK_SUCCESS != result) 931 { 932 BX_TRACE("Create swapchain error: vkCreateImage failed %d: %s.", result, getName(result)); 933 return result; 934 } 935 936 VkMemoryRequirements mr; 937 vkGetImageMemoryRequirements(m_device, m_backBufferDepthStencilImage, &mr); 938 939 VkMemoryAllocateInfo ma; 940 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 941 ma.pNext = NULL; 942 ma.allocationSize = mr.size; 943 ma.memoryTypeIndex = selectMemoryType(mr.memoryTypeBits 944 , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 945 ); 946 result = vkAllocateMemory(m_device 947 , &ma 948 , m_allocatorCb 949 , &m_backBufferDepthStencilMemory 950 ); 951 952 if (VK_SUCCESS != result) 953 { 954 BX_TRACE("Create swapchain error: vkAllocateMemory failed %d: %s.", result, getName(result)); 955 return result; 956 } 957 958 result = vkBindImageMemory(m_device, m_backBufferDepthStencilImage, m_backBufferDepthStencilMemory, 0); 959 960 if (VK_SUCCESS != result) 961 { 962 BX_TRACE("Create swapchain error: vkBindImageMemory failed %d: %s.", result, getName(result)); 963 return result; 964 } 965 966 VkImageViewCreateInfo ivci; 967 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 968 ivci.pNext = NULL; 969 ivci.flags = 0; 970 ivci.image = m_backBufferDepthStencilImage; 971 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 972 ivci.format = m_backBufferDepthStencilFormat; 973 ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 974 ivci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 975 ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 976 ivci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 977 ivci.subresourceRange.aspectMask = 0 978 | VK_IMAGE_ASPECT_DEPTH_BIT 979 | VK_IMAGE_ASPECT_STENCIL_BIT 980 ; 981 ivci.subresourceRange.baseMipLevel = 0; 982 ivci.subresourceRange.levelCount = 1; 983 ivci.subresourceRange.baseArrayLayer = 0; 984 ivci.subresourceRange.layerCount = 1; 985 result = vkCreateImageView(m_device, &ivci, m_allocatorCb, &m_backBufferDepthStencilImageView); 986 987 if (VK_SUCCESS != result) 988 { 989 BX_TRACE("Create swapchain error: vkCreateImageView failed %d: %s.", result, getName(result)); 990 return result; 991 } 992 993 for (uint32_t ii = 0; ii < m_numSwapchainImages; ++ii) 994 { 995 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 996 ivci.pNext = NULL; 997 ivci.flags = 0; 998 ivci.image = m_backBufferColorImage[ii]; 999 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 1000 ivci.format = m_sci.imageFormat; 1001 ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 1002 ivci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 1003 ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 1004 ivci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 1005 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1006 ivci.subresourceRange.baseMipLevel = 0; 1007 ivci.subresourceRange.levelCount = 1; 1008 ivci.subresourceRange.baseArrayLayer = 0; 1009 ivci.subresourceRange.layerCount = 1; 1010 1011 result = vkCreateImageView(m_device, &ivci, m_allocatorCb, &m_backBufferColorImageView[ii]); 1012 1013 if (VK_SUCCESS != result) 1014 { 1015 BX_TRACE("Create swapchain error: vkCreateImageView failed %d: %s.", result, getName(result)); 1016 return result; 1017 } 1018 1019 m_backBufferColorImageLayout[ii] = VK_IMAGE_LAYOUT_UNDEFINED; 1020 } 1021 1022 m_needToRefreshSwapchain = false; 1023 1024 return result; 1025 } 1026 releaseSwapchainbgfx::vk::RendererContextVK1027 void releaseSwapchain() 1028 { 1029 VK_CHECK(vkDeviceWaitIdle(m_device) ); 1030 vkFreeMemory(m_device, m_backBufferDepthStencilMemory, m_allocatorCb); 1031 vkDestroy(m_backBufferDepthStencilImageView); 1032 vkDestroy(m_backBufferDepthStencilImage); 1033 for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii) 1034 { 1035 vkDestroy(m_backBufferColorImageView[ii]); 1036 m_backBufferColorImageLayout[ii] = VK_IMAGE_LAYOUT_UNDEFINED; 1037 } 1038 vkDestroy(m_swapchain); 1039 } 1040 createSwapchainFramebufferbgfx::vk::RendererContextVK1041 VkResult createSwapchainFramebuffer() 1042 { 1043 VkResult result = VK_SUCCESS; 1044 for (uint32_t ii = 0; ii < m_numSwapchainImages; ++ii) 1045 { 1046 ::VkImageView attachments[] = 1047 { 1048 m_backBufferColorImageView[ii], 1049 m_backBufferDepthStencilImageView, 1050 }; 1051 1052 VkFramebufferCreateInfo fci; 1053 fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 1054 fci.pNext = NULL; 1055 fci.flags = 0; 1056 fci.renderPass = m_renderPass; 1057 fci.attachmentCount = BX_COUNTOF(attachments); 1058 fci.pAttachments = attachments; 1059 fci.width = m_sci.imageExtent.width; 1060 fci.height = m_sci.imageExtent.height; 1061 fci.layers = 1; 1062 1063 result = vkCreateFramebuffer(m_device, &fci, m_allocatorCb, &m_backBufferColor[ii]); 1064 1065 if (VK_SUCCESS != result) 1066 { 1067 return result; 1068 } 1069 } 1070 return result; 1071 } 1072 releaseSwapchainFramebufferbgfx::vk::RendererContextVK1073 void releaseSwapchainFramebuffer() 1074 { 1075 for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii) 1076 { 1077 vkDestroy(m_backBufferColor[ii]); 1078 } 1079 } 1080 initSwapchainImageLayoutbgfx::vk::RendererContextVK1081 void initSwapchainImageLayout() 1082 { 1083 VkCommandBuffer commandBuffer = beginNewCommand(); 1084 1085 setImageMemoryBarrier( 1086 commandBuffer 1087 , m_backBufferDepthStencilImage 1088 , VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT 1089 , VK_IMAGE_LAYOUT_UNDEFINED 1090 , VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL 1091 , 1 1092 , 1 1093 ); 1094 1095 m_backBufferColorIdx = 0; 1096 submitCommandAndWait(commandBuffer); 1097 } 1098 initbgfx::vk::RendererContextVK1099 bool init(const Init& _init) 1100 { 1101 BX_UNUSED(s_checkMsaa, s_textureAddress); 1102 1103 struct ErrorState 1104 { 1105 enum Enum 1106 { 1107 Default, 1108 LoadedVulkan1, 1109 InstanceCreated, 1110 DeviceCreated, 1111 SurfaceCreated, 1112 SwapchainCreated, 1113 RenderPassCreated, 1114 FrameBufferCreated, 1115 CommandBuffersCreated, 1116 DescriptorCreated, 1117 }; 1118 }; 1119 1120 ErrorState::Enum errorState = ErrorState::Default; 1121 1122 m_fbh.idx = kInvalidHandle; 1123 bx::memSet(m_uniforms, 0, sizeof(m_uniforms) ); 1124 bx::memSet(&m_resolution, 0, sizeof(m_resolution) ); 1125 1126 bool imported = true; 1127 VkResult result; 1128 m_qfiGraphics = UINT32_MAX; 1129 m_qfiCompute = UINT32_MAX; 1130 1131 if (_init.debug 1132 || _init.profile) 1133 { 1134 m_renderDocDll = loadRenderDoc(); 1135 } 1136 1137 m_vulkan1Dll = bx::dlopen( 1138 #if BX_PLATFORM_WINDOWS 1139 "vulkan-1.dll" 1140 #elif BX_PLATFORM_ANDROID 1141 "libvulkan.so" 1142 #elif BX_PLATFORM_OSX 1143 "libvulkan.dylib" 1144 #else 1145 "libvulkan.so.1" 1146 #endif // BX_PLATFORM_* 1147 ); 1148 1149 if (NULL == m_vulkan1Dll) 1150 { 1151 BX_TRACE("Init error: Failed to load vulkan dynamic library."); 1152 goto error; 1153 } 1154 1155 errorState = ErrorState::LoadedVulkan1; 1156 1157 BX_TRACE("Shared library functions:"); 1158 #define VK_IMPORT_FUNC(_optional, _func) \ 1159 _func = (PFN_##_func)bx::dlsym(m_vulkan1Dll, #_func); \ 1160 BX_TRACE("\t%p " #_func, _func); \ 1161 imported &= _optional || NULL != _func 1162 VK_IMPORT 1163 #undef VK_IMPORT_FUNC 1164 1165 if (!imported) 1166 { 1167 BX_TRACE("Init error: Failed to load shared library functions."); 1168 goto error; 1169 } 1170 1171 { 1172 dumpExtensions(); 1173 1174 VkApplicationInfo appInfo; 1175 appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 1176 appInfo.pNext = NULL; 1177 appInfo.pApplicationName = "bgfx"; 1178 appInfo.applicationVersion = BGFX_API_VERSION; 1179 appInfo.pEngineName = "bgfx"; 1180 appInfo.engineVersion = BGFX_API_VERSION; 1181 appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 0); //VK_HEADER_VERSION); 1182 1183 const char* enabledLayerNames[] = 1184 { 1185 #if BGFX_CONFIG_DEBUG 1186 // "VK_LAYER_GOOGLE_threading", 1187 // "VK_LAYER_GOOGLE_unique_objects", 1188 // "VK_LAYER_LUNARG_device_limits", 1189 "VK_LAYER_LUNARG_standard_validation", 1190 // "VK_LAYER_LUNARG_image", 1191 // "VK_LAYER_LUNARG_mem_tracker", 1192 // "VK_LAYER_LUNARG_core_validation", 1193 // "VK_LAYER_LUNARG_object_tracker", 1194 // "VK_LAYER_LUNARG_parameter_validation", 1195 // "VK_LAYER_LUNARG_swapchain", 1196 // "VK_LAYER_LUNARG_vktrace", 1197 // "VK_LAYER_RENDERDOC_Capture", 1198 #endif // BGFX_CONFIG_DEBUG 1199 /*not used*/ "" 1200 }; 1201 1202 uint32_t numEnabledExtensions = 2; 1203 1204 const char* enabledExtension[Extension::Count + 2] = 1205 { 1206 VK_KHR_SURFACE_EXTENSION_NAME, 1207 KHR_SURFACE_EXTENSION_NAME, 1208 }; 1209 1210 for (uint32_t ii = 0; ii < Extension::Count; ++ii) 1211 { 1212 const Extension& extension = s_extension[ii]; 1213 1214 if (extension.m_supported 1215 && extension.m_initialize 1216 && extension.m_instanceExt) 1217 { 1218 enabledExtension[numEnabledExtensions++] = extension.m_name; 1219 BX_TRACE("%d: %s", numEnabledExtensions, extension.m_name); 1220 } 1221 } 1222 1223 VkInstanceCreateInfo ici; 1224 ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 1225 ici.pNext = NULL; 1226 ici.flags = 0; 1227 ici.pApplicationInfo = &appInfo; 1228 ici.enabledLayerCount = BX_COUNTOF(enabledLayerNames) - 1; 1229 ici.ppEnabledLayerNames = enabledLayerNames; 1230 ici.enabledExtensionCount = numEnabledExtensions; 1231 ici.ppEnabledExtensionNames = enabledExtension; 1232 1233 if (BX_ENABLED(BGFX_CONFIG_DEBUG) ) 1234 { 1235 m_allocatorCb = &s_allocationCb; 1236 BX_UNUSED(s_allocationCb); 1237 } 1238 1239 result = vkCreateInstance(&ici 1240 , m_allocatorCb 1241 , &m_instance 1242 ); 1243 } 1244 1245 if (VK_SUCCESS != result) 1246 { 1247 BX_TRACE("Init error: vkCreateInstance failed %d: %s.", result, getName(result) ); 1248 goto error; 1249 } 1250 1251 errorState = ErrorState::InstanceCreated; 1252 1253 BX_TRACE("Instance functions:"); 1254 1255 #define VK_IMPORT_INSTANCE_FUNC(_optional, _func) \ 1256 _func = (PFN_##_func)vkGetInstanceProcAddr(m_instance, #_func); \ 1257 BX_TRACE("\t%p " #_func, _func); \ 1258 imported &= _optional || NULL != _func 1259 VK_IMPORT_INSTANCE 1260 #undef VK_IMPORT_INSTANCE_FUNC 1261 1262 if (!imported) 1263 { 1264 BX_TRACE("Init error: Failed to load instance functions."); 1265 goto error; 1266 } 1267 1268 m_debugReportCallback = VK_NULL_HANDLE; 1269 1270 if (s_extension[Extension::EXT_debug_report].m_supported) 1271 { 1272 VkDebugReportCallbackCreateInfoEXT drcb; 1273 drcb.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 1274 drcb.pNext = NULL; 1275 drcb.pfnCallback = debugReportCb; 1276 drcb.pUserData = NULL; 1277 drcb.flags = 0 1278 | VK_DEBUG_REPORT_ERROR_BIT_EXT 1279 | VK_DEBUG_REPORT_WARNING_BIT_EXT 1280 ; 1281 result = vkCreateDebugReportCallbackEXT(m_instance 1282 , &drcb 1283 , m_allocatorCb 1284 , &m_debugReportCallback 1285 ); 1286 BX_WARN(VK_SUCCESS == result, "vkCreateDebugReportCallbackEXT failed %d: %s.", result, getName(result) ); 1287 } 1288 1289 { 1290 BX_TRACE("---"); 1291 1292 uint32_t numPhysicalDevices; 1293 result = vkEnumeratePhysicalDevices(m_instance 1294 , &numPhysicalDevices 1295 , NULL 1296 ); 1297 1298 if (VK_SUCCESS != result) 1299 { 1300 BX_TRACE("Init error: vkEnumeratePhysicalDevices failed %d: %s.", result, getName(result) ); 1301 goto error; 1302 } 1303 1304 VkPhysicalDevice physicalDevices[4]; 1305 numPhysicalDevices = bx::min<uint32_t>(numPhysicalDevices, BX_COUNTOF(physicalDevices) ); 1306 result = vkEnumeratePhysicalDevices(m_instance 1307 , &numPhysicalDevices 1308 , physicalDevices 1309 ); 1310 1311 if (VK_SUCCESS != result) 1312 { 1313 BX_TRACE("Init error: vkEnumeratePhysicalDevices failed %d: %s.", result, getName(result) ); 1314 goto error; 1315 } 1316 1317 m_physicalDevice = VK_NULL_HANDLE; 1318 1319 for (uint32_t ii = 0; ii < numPhysicalDevices; ++ii) 1320 { 1321 VkPhysicalDeviceProperties pdp; 1322 vkGetPhysicalDeviceProperties(physicalDevices[ii], &pdp); 1323 BX_TRACE("Physical device %d:", ii); 1324 BX_TRACE("\t Name: %s", pdp.deviceName); 1325 BX_TRACE("\t API version: %x", pdp.apiVersion); 1326 BX_TRACE("\tDriver version: %x", pdp.driverVersion); 1327 BX_TRACE("\t VendorId: %x", pdp.vendorID); 1328 BX_TRACE("\t DeviceId: %x", pdp.deviceID); 1329 BX_TRACE("\t Type: %d", pdp.deviceType); 1330 1331 g_caps.gpu[ii].vendorId = uint16_t(pdp.vendorID); 1332 g_caps.gpu[ii].deviceId = uint16_t(pdp.deviceID); 1333 ++g_caps.numGPUs; 1334 1335 if ( (BGFX_PCI_ID_NONE != g_caps.vendorId || 0 != g_caps.deviceId) 1336 && (BGFX_PCI_ID_NONE == g_caps.vendorId || pdp.vendorID == g_caps.vendorId) 1337 && (0 == g_caps.deviceId || pdp.deviceID == g_caps.deviceId) ) 1338 { 1339 m_physicalDevice = physicalDevices[ii]; 1340 } 1341 1342 VkPhysicalDeviceMemoryProperties pdmp; 1343 vkGetPhysicalDeviceMemoryProperties(physicalDevices[ii], &pdmp); 1344 1345 BX_TRACE("\tMemory type count: %d", pdmp.memoryTypeCount); 1346 for (uint32_t jj = 0; jj < pdmp.memoryTypeCount; ++jj) 1347 { 1348 BX_TRACE("\t%3d: flags 0x%08x, index %d" 1349 , jj 1350 , pdmp.memoryTypes[jj].propertyFlags 1351 , pdmp.memoryTypes[jj].heapIndex 1352 ); 1353 } 1354 1355 BX_TRACE("\tMemory heap count: %d", pdmp.memoryHeapCount); 1356 for (uint32_t jj = 0; jj < pdmp.memoryHeapCount; ++jj) 1357 { 1358 char size[16]; 1359 bx::prettify(size, BX_COUNTOF(size), pdmp.memoryHeaps[jj].size); 1360 BX_TRACE("\t%3d: flags 0x%08x, size %10s" 1361 , jj 1362 , pdmp.memoryHeaps[jj].flags 1363 , size 1364 ); 1365 } 1366 1367 dumpExtensions(physicalDevices[ii]); 1368 } 1369 1370 if (VK_NULL_HANDLE == m_physicalDevice) 1371 { 1372 m_physicalDevice = physicalDevices[0]; 1373 } 1374 1375 vkGetPhysicalDeviceProperties(m_physicalDevice, &m_deviceProperties); 1376 g_caps.vendorId = uint16_t(m_deviceProperties.vendorID); 1377 g_caps.deviceId = uint16_t(m_deviceProperties.deviceID); 1378 1379 g_caps.supported |= ( 0 1380 | BGFX_CAPS_ALPHA_TO_COVERAGE 1381 | BGFX_CAPS_BLEND_INDEPENDENT 1382 | BGFX_CAPS_COMPUTE 1383 | BGFX_CAPS_DRAW_INDIRECT 1384 | BGFX_CAPS_FRAGMENT_DEPTH 1385 | BGFX_CAPS_INSTANCING 1386 | BGFX_CAPS_TEXTURE_3D 1387 | BGFX_CAPS_TEXTURE_BLIT 1388 | BGFX_CAPS_TEXTURE_COMPARE_ALL 1389 | BGFX_CAPS_VERTEX_ATTRIB_HALF 1390 | BGFX_CAPS_VERTEX_ATTRIB_UINT10 1391 | BGFX_CAPS_VERTEX_ID 1392 ); 1393 g_caps.limits.maxTextureSize = m_deviceProperties.limits.maxImageDimension2D; 1394 g_caps.limits.maxFBAttachments = bx::min(uint8_t(m_deviceProperties.limits.maxFragmentOutputAttachments), uint8_t(BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); 1395 g_caps.limits.maxComputeBindings = BGFX_MAX_COMPUTE_BINDINGS; 1396 g_caps.limits.maxVertexStreams = BGFX_CONFIG_MAX_VERTEX_STREAMS; 1397 1398 vkGetPhysicalDeviceFeatures(m_physicalDevice, &m_deviceFeatures); 1399 m_deviceFeatures.robustBufferAccess = VK_FALSE; 1400 1401 { 1402 struct ImageTest 1403 { 1404 VkImageType type; 1405 VkImageUsageFlags usage; 1406 VkImageCreateFlags flags; 1407 uint32_t formatCaps[2]; 1408 }; 1409 1410 const ImageTest imageTest[] = 1411 { 1412 { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_SAMPLED_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_2D, BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB } }, 1413 { VK_IMAGE_TYPE_3D, VK_IMAGE_USAGE_SAMPLED_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_3D, BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB } }, 1414 { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, { BGFX_CAPS_FORMAT_TEXTURE_CUBE, BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB } }, 1415 { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER, BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER } }, 1416 { VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, { BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER, BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER } }, 1417 }; 1418 1419 for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) 1420 { 1421 uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; 1422 1423 const bool depth = bimg::isDepth(bimg::TextureFormat::Enum(ii) ); 1424 VkFormat fmt = depth 1425 ? s_textureFormat[ii].m_fmtDsv 1426 : s_textureFormat[ii].m_fmt 1427 ; 1428 1429 for (uint32_t jj = 0, num = depth ? 1 : 2; jj < num; ++jj) 1430 { 1431 if (VK_FORMAT_UNDEFINED != fmt) 1432 { 1433 for (uint32_t test = 0; test < BX_COUNTOF(imageTest); ++test) 1434 { 1435 const ImageTest& it = imageTest[test]; 1436 1437 VkImageFormatProperties ifp; 1438 result = vkGetPhysicalDeviceImageFormatProperties(m_physicalDevice 1439 , fmt 1440 , it.type 1441 , VK_IMAGE_TILING_OPTIMAL 1442 , it.usage 1443 , it.flags 1444 , &ifp 1445 ); 1446 1447 if (VK_SUCCESS == result) 1448 { 1449 support |= it.formatCaps[jj]; 1450 if (VK_SAMPLE_COUNT_1_BIT < ifp.sampleCounts) 1451 { 1452 support |= BGFX_CAPS_FORMAT_TEXTURE_MSAA; 1453 } 1454 } 1455 } 1456 } 1457 1458 fmt = s_textureFormat[ii].m_fmtSrgb; 1459 } 1460 1461 g_caps.formats[ii] = support; 1462 } 1463 } 1464 1465 vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &m_memoryProperties); 1466 } 1467 1468 { 1469 BX_TRACE("---"); 1470 1471 uint32_t queueFamilyPropertyCount = 0; 1472 vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice 1473 , &queueFamilyPropertyCount 1474 , NULL 1475 ); 1476 1477 VkQueueFamilyProperties queueFamilyPropertices[10]; 1478 queueFamilyPropertyCount = bx::min<uint32_t>(queueFamilyPropertyCount, BX_COUNTOF(queueFamilyPropertices) ); 1479 vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice 1480 , &queueFamilyPropertyCount 1481 , queueFamilyPropertices 1482 ); 1483 1484 for (uint32_t ii = 0; ii < queueFamilyPropertyCount; ++ii) 1485 { 1486 const VkQueueFamilyProperties& qfp = queueFamilyPropertices[ii]; 1487 BX_UNUSED(qfp); 1488 BX_TRACE("Queue family property %d:", ii); 1489 BX_TRACE("\t Queue flags: 0x%08x", qfp.queueFlags); 1490 BX_TRACE("\t Queue count: %d", qfp.queueCount); 1491 BX_TRACE("\tTS valid bits: 0x%08x", qfp.timestampValidBits); 1492 BX_TRACE("\t Min image: %d x %d x %d" 1493 , qfp.minImageTransferGranularity.width 1494 , qfp.minImageTransferGranularity.height 1495 , qfp.minImageTransferGranularity.depth 1496 ); 1497 } 1498 1499 for (uint32_t ii = 0; ii < queueFamilyPropertyCount; ++ii) 1500 { 1501 const VkQueueFamilyProperties& qfp = queueFamilyPropertices[ii]; 1502 if (UINT32_MAX == m_qfiGraphics 1503 && VK_QUEUE_GRAPHICS_BIT & qfp.queueFlags) 1504 { 1505 m_qfiGraphics = ii; 1506 } 1507 1508 if (UINT32_MAX == m_qfiCompute 1509 && VK_QUEUE_COMPUTE_BIT & qfp.queueFlags) 1510 { 1511 m_qfiCompute = ii; 1512 } 1513 1514 if (UINT32_MAX != m_qfiGraphics 1515 && UINT32_MAX != m_qfiCompute) 1516 { 1517 break; 1518 } 1519 } 1520 1521 if (UINT32_MAX == m_qfiGraphics) 1522 { 1523 BX_TRACE("Init error: Unable to find graphics queue."); 1524 goto error; 1525 } 1526 } 1527 1528 if (m_qfiCompute != UINT32_MAX) 1529 { 1530 g_caps.supported |= BGFX_CAPS_COMPUTE; 1531 } 1532 1533 { 1534 const char* enabledLayerNames[] = 1535 { 1536 #if BGFX_CONFIG_DEBUG 1537 "VK_LAYER_GOOGLE_threading", 1538 // "VK_LAYER_GOOGLE_unique_objects", 1539 "VK_LAYER_LUNARG_device_limits", 1540 // "VK_LAYER_LUNARG_standard_validation", 1541 "VK_LAYER_LUNARG_image", 1542 "VK_LAYER_LUNARG_object_tracker", 1543 "VK_LAYER_LUNARG_parameter_validation", 1544 "VK_LAYER_LUNARG_swapchain", 1545 // "VK_LAYER_LUNARG_vktrace", 1546 // "VK_LAYER_RENDERDOC_Capture", 1547 #endif // BGFX_CONFIG_DEBUG 1548 /*not used*/ "" 1549 }; 1550 1551 uint32_t numEnabledExtensions = 1; 1552 1553 const char* enabledExtension[Extension::Count + 1] = 1554 { 1555 VK_KHR_SWAPCHAIN_EXTENSION_NAME, 1556 }; 1557 1558 for (uint32_t ii = 0; ii < Extension::Count; ++ii) 1559 { 1560 const Extension& extension = s_extension[ii]; 1561 1562 if (extension.m_supported 1563 && extension.m_initialize 1564 && !extension.m_instanceExt) 1565 { 1566 enabledExtension[numEnabledExtensions++] = extension.m_name; 1567 BX_TRACE("%d: %s", numEnabledExtensions, extension.m_name); 1568 } 1569 } 1570 1571 float queuePriorities[1] = { 0.0f }; 1572 VkDeviceQueueCreateInfo dcqi; 1573 dcqi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 1574 dcqi.pNext = NULL; 1575 dcqi.flags = 0; 1576 dcqi.queueFamilyIndex = m_qfiGraphics; 1577 dcqi.queueCount = 1; 1578 dcqi.pQueuePriorities = queuePriorities; 1579 1580 VkDeviceCreateInfo dci; 1581 dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 1582 dci.pNext = NULL; 1583 dci.flags = 0; 1584 dci.queueCreateInfoCount = 1; 1585 dci.pQueueCreateInfos = &dcqi; 1586 dci.enabledLayerCount = BX_COUNTOF(enabledLayerNames) - 1; 1587 dci.ppEnabledLayerNames = enabledLayerNames; 1588 dci.enabledExtensionCount = numEnabledExtensions; 1589 dci.ppEnabledExtensionNames = enabledExtension; 1590 dci.pEnabledFeatures = &m_deviceFeatures; 1591 1592 result = vkCreateDevice( 1593 m_physicalDevice 1594 , &dci 1595 , m_allocatorCb 1596 , &m_device 1597 ); 1598 1599 if (VK_SUCCESS != result) 1600 { 1601 BX_TRACE("Init error: vkCreateDevice failed %d: %s.", result, getName(result) ); 1602 goto error; 1603 } 1604 } 1605 1606 errorState = ErrorState::DeviceCreated; 1607 1608 BX_TRACE("Device functions:"); 1609 #define VK_IMPORT_DEVICE_FUNC(_optional, _func) \ 1610 _func = (PFN_##_func)vkGetDeviceProcAddr(m_device, #_func); \ 1611 BX_TRACE("\t%p " #_func, _func); \ 1612 imported &= _optional || NULL != _func 1613 VK_IMPORT_DEVICE 1614 #undef VK_IMPORT_DEVICE_FUNC 1615 1616 if (!imported) 1617 { 1618 BX_TRACE("Init error: Failed to load device functions."); 1619 goto error; 1620 } 1621 1622 vkGetDeviceQueue(m_device, m_qfiGraphics, 0, &m_queueGraphics); 1623 vkGetDeviceQueue(m_device, m_qfiCompute, 0, &m_queueCompute); 1624 1625 #if BX_PLATFORM_WINDOWS 1626 { 1627 VkWin32SurfaceCreateInfoKHR sci; 1628 sci.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; 1629 sci.pNext = NULL; 1630 sci.flags = 0; 1631 sci.hinstance = (HINSTANCE)GetModuleHandle(NULL); 1632 sci.hwnd = (HWND)g_platformData.nwh; 1633 result = vkCreateWin32SurfaceKHR(m_instance, &sci, m_allocatorCb, &m_surface); 1634 } 1635 #elif BX_PLATFORM_ANDROID 1636 { 1637 VkAndroidSurfaceCreateInfoKHR sci; 1638 sci.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; 1639 sci.pNext = NULL; 1640 sci.flags = 0; 1641 sci.window = (ANativeWindow*)g_platformData.nwh; 1642 result = vkCreateAndroidSurfaceKHR(m_instance, &sci, m_allocatorCb, &m_surface); 1643 } 1644 #elif BX_PLATFORM_LINUX 1645 { 1646 if (NULL != vkCreateXlibSurfaceKHR) 1647 { 1648 VkXlibSurfaceCreateInfoKHR sci; 1649 sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 1650 sci.pNext = NULL; 1651 sci.flags = 0; 1652 sci.dpy = (Display*)g_platformData.ndt; 1653 sci.window = (Window)g_platformData.nwh; 1654 result = vkCreateXlibSurfaceKHR(m_instance, &sci, m_allocatorCb, &m_surface); 1655 } 1656 else 1657 { 1658 result = VK_RESULT_MAX_ENUM; 1659 } 1660 1661 if (VK_SUCCESS != result) 1662 { 1663 void* xcbdll = bx::dlopen("libX11-xcb.so.1"); 1664 if (NULL != xcbdll) 1665 { 1666 typedef xcb_connection_t* (*PFN_XGETXCBCONNECTION)(Display*); 1667 PFN_XGETXCBCONNECTION XGetXCBConnection = (PFN_XGETXCBCONNECTION)bx::dlsym(xcbdll, "XGetXCBConnection"); 1668 1669 VkXcbSurfaceCreateInfoKHR sci; 1670 sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 1671 sci.pNext = NULL; 1672 sci.flags = 0; 1673 sci.connection = XGetXCBConnection( (Display*)g_platformData.ndt); 1674 union { void* ptr; xcb_window_t window; } cast = { g_platformData.nwh }; 1675 sci.window = cast.window; 1676 result = vkCreateXcbSurfaceKHR(m_instance, &sci, m_allocatorCb, &m_surface); 1677 1678 bx::dlclose(xcbdll); 1679 } 1680 } 1681 } 1682 #elif BX_PLATFORM_OSX 1683 { 1684 if (NULL != vkCreateMacOSSurfaceMVK) 1685 { 1686 NSWindow* window = (NSWindow*)(g_platformData.nwh); 1687 NSView* contentView = (NSView*)window.contentView; 1688 CAMetalLayer* layer = [CAMetalLayer layer]; 1689 if (_init.resolution.reset & BGFX_RESET_HIDPI) 1690 layer.contentsScale = [window backingScaleFactor]; 1691 [contentView setWantsLayer : YES] ; 1692 [contentView setLayer : layer] ; 1693 1694 VkMacOSSurfaceCreateInfoMVK sci; 1695 sci.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; 1696 sci.pNext = NULL; 1697 sci.flags = 0; 1698 sci.pView = (__bridge void*)layer; 1699 result = vkCreateMacOSSurfaceMVK(m_instance, &sci, m_allocatorCb, &m_surface); 1700 } 1701 } 1702 #else 1703 # error "Figure out KHR surface..." 1704 #endif // BX_PLATFORM_ 1705 1706 if (VK_SUCCESS != result) 1707 { 1708 BX_TRACE("Init error: vkCreateSurfaceKHR failed %d: %s.", result, getName(result) ); 1709 goto error; 1710 } 1711 1712 errorState = ErrorState::SurfaceCreated; 1713 1714 { 1715 VkBool32 surfaceSupported; 1716 result = vkGetPhysicalDeviceSurfaceSupportKHR(m_physicalDevice, m_qfiGraphics, m_surface, &surfaceSupported); 1717 1718 if (VK_SUCCESS != result) 1719 { 1720 BX_TRACE("Init error: vkGetPhysicalDeviceSurfaceSupportKHR failed %d: %s.", result, getName(result) ); 1721 goto error; 1722 } 1723 1724 VkSurfaceCapabilitiesKHR surfaceCapabilities; 1725 result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_physicalDevice, m_surface, &surfaceCapabilities); 1726 1727 if (VK_SUCCESS != result) 1728 { 1729 BX_TRACE("Init error: vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed %d: %s.", result, getName(result) ); 1730 goto error; 1731 } 1732 1733 uint32_t width = bx::clamp<uint32_t>( 1734 _init.resolution.width 1735 , surfaceCapabilities.minImageExtent.width 1736 , surfaceCapabilities.maxImageExtent.width 1737 ); 1738 uint32_t height = bx::clamp<uint32_t>( 1739 _init.resolution.height 1740 , surfaceCapabilities.minImageExtent.height 1741 , surfaceCapabilities.maxImageExtent.height 1742 ); 1743 1744 uint32_t numSurfaceFormats; 1745 result = vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, NULL); 1746 1747 if (VK_SUCCESS != result) 1748 { 1749 BX_TRACE("Init error: vkGetPhysicalDeviceSurfaceFormatsKHR failed %d: %s.", result, getName(result) ); 1750 goto error; 1751 } 1752 1753 VkSurfaceFormatKHR surfaceFormats[10]; 1754 numSurfaceFormats = bx::min<uint32_t>(numSurfaceFormats, BX_COUNTOF(surfaceFormats) ); 1755 vkGetPhysicalDeviceSurfaceFormatsKHR(m_physicalDevice, m_surface, &numSurfaceFormats, surfaceFormats); 1756 1757 // find the best match... 1758 VkFormat preferredSurfaceFormat[4] = 1759 { 1760 VK_FORMAT_R8G8B8A8_UNORM, 1761 VK_FORMAT_B8G8R8A8_UNORM, 1762 VK_FORMAT_R8G8B8A8_SRGB, 1763 VK_FORMAT_B8G8R8A8_SRGB, 1764 }; 1765 1766 uint32_t surfaceFormatIdx = numSurfaceFormats; 1767 1768 for (uint32_t jj = 0; jj < BX_COUNTOF(preferredSurfaceFormat); jj++) 1769 { 1770 for (uint32_t ii = 0; ii < numSurfaceFormats; ii++) 1771 { 1772 BX_TRACE("Supported surface format: %d", surfaceFormats[ii].format); 1773 if (preferredSurfaceFormat[jj] == surfaceFormats[ii].format) 1774 { 1775 surfaceFormatIdx = ii; 1776 break; 1777 } 1778 } 1779 1780 if (surfaceFormatIdx < numSurfaceFormats) 1781 { // found 1782 BX_TRACE("Preferred surface format found: %d", surfaceFormats[surfaceFormatIdx].format); 1783 break; 1784 } 1785 } 1786 1787 BX_CHECK(surfaceFormatIdx < numSurfaceFormats, "cannot found preferred surface format from supported surface format"); 1788 1789 uint32_t numPresentModes; 1790 result = vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, NULL); 1791 if (VK_SUCCESS != result) 1792 { 1793 BX_TRACE("Init error: vkGetPhysicalDeviceSurfacePresentModesKHR failed %d: %s.", result, getName(result) ); 1794 goto error; 1795 } 1796 1797 VkPresentModeKHR presentModes[10]; 1798 numPresentModes = bx::min<uint32_t>(numPresentModes, BX_COUNTOF(presentModes) ); 1799 vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, presentModes); 1800 1801 // find the best match... 1802 uint32_t presentModeIdx = numPresentModes; 1803 VkPresentModeKHR preferredPresentMode[] = { 1804 VK_PRESENT_MODE_FIFO_KHR, 1805 VK_PRESENT_MODE_FIFO_RELAXED_KHR, 1806 VK_PRESENT_MODE_MAILBOX_KHR, 1807 VK_PRESENT_MODE_IMMEDIATE_KHR, 1808 }; 1809 for (uint32_t ii = 0; ii < BX_COUNTOF(preferredPresentMode); ++ii) 1810 { 1811 for (uint32_t jj = 0; jj < numPresentModes; ++jj) 1812 { 1813 if (presentModes[jj] == preferredPresentMode[ii]) 1814 { 1815 presentModeIdx = jj; 1816 BX_TRACE("present mode: %d", (int)preferredPresentMode[ii]); 1817 break; 1818 } 1819 } 1820 if (presentModeIdx < numPresentModes) 1821 { 1822 break; 1823 } 1824 } 1825 if (presentModeIdx == numPresentModes) 1826 { 1827 presentModeIdx = 0; 1828 } 1829 1830 m_backBufferDepthStencilFormat = 0 != (g_caps.formats[TextureFormat::D24S8] & BGFX_CAPS_FORMAT_TEXTURE_2D) 1831 ? VK_FORMAT_D24_UNORM_S8_UINT 1832 : VK_FORMAT_D32_SFLOAT_S8_UINT 1833 ; 1834 1835 VkCompositeAlphaFlagBitsKHR compositeAlpha = (VkCompositeAlphaFlagBitsKHR)0; 1836 if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) 1837 { 1838 compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; 1839 } 1840 else if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) 1841 { 1842 compositeAlpha = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR; 1843 } 1844 else if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) 1845 { 1846 compositeAlpha = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR; 1847 } 1848 else if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) 1849 { 1850 compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; 1851 } 1852 1853 m_sci.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; 1854 m_sci.pNext = NULL; 1855 m_sci.flags = 0; 1856 m_sci.surface = m_surface; 1857 m_sci.minImageCount = 2; 1858 m_sci.imageFormat = surfaceFormats[surfaceFormatIdx].format; 1859 m_sci.imageColorSpace = surfaceFormats[surfaceFormatIdx].colorSpace; 1860 m_sci.imageExtent.width = width; 1861 m_sci.imageExtent.height = height; 1862 m_sci.imageArrayLayers = 1; 1863 m_sci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 1864 m_sci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; 1865 m_sci.queueFamilyIndexCount = 0; 1866 m_sci.pQueueFamilyIndices = NULL; 1867 m_sci.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; 1868 m_sci.compositeAlpha = compositeAlpha; 1869 m_sci.presentMode = presentModes[presentModeIdx]; 1870 m_sci.clipped = VK_TRUE; 1871 m_sci.oldSwapchain = VK_NULL_HANDLE; 1872 1873 for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii) 1874 { 1875 m_backBufferColorImageView[ii] = VK_NULL_HANDLE; 1876 m_backBufferColorImage[ii] = VK_NULL_HANDLE; 1877 m_backBufferColor[ii] = VK_NULL_HANDLE; 1878 m_presentDone[ii] = VK_NULL_HANDLE; 1879 } 1880 1881 result = createSwapchain(); 1882 if (VK_SUCCESS != result) 1883 { 1884 BX_TRACE("Init error: creating swapchain and image view failed %d: %s", result, getName(result)); 1885 goto error; 1886 } 1887 1888 VkSemaphoreCreateInfo sci; 1889 sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 1890 sci.pNext = NULL; 1891 sci.flags = 0; 1892 1893 for (uint32_t ii = 0; ii < m_numSwapchainImages; ++ii) 1894 { 1895 result = vkCreateSemaphore(m_device, &sci, m_allocatorCb, &m_presentDone[ii]); 1896 if (VK_SUCCESS != result) 1897 { 1898 BX_TRACE("Init error: vkCreateSemaphore failed %d: %s.", result, getName(result) ); 1899 goto error; 1900 } 1901 } 1902 } 1903 1904 errorState = ErrorState::SwapchainCreated; 1905 1906 { 1907 VkAttachmentDescription ad[2]; 1908 ad[0].flags = 0; 1909 ad[0].format = m_sci.imageFormat; 1910 ad[0].samples = VK_SAMPLE_COUNT_1_BIT; 1911 ad[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 1912 ad[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; 1913 ad[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 1914 ad[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 1915 ad[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1916 ad[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1917 ad[1].flags = 0; 1918 ad[1].format = m_backBufferDepthStencilFormat; 1919 ad[1].samples = VK_SAMPLE_COUNT_1_BIT; 1920 ad[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 1921 ad[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; 1922 ad[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 1923 ad[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; 1924 ad[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1925 ad[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1926 1927 VkAttachmentReference colorAr[1]; 1928 colorAr[0].attachment = 0; 1929 colorAr[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1930 1931 VkAttachmentReference resolveAr[1]; 1932 resolveAr[0].attachment = VK_ATTACHMENT_UNUSED; 1933 resolveAr[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1934 1935 VkAttachmentReference depthAr[1]; 1936 depthAr[0].attachment = 1; 1937 depthAr[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 1938 1939 VkSubpassDescription sd[1]; 1940 sd[0].flags = 0; 1941 sd[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 1942 sd[0].inputAttachmentCount = 0; 1943 sd[0].pInputAttachments = NULL; 1944 sd[0].colorAttachmentCount = BX_COUNTOF(colorAr); 1945 sd[0].pColorAttachments = colorAr; 1946 sd[0].pResolveAttachments = resolveAr; 1947 sd[0].pDepthStencilAttachment = depthAr; 1948 sd[0].preserveAttachmentCount = 0; 1949 sd[0].pPreserveAttachments = NULL; 1950 1951 VkRenderPassCreateInfo rpi; 1952 rpi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 1953 rpi.pNext = NULL; 1954 rpi.flags = 0; 1955 rpi.attachmentCount = BX_COUNTOF(ad); 1956 rpi.pAttachments = ad; 1957 rpi.subpassCount = BX_COUNTOF(sd); 1958 rpi.pSubpasses = sd; 1959 rpi.dependencyCount = 0; 1960 rpi.pDependencies = NULL; 1961 1962 result = vkCreateRenderPass(m_device, &rpi, m_allocatorCb, &m_renderPass); 1963 1964 if (VK_SUCCESS != result) 1965 { 1966 BX_TRACE("Init error: vkCreateRenderPass failed %d: %s.", result, getName(result)); 1967 goto error; 1968 } 1969 } 1970 1971 errorState = ErrorState::RenderPassCreated; 1972 1973 // framebuffer creation 1974 result = createSwapchainFramebuffer(); 1975 if (VK_SUCCESS != result) 1976 { 1977 BX_TRACE("Init error: vkCreateFramebuffer failed %d: %s.", result, getName(result)); 1978 goto error; 1979 } 1980 1981 errorState = ErrorState::FrameBufferCreated; 1982 1983 { 1984 VkFenceCreateInfo fci; 1985 fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 1986 fci.pNext = NULL; 1987 fci.flags = 0; 1988 result = vkCreateFence(m_device, &fci, m_allocatorCb, &m_fence); 1989 1990 if (VK_SUCCESS != result) 1991 { 1992 BX_TRACE("Init error: vkCreateFence failed %d: %s.", result, getName(result) ); 1993 goto error; 1994 } 1995 1996 VkCommandPoolCreateInfo cpci; 1997 cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 1998 cpci.pNext = NULL; 1999 cpci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 2000 cpci.queueFamilyIndex = m_qfiGraphics; 2001 result = vkCreateCommandPool(m_device, &cpci, m_allocatorCb, &m_commandPool); 2002 2003 if (VK_SUCCESS != result) 2004 { 2005 vkDestroy(m_fence); 2006 BX_TRACE("Init error: vkCreateCommandPool failed %d: %s.", result, getName(result) ); 2007 goto error; 2008 } 2009 2010 VkCommandBufferAllocateInfo cbai; 2011 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 2012 cbai.pNext = NULL; 2013 cbai.commandPool = m_commandPool; 2014 cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 2015 cbai.commandBufferCount = BX_COUNTOF(m_commandBuffers); 2016 2017 result = vkAllocateCommandBuffers(m_device, &cbai, m_commandBuffers); 2018 2019 if (VK_SUCCESS != result) 2020 { 2021 vkDestroy(m_commandPool); 2022 vkDestroy(m_fence); 2023 BX_TRACE("Init error: vkAllocateCommandBuffers failed %d: %s.", result, getName(result) ); 2024 goto error; 2025 } 2026 2027 initSwapchainImageLayout(); 2028 2029 // kick(); 2030 // finishAll(); 2031 2032 VK_CHECK(vkResetCommandPool(m_device, m_commandPool, 0) ); 2033 } 2034 2035 errorState = ErrorState::CommandBuffersCreated; 2036 2037 { 2038 VkDescriptorPoolSize dps[] = 2039 { 2040 // { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, (10 * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS) << 10 }, 2041 { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, (10 * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS) << 10 }, 2042 { VK_DESCRIPTOR_TYPE_SAMPLER, (10 * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS) << 10 }, 2043 { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 10<<10 }, 2044 { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS << 10 }, 2045 { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS << 10 }, 2046 }; 2047 2048 // VkDescriptorSetLayoutBinding dslb[] = 2049 // { 2050 // // { DslBinding::CombinedImageSampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, VK_SHADER_STAGE_ALL, NULL }, 2051 // { DslBinding::VertexUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL }, 2052 // { DslBinding::FragmentUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, NULL }, 2053 // // { DslBinding::StorageBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, VK_SHADER_STAGE_ALL, NULL }, 2054 // }; 2055 2056 VkDescriptorPoolCreateInfo dpci; 2057 dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 2058 dpci.pNext = NULL; 2059 dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 2060 dpci.maxSets = 10<<10; 2061 dpci.poolSizeCount = BX_COUNTOF(dps); 2062 dpci.pPoolSizes = dps; 2063 2064 result = vkCreateDescriptorPool(m_device, &dpci, m_allocatorCb, &m_descriptorPool); 2065 2066 if (VK_SUCCESS != result) 2067 { 2068 BX_TRACE("Init error: vkCreateDescriptorPool failed %d: %s.", result, getName(result) ); 2069 goto error; 2070 } 2071 2072 // VkDescriptorSetLayoutCreateInfo dsl; 2073 // dsl.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 2074 // dsl.pNext = NULL; 2075 // dsl.flags = 0; 2076 // dsl.bindingCount = BX_COUNTOF(dslb); 2077 // dsl.pBindings = dslb; 2078 // result = vkCreateDescriptorSetLayout(m_device, &dsl, m_allocatorCb, &m_descriptorSetLayout); 2079 // 2080 // if (VK_SUCCESS != result) 2081 // { 2082 // BX_TRACE("Init error: vkCreateDescriptorSetLayout failed %d: %s.", result, getName(result) ); 2083 // goto error; 2084 // } 2085 // 2086 // VkPipelineLayoutCreateInfo pl; 2087 // pl.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 2088 // pl.pNext = NULL; 2089 // pl.flags = 0; 2090 // pl.setLayoutCount = 1; 2091 // pl.pSetLayouts = &m_descriptorSetLayout; 2092 // pl.pushConstantRangeCount = 0; 2093 // pl.pPushConstantRanges = NULL; 2094 // result = vkCreatePipelineLayout(m_device, &pl, m_allocatorCb, &m_pipelineLayout); 2095 // 2096 // if (VK_SUCCESS != result) 2097 // { 2098 // BX_TRACE("Init error: vkCreatePipelineLayout failed %d: %s.", result, getName(result) ); 2099 // goto error; 2100 // } 2101 2102 VkPipelineCacheCreateInfo pcci; 2103 pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 2104 pcci.pNext = NULL; 2105 pcci.flags = 0; 2106 pcci.initialDataSize = 0; 2107 pcci.pInitialData = NULL; 2108 result = vkCreatePipelineCache(m_device, &pcci, m_allocatorCb, &m_pipelineCache); 2109 2110 if (VK_SUCCESS != result) 2111 { 2112 BX_TRACE("Init error: vkCreatePipelineCache failed %d: %s.", result, getName(result) ); 2113 goto error; 2114 } 2115 } 2116 2117 for (uint32_t ii = 0; ii < BX_COUNTOF(m_scratchBuffer); ++ii) 2118 { 2119 BX_TRACE("Create scratch buffer %d", ii); 2120 m_scratchBuffer[ii].create(BGFX_CONFIG_MAX_DRAW_CALLS * 128, 1024); 2121 } 2122 2123 errorState = ErrorState::DescriptorCreated; 2124 2125 if (NULL == vkSetDebugUtilsObjectNameEXT) 2126 { 2127 vkSetDebugUtilsObjectNameEXT = stubSetDebugUtilsObjectNameEXT; 2128 } 2129 2130 if (NULL == vkCmdBeginDebugUtilsLabelEXT 2131 || NULL == vkCmdEndDebugUtilsLabelEXT) 2132 { 2133 vkCmdBeginDebugUtilsLabelEXT = stubCmdBeginDebugUtilsLabelEXT; 2134 vkCmdEndDebugUtilsLabelEXT = stubCmdEndDebugUtilsLabelEXT; 2135 } 2136 2137 if (NULL == vkCmdInsertDebugUtilsLabelEXT) 2138 { 2139 vkCmdInsertDebugUtilsLabelEXT = stubCmdInsertDebugUtilsLabelEXT; 2140 } 2141 2142 // Init reserved part of view name. 2143 for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii) 2144 { 2145 bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii); 2146 } 2147 2148 g_internalData.context = m_device; 2149 return true; 2150 2151 error: 2152 BX_TRACE("errorState %d", errorState); 2153 switch (errorState) 2154 { 2155 case ErrorState::DescriptorCreated: 2156 vkDestroy(m_pipelineCache); 2157 // vkDestroy(m_pipelineLayout); 2158 // vkDestroy(m_descriptorSetLayout); 2159 vkDestroy(m_descriptorPool); 2160 BX_FALLTHROUGH; 2161 2162 case ErrorState::CommandBuffersCreated: 2163 vkFreeCommandBuffers(m_device, m_commandPool, BX_COUNTOF(m_commandBuffers), m_commandBuffers); 2164 vkDestroy(m_commandPool); 2165 vkDestroy(m_fence); 2166 BX_FALLTHROUGH; 2167 2168 case ErrorState::FrameBufferCreated: 2169 releaseSwapchainFramebuffer(); 2170 BX_FALLTHROUGH; 2171 2172 case ErrorState::RenderPassCreated: 2173 vkDestroy(m_renderPass); 2174 BX_FALLTHROUGH; 2175 2176 case ErrorState::SwapchainCreated: 2177 for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii) 2178 { 2179 vkDestroy(m_presentDone[ii]); 2180 } 2181 releaseSwapchain(); 2182 BX_FALLTHROUGH; 2183 2184 case ErrorState::SurfaceCreated: 2185 vkDestroySurfaceKHR(m_instance, m_surface, m_allocatorCb); 2186 BX_FALLTHROUGH; 2187 2188 case ErrorState::DeviceCreated: 2189 vkDestroyDevice(m_device, m_allocatorCb); 2190 BX_FALLTHROUGH; 2191 2192 case ErrorState::InstanceCreated: 2193 if (VK_NULL_HANDLE != m_debugReportCallback) 2194 { 2195 vkDestroyDebugReportCallbackEXT(m_instance, m_debugReportCallback, m_allocatorCb); 2196 } 2197 2198 vkDestroyInstance(m_instance, m_allocatorCb); 2199 BX_FALLTHROUGH; 2200 2201 case ErrorState::LoadedVulkan1: 2202 bx::dlclose(m_vulkan1Dll); 2203 m_vulkan1Dll = NULL; 2204 m_allocatorCb = NULL; 2205 unloadRenderDoc(m_renderDocDll); 2206 BX_FALLTHROUGH; 2207 2208 case ErrorState::Default: 2209 break; 2210 }; 2211 2212 BX_CHECK(false, "Failed to initialize Vulkan."); 2213 return false; 2214 } 2215 shutdownbgfx::vk::RendererContextVK2216 void shutdown() 2217 { 2218 VK_CHECK(vkQueueWaitIdle(m_queueGraphics) ); 2219 VK_CHECK(vkDeviceWaitIdle(m_device) ); 2220 2221 m_pipelineStateCache.invalidate(); 2222 m_descriptorSetLayoutCache.invalidate(); 2223 m_renderPassCache.invalidate(); 2224 m_samplerCache.invalidate(); 2225 2226 for (uint32_t ii = 0; ii < BX_COUNTOF(m_scratchBuffer); ++ii) 2227 { 2228 m_scratchBuffer[ii].destroy(); 2229 } 2230 2231 for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) 2232 { 2233 m_frameBuffers[ii].destroy(); 2234 } 2235 2236 for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) 2237 { 2238 m_indexBuffers[ii].destroy(); 2239 } 2240 2241 for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii) 2242 { 2243 m_vertexBuffers[ii].destroy(); 2244 } 2245 2246 for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) 2247 { 2248 m_shaders[ii].destroy(); 2249 } 2250 2251 for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii) 2252 { 2253 m_textures[ii].destroy(); 2254 } 2255 2256 vkDestroy(m_pipelineCache); 2257 // vkDestroy(m_pipelineLayout); 2258 // vkDestroy(m_descriptorSetLayout); 2259 vkDestroy(m_descriptorPool); 2260 2261 vkFreeCommandBuffers(m_device, m_commandPool, BX_COUNTOF(m_commandBuffers), m_commandBuffers); 2262 vkDestroy(m_commandPool); 2263 vkDestroy(m_fence); 2264 2265 for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii) 2266 { 2267 vkDestroy(m_presentDone[ii]); 2268 } 2269 releaseSwapchainFramebuffer(); 2270 releaseSwapchain(); 2271 2272 vkDestroySurfaceKHR(m_instance, m_surface, m_allocatorCb); 2273 2274 vkDestroy(m_renderPass); 2275 2276 vkDestroyDevice(m_device, m_allocatorCb); 2277 2278 if (VK_NULL_HANDLE != m_debugReportCallback) 2279 { 2280 vkDestroyDebugReportCallbackEXT(m_instance, m_debugReportCallback, m_allocatorCb); 2281 } 2282 2283 vkDestroyInstance(m_instance, m_allocatorCb); 2284 2285 bx::dlclose(m_vulkan1Dll); 2286 m_vulkan1Dll = NULL; 2287 m_allocatorCb = NULL; 2288 unloadRenderDoc(m_renderDocDll); 2289 } 2290 getRendererTypebgfx::vk::RendererContextVK2291 RendererType::Enum getRendererType() const override 2292 { 2293 return RendererType::Vulkan; 2294 } 2295 getRendererNamebgfx::vk::RendererContextVK2296 const char* getRendererName() const override 2297 { 2298 return BGFX_RENDERER_VULKAN_NAME; 2299 } 2300 isDeviceRemovedbgfx::vk::RendererContextVK2301 bool isDeviceRemoved() override 2302 { 2303 return false; 2304 } 2305 flipbgfx::vk::RendererContextVK2306 void flip() override 2307 { 2308 if (VK_NULL_HANDLE != m_swapchain) 2309 { 2310 VkPresentInfoKHR pi; 2311 pi.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; 2312 pi.pNext = NULL; 2313 pi.waitSemaphoreCount = 0; 2314 pi.pWaitSemaphores = NULL; 2315 pi.swapchainCount = 1; 2316 pi.pSwapchains = &m_swapchain; 2317 pi.pImageIndices = &m_backBufferColorIdx; 2318 pi.pResults = NULL; 2319 VkResult result = vkQueuePresentKHR(m_queueGraphics, &pi); 2320 if (VK_ERROR_OUT_OF_DATE_KHR == result 2321 || VK_SUBOPTIMAL_KHR == result) 2322 { 2323 m_needToRefreshSwapchain = true; 2324 } 2325 } 2326 } 2327 createIndexBufferbgfx::vk::RendererContextVK2328 void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override 2329 { 2330 m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags, false); 2331 } 2332 destroyIndexBufferbgfx::vk::RendererContextVK2333 void destroyIndexBuffer(IndexBufferHandle _handle) override 2334 { 2335 m_indexBuffers[_handle.idx].destroy(); 2336 } 2337 createVertexLayoutbgfx::vk::RendererContextVK2338 void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override 2339 { 2340 VertexLayout& layout = m_vertexLayouts[_handle.idx]; 2341 bx::memCopy(&layout, &_layout, sizeof(VertexLayout) ); 2342 dump(layout); 2343 } 2344 destroyVertexLayoutbgfx::vk::RendererContextVK2345 void destroyVertexLayout(VertexLayoutHandle /*_handle*/) override 2346 { 2347 } 2348 createVertexBufferbgfx::vk::RendererContextVK2349 void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override 2350 { 2351 m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); 2352 } 2353 destroyVertexBufferbgfx::vk::RendererContextVK2354 void destroyVertexBuffer(VertexBufferHandle _handle) override 2355 { 2356 m_vertexBuffers[_handle.idx].destroy(); 2357 } 2358 createDynamicIndexBufferbgfx::vk::RendererContextVK2359 void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override 2360 { 2361 m_indexBuffers[_handle.idx].create(_size, NULL, _flags, false); 2362 } 2363 updateDynamicIndexBufferbgfx::vk::RendererContextVK2364 void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override 2365 { 2366 // BX_UNUSED(_handle, _offset, _size, _mem); 2367 m_indexBuffers[_handle.idx].update(/*m_commandBuffer*/NULL, _offset, bx::min<uint32_t>(_size, _mem->size), _mem->data); 2368 } 2369 destroyDynamicIndexBufferbgfx::vk::RendererContextVK2370 void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override 2371 { 2372 m_indexBuffers[_handle.idx].destroy(); 2373 } 2374 createDynamicVertexBufferbgfx::vk::RendererContextVK2375 void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override 2376 { 2377 VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; 2378 m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); 2379 } 2380 updateDynamicVertexBufferbgfx::vk::RendererContextVK2381 void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override 2382 { 2383 // BX_UNUSED(_handle, _offset, _size, _mem); 2384 m_vertexBuffers[_handle.idx].update(/*m_commandBuffer*/NULL, _offset, bx::min<uint32_t>(_size, _mem->size), _mem->data); 2385 } 2386 destroyDynamicVertexBufferbgfx::vk::RendererContextVK2387 void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override 2388 { 2389 m_vertexBuffers[_handle.idx].destroy(); 2390 } 2391 createShaderbgfx::vk::RendererContextVK2392 void createShader(ShaderHandle _handle, const Memory* _mem) override 2393 { 2394 m_shaders[_handle.idx].create(_mem); 2395 } 2396 destroyShaderbgfx::vk::RendererContextVK2397 void destroyShader(ShaderHandle _handle) override 2398 { 2399 m_shaders[_handle.idx].destroy(); 2400 } 2401 createProgrambgfx::vk::RendererContextVK2402 void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override 2403 { 2404 m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); 2405 } 2406 destroyProgrambgfx::vk::RendererContextVK2407 void destroyProgram(ProgramHandle _handle) override 2408 { 2409 m_program[_handle.idx].destroy(); 2410 } 2411 createTexturebgfx::vk::RendererContextVK2412 void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override 2413 { 2414 return m_textures[_handle.idx].create(_mem, _flags, _skip); 2415 } 2416 updateTextureBeginbgfx::vk::RendererContextVK2417 void updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) override 2418 { 2419 } 2420 updateTexturebgfx::vk::RendererContextVK2421 void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override 2422 { 2423 m_textures[_handle.idx].update(m_commandPool, _side, _mip, _rect, _z, _depth, _pitch, _mem); 2424 } 2425 updateTextureEndbgfx::vk::RendererContextVK2426 void updateTextureEnd() override 2427 { 2428 } 2429 readTexturebgfx::vk::RendererContextVK2430 void readTexture(TextureHandle /*_handle*/, void* /*_data*/, uint8_t /*_mip*/) override 2431 { 2432 } 2433 resizeTexturebgfx::vk::RendererContextVK2434 void resizeTexture(TextureHandle /*_handle*/, uint16_t /*_width*/, uint16_t /*_height*/, uint8_t /*_numMips*/, uint16_t /*_numLayers*/) override 2435 { 2436 } 2437 overrideInternalbgfx::vk::RendererContextVK2438 void overrideInternal(TextureHandle /*_handle*/, uintptr_t /*_ptr*/) override 2439 { 2440 } 2441 getInternalbgfx::vk::RendererContextVK2442 uintptr_t getInternal(TextureHandle /*_handle*/) override 2443 { 2444 return 0; 2445 } 2446 destroyTexturebgfx::vk::RendererContextVK2447 void destroyTexture(TextureHandle _handle) override 2448 { 2449 m_textures[_handle.idx].destroy(); 2450 } 2451 createFrameBufferbgfx::vk::RendererContextVK2452 void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override 2453 { 2454 m_frameBuffers[_handle.idx].create(_num, _attachment); 2455 } 2456 createFrameBufferbgfx::vk::RendererContextVK2457 void createFrameBuffer(FrameBufferHandle /*_handle*/, void* /*_nwh*/, uint32_t /*_width*/, uint32_t /*_height*/, TextureFormat::Enum /*_format*/, TextureFormat::Enum /*_depthFormat*/) override 2458 { 2459 } 2460 destroyFrameBufferbgfx::vk::RendererContextVK2461 void destroyFrameBuffer(FrameBufferHandle _handle) override 2462 { 2463 m_frameBuffers[_handle.idx].destroy(); 2464 } 2465 createUniformbgfx::vk::RendererContextVK2466 void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) override 2467 { 2468 if (NULL != m_uniforms[_handle.idx]) 2469 { 2470 BX_FREE(g_allocator, m_uniforms[_handle.idx]); 2471 } 2472 2473 uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type] * _num); 2474 void* data = BX_ALLOC(g_allocator, size); 2475 bx::memSet(data, 0, size); 2476 m_uniforms[_handle.idx] = data; 2477 m_uniformReg.add(_handle, _name); 2478 } 2479 destroyUniformbgfx::vk::RendererContextVK2480 void destroyUniform(UniformHandle _handle) override 2481 { 2482 BX_FREE(g_allocator, m_uniforms[_handle.idx]); 2483 m_uniforms[_handle.idx] = NULL; 2484 } 2485 requestScreenShotbgfx::vk::RendererContextVK2486 void requestScreenShot(FrameBufferHandle /*_handle*/, const char* /*_filePath*/) override 2487 { 2488 } 2489 updateViewNamebgfx::vk::RendererContextVK2490 void updateViewName(ViewId _id, const char* _name) override 2491 { 2492 bx::strCopy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED] 2493 , BX_COUNTOF(s_viewName[0]) - BGFX_CONFIG_MAX_VIEW_NAME_RESERVED 2494 , _name 2495 ); 2496 } 2497 updateUniformbgfx::vk::RendererContextVK2498 void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) override 2499 { 2500 bx::memCopy(m_uniforms[_loc], _data, _size); 2501 } 2502 invalidateOcclusionQuerybgfx::vk::RendererContextVK2503 void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override 2504 { 2505 BX_UNUSED(_handle); 2506 } 2507 setMarkerbgfx::vk::RendererContextVK2508 void setMarker(const char* _marker, uint16_t _len) override 2509 { 2510 if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) 2511 { 2512 BX_UNUSED(_len); 2513 2514 VkDebugUtilsLabelEXT dul; 2515 dul.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; 2516 dul.pNext = NULL; 2517 dul.pLabelName = _marker; 2518 dul.color[0] = 1.0f; 2519 dul.color[1] = 0.0f; 2520 dul.color[2] = 0.0f; 2521 dul.color[3] = 1.0f; 2522 vkCmdInsertDebugUtilsLabelEXT(m_commandBuffer, &dul); 2523 } 2524 } 2525 setNamebgfx::vk::RendererContextVK2526 virtual void setName(Handle _handle, const char* _name, uint16_t _len) override 2527 { 2528 switch (_handle.type) 2529 { 2530 case Handle::IndexBuffer: 2531 setDebugObjectName(m_device, m_indexBuffers[_handle.idx].m_buffer, "%.*s", _len, _name); 2532 break; 2533 2534 case Handle::Shader: 2535 setDebugObjectName(m_device, m_shaders[_handle.idx].m_module, "%.*s", _len, _name); 2536 break; 2537 2538 case Handle::Texture: 2539 // setDebugObjectName(m_device, m_textures[_handle.idx].m_ptr, "%.*s", _len, _name); 2540 break; 2541 2542 case Handle::VertexBuffer: 2543 setDebugObjectName(m_device, m_vertexBuffers[_handle.idx].m_buffer, "%.*s", _len, _name); 2544 break; 2545 2546 default: 2547 BX_CHECK(false, "Invalid handle type?! %d", _handle.type); 2548 break; 2549 } 2550 } 2551 2552 void submitBlit(BlitState& _bs, uint16_t _view); 2553 2554 void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override; 2555 blitSetupbgfx::vk::RendererContextVK2556 void blitSetup(TextVideoMemBlitter& _blitter) override 2557 { 2558 const uint32_t width = m_sci.imageExtent.width; 2559 const uint32_t height = m_sci.imageExtent.height; 2560 2561 setFrameBuffer(BGFX_INVALID_HANDLE, false); 2562 2563 VkViewport vp; 2564 vp.x = 0; 2565 vp.y = 0; 2566 vp.width = (float)width; 2567 vp.height = (float)height; 2568 vp.minDepth = 0.0f; 2569 vp.maxDepth = 1.0f; 2570 vkCmdSetViewport(m_commandBuffer, 0, 1, &vp); 2571 2572 VkRect2D rc; 2573 rc.offset.x = 0; 2574 rc.offset.y = 0; 2575 rc.extent.width = width; 2576 rc.extent.height = height; 2577 vkCmdSetScissor(m_commandBuffer, 0, 1, &rc); 2578 2579 const uint64_t state = 0 2580 | BGFX_STATE_WRITE_RGB 2581 | BGFX_STATE_WRITE_A 2582 | BGFX_STATE_DEPTH_TEST_ALWAYS 2583 ; 2584 2585 const VertexLayout* layout = &m_vertexLayouts[_blitter.m_vb->layoutHandle.idx]; 2586 VkPipeline pso = getPipeline(state 2587 , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) 2588 , 1 2589 , &layout 2590 , _blitter.m_program 2591 , 0 2592 ); 2593 vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pso); 2594 2595 ProgramVK& program = m_program[_blitter.m_program.idx]; 2596 float proj[16]; 2597 bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false); 2598 2599 PredefinedUniform& predefined = m_program[_blitter.m_program.idx].m_predefined[0]; 2600 uint8_t flags = predefined.m_type; 2601 setShaderUniform(flags, predefined.m_loc, proj, 4); 2602 2603 UniformBuffer* vcb = program.m_vsh->m_constantBuffer; 2604 if (NULL != vcb) 2605 { 2606 commit(*vcb); 2607 } 2608 ScratchBufferVK& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx]; 2609 VkDescriptorSetLayout dsl = m_descriptorSetLayoutCache.find(program.m_descriptorSetLayoutHash); 2610 VkDescriptorSetAllocateInfo dsai; 2611 dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 2612 dsai.pNext = NULL; 2613 dsai.descriptorPool = m_descriptorPool; 2614 dsai.descriptorSetCount = 1; 2615 dsai.pSetLayouts = &dsl; 2616 vkAllocateDescriptorSets(m_device, &dsai, &scratchBuffer.m_descriptorSet[scratchBuffer.m_currentDs]); 2617 2618 const uint32_t align = uint32_t(m_deviceProperties.limits.minUniformBufferOffsetAlignment); 2619 TextureVK& texture = m_textures[_blitter.m_texture.idx]; 2620 uint32_t samplerFlags = (uint32_t)(texture.m_flags & BGFX_SAMPLER_BITS_MASK); 2621 VkSampler sampler = getSampler(samplerFlags, 1); 2622 2623 const uint32_t size = bx::strideAlign(program.m_vsh->m_size, align); 2624 uint32_t bufferOffset = scratchBuffer.m_pos; 2625 VkDescriptorBufferInfo bufferInfo; 2626 bufferInfo.buffer = scratchBuffer.m_buffer; 2627 bufferInfo.offset = 0; 2628 bufferInfo.range = size; 2629 bx::memCopy(&scratchBuffer.m_data[scratchBuffer.m_pos], m_vsScratch, program.m_vsh->m_size); 2630 scratchBuffer.m_pos += size; 2631 2632 VkWriteDescriptorSet wds[3]; 2633 wds[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 2634 wds[0].pNext = NULL; 2635 wds[0].dstSet = scratchBuffer.m_descriptorSet[scratchBuffer.m_currentDs]; 2636 wds[0].dstBinding = program.m_vsh->m_uniformBinding; 2637 wds[0].dstArrayElement = 0; 2638 wds[0].descriptorCount = 1; 2639 wds[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 2640 wds[0].pImageInfo = NULL; 2641 wds[0].pBufferInfo = &bufferInfo; 2642 wds[0].pTexelBufferView = NULL; 2643 2644 VkDescriptorImageInfo imageInfo; 2645 imageInfo.imageLayout = texture.m_currentImageLayout; 2646 imageInfo.imageView = texture.m_textureImageView; 2647 imageInfo.sampler = sampler; 2648 2649 wds[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 2650 wds[1].pNext = NULL; 2651 wds[1].dstSet = scratchBuffer.m_descriptorSet[scratchBuffer.m_currentDs]; 2652 wds[1].dstBinding = program.m_fsh->m_bindInfo[0].binding; 2653 wds[1].dstArrayElement = 0; 2654 wds[1].descriptorCount = 1; 2655 wds[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 2656 wds[1].pImageInfo = &imageInfo; 2657 wds[1].pBufferInfo = NULL; 2658 wds[1].pTexelBufferView = NULL; 2659 2660 wds[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 2661 wds[2].pNext = NULL; 2662 wds[2].dstSet = scratchBuffer.m_descriptorSet[scratchBuffer.m_currentDs]; 2663 wds[2].dstBinding = program.m_fsh->m_bindInfo[0].samplerBinding; 2664 wds[2].dstArrayElement = 0; 2665 wds[2].descriptorCount = 1; 2666 wds[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 2667 wds[2].pImageInfo = &imageInfo; 2668 wds[2].pBufferInfo = NULL; 2669 wds[2].pTexelBufferView = NULL; 2670 2671 m_vsChanges = 0; 2672 m_fsChanges = 0; 2673 2674 vkUpdateDescriptorSets(m_device, 3, wds, 0, NULL); 2675 vkCmdBindDescriptorSets( 2676 m_commandBuffer 2677 , VK_PIPELINE_BIND_POINT_GRAPHICS 2678 , program.m_pipelineLayout 2679 , 0 2680 , 1 2681 , &scratchBuffer.m_descriptorSet[scratchBuffer.m_currentDs] 2682 , 1 2683 , &bufferOffset 2684 ); 2685 2686 scratchBuffer.m_currentDs++; 2687 2688 VertexBufferVK& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; 2689 VkDeviceSize offset = 0; 2690 vkCmdBindVertexBuffers(m_commandBuffer 2691 , 0 2692 , 1 2693 , &vb.m_buffer 2694 , &offset 2695 ); 2696 2697 BufferVK& ib = m_indexBuffers[_blitter.m_ib->handle.idx]; 2698 vkCmdBindIndexBuffer(m_commandBuffer 2699 , ib.m_buffer 2700 , 0 2701 , VK_INDEX_TYPE_UINT16 2702 ); 2703 } 2704 blitRenderbgfx::vk::RendererContextVK2705 void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override 2706 { 2707 const uint32_t numVertices = _numIndices*4/6; 2708 if (0 < numVertices) 2709 { 2710 m_indexBuffers[_blitter.m_ib->handle.idx].update(m_commandBuffer, 0, _numIndices*2, _blitter.m_ib->data); 2711 m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandBuffer, 0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true); 2712 2713 vkCmdDrawIndexed(m_commandBuffer 2714 , _numIndices 2715 , 1 2716 , 0 2717 , 0 2718 , 0 2719 ); 2720 } 2721 } 2722 updateResolutionbgfx::vk::RendererContextVK2723 void updateResolution(const Resolution& _resolution) 2724 { 2725 if (!!(_resolution.reset & BGFX_RESET_MAXANISOTROPY) ) 2726 { 2727 m_maxAnisotropy = UINT32_MAX; 2728 } 2729 else 2730 { 2731 m_maxAnisotropy = 1; 2732 } 2733 2734 bool depthClamp = !!(_resolution.reset & BGFX_RESET_DEPTH_CLAMP); 2735 2736 if (m_depthClamp != depthClamp) 2737 { 2738 m_depthClamp = depthClamp; 2739 m_pipelineStateCache.invalidate(); 2740 } 2741 2742 uint32_t flags = _resolution.reset & ~(BGFX_RESET_MAXANISOTROPY | BGFX_RESET_DEPTH_CLAMP); 2743 2744 if (m_resolution.width != _resolution.width 2745 || m_resolution.height != _resolution.height 2746 || m_resolution.reset != flags) 2747 { 2748 flags &= ~BGFX_RESET_INTERNAL_FORCE; 2749 2750 bool resize = (m_resolution.reset&BGFX_RESET_MSAA_MASK) == (_resolution.reset&BGFX_RESET_MSAA_MASK); 2751 2752 m_resolution = _resolution; 2753 m_resolution.reset = flags; 2754 2755 m_textVideoMem.resize(false, _resolution.width, _resolution.height); 2756 m_textVideoMem.clear(); 2757 2758 if (resize || m_needToRefreshSwapchain) 2759 { 2760 VK_CHECK(vkDeviceWaitIdle(m_device) ); 2761 releaseSwapchainFramebuffer(); 2762 releaseSwapchain(); 2763 2764 uint32_t numPresentModes(10); 2765 VkPresentModeKHR presentModes[10]; 2766 vkGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &numPresentModes, presentModes); 2767 2768 uint32_t presentModeIdx = numPresentModes; 2769 static const VkPresentModeKHR preferredPresentMode[] = 2770 { 2771 VK_PRESENT_MODE_FIFO_KHR, 2772 VK_PRESENT_MODE_FIFO_RELAXED_KHR, 2773 VK_PRESENT_MODE_MAILBOX_KHR, 2774 VK_PRESENT_MODE_IMMEDIATE_KHR, 2775 }; 2776 static const bool hasVsync[] = { true, true, true, false }; 2777 BX_STATIC_ASSERT(BX_COUNTOF(preferredPresentMode) == BX_COUNTOF(hasVsync) ); 2778 2779 const bool vsync = !!(flags & BGFX_RESET_VSYNC); 2780 2781 for (uint32_t ii = 0; ii < BX_COUNTOF(preferredPresentMode); ++ii) 2782 { 2783 for (uint32_t jj = 0; jj < numPresentModes; ++jj) 2784 { 2785 if (presentModes[jj] == preferredPresentMode[ii] 2786 && vsync == hasVsync[ii]) 2787 { 2788 presentModeIdx = jj; 2789 BX_TRACE("present mode: %d", preferredPresentMode[ii]); 2790 break; 2791 } 2792 } 2793 2794 if (presentModeIdx < numPresentModes) 2795 { 2796 break; 2797 } 2798 } 2799 2800 if (presentModeIdx == numPresentModes) 2801 { 2802 presentModeIdx = 0; 2803 } 2804 2805 m_sci.presentMode = presentModes[presentModeIdx]; 2806 2807 VkSurfaceCapabilitiesKHR surfaceCapabilities; 2808 VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_physicalDevice, m_surface, &surfaceCapabilities) ); 2809 2810 m_sci.imageExtent.width = bx::clamp<uint32_t>(m_resolution.width 2811 , surfaceCapabilities.minImageExtent.width 2812 , surfaceCapabilities.maxImageExtent.width 2813 ); 2814 m_sci.imageExtent.height = bx::clamp<uint32_t>(m_resolution.height 2815 , surfaceCapabilities.minImageExtent.height 2816 , surfaceCapabilities.maxImageExtent.height 2817 ); 2818 2819 VK_CHECK(createSwapchain() ); 2820 VK_CHECK(createSwapchainFramebuffer() ); 2821 initSwapchainImageLayout(); 2822 BX_TRACE("refreshed swapchain: %d x %d", m_sci.imageExtent.width, m_sci.imageExtent.height); 2823 } 2824 #if 1 2825 BX_UNUSED(resize); 2826 #else 2827 m_scd.BufferDesc.Width = _resolution.m_width; 2828 m_scd.BufferDesc.Height = _resolution.m_height; 2829 2830 preReset(); 2831 2832 if (resize) 2833 { 2834 uint32_t nodeMask[] = { 1, 1, 1, 1 }; 2835 BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(nodeMask) ); 2836 IUnknown* presentQueue[] ={ m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue }; 2837 BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(presentQueue) ); 2838 2839 DX_CHECK(m_swapChain->ResizeBuffers1(m_scd.BufferCount 2840 , m_scd.BufferDesc.Width 2841 , m_scd.BufferDesc.Height 2842 , m_scd.BufferDesc.Format 2843 , m_scd.Flags 2844 , nodeMask 2845 , presentQueue 2846 ) ); 2847 } 2848 else 2849 { 2850 updateMsaa(); 2851 m_scd.SampleDesc = s_msaa[(m_resolution.m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; 2852 2853 DX_RELEASE(m_swapChain, 0); 2854 2855 HRESULT hr; 2856 hr = m_factory->CreateSwapChain(m_cmd.m_commandQueue 2857 , &m_scd 2858 , reinterpret_cast<IDXGISwapChain**>(&m_swapChain) 2859 ); 2860 BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain."); 2861 } 2862 2863 postReset(); 2864 #endif // 0 2865 } 2866 } 2867 setShaderUniformbgfx::vk::RendererContextVK2868 void setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) 2869 { 2870 BX_UNUSED(_flags, _regIndex, _val, _numRegs); 2871 if (_flags&BGFX_UNIFORM_FRAGMENTBIT) 2872 { 2873 bx::memCopy(&m_fsScratch[_regIndex], _val, _numRegs*16); 2874 m_fsChanges += _numRegs; 2875 } 2876 else 2877 { 2878 bx::memCopy(&m_vsScratch[_regIndex], _val, _numRegs*16); 2879 m_vsChanges += _numRegs; 2880 } 2881 } 2882 setShaderUniform4fbgfx::vk::RendererContextVK2883 void setShaderUniform4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) 2884 { 2885 setShaderUniform(_flags, _regIndex, _val, _numRegs); 2886 } 2887 setShaderUniform4x4fbgfx::vk::RendererContextVK2888 void setShaderUniform4x4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) 2889 { 2890 setShaderUniform(_flags, _regIndex, _val, _numRegs); 2891 } 2892 2893 // void commitShaderUniforms(VkCommandBuffer _commandBuffer, ProgramHandle _program) 2894 // { 2895 // ProgramVK& program = m_program[_program.idx]; 2896 // 2897 // const uint32_t align = uint32_t(m_deviceProperties.limits.minUniformBufferOffsetAlignment); 2898 // const uint32_t vsize = bx::strideAlign(program.m_vsh->m_size, align); 2899 // const uint32_t fsize = bx::strideAlign( (NULL != program.m_fsh ? program.m_fsh->m_size : 0), align); 2900 // const uint32_t total = vsize + fsize; 2901 // 2902 // if (0 < total) 2903 // { 2904 // ScratchBufferVK& sb = m_scratchBuffer[m_backBufferColorIdx]; 2905 // 2906 // uint8_t* data = (uint8_t*)sb.allocUbv(vsize, fsize); 2907 // 2908 // bx::memCopy(data, m_vsScratch, program.m_vsh->m_size); 2909 // data += vsize; 2910 // 2911 // if (0 != fsize) 2912 // { 2913 // bx::memCopy(data, m_fsScratch, program.m_fsh->m_size); 2914 // } 2915 // 2916 // vkCmdBindDescriptorSets(_commandBuffer 2917 // , VK_PIPELINE_BIND_POINT_GRAPHICS 2918 // , m_pipelineLayout 2919 // , program.m_pipelineLayout 2920 // , 0 2921 // , 1 2922 // , &sb.m_descriptorSet[sb.m_currentDs - 1] 2923 // , 0 2924 // , NULL 2925 // ); 2926 // } 2927 // 2928 // m_vsChanges = 0; 2929 // m_fsChanges = 0; 2930 // } 2931 setFrameBufferbgfx::vk::RendererContextVK2932 void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true) 2933 { 2934 BX_UNUSED(_msaa); 2935 2936 if (isValid(m_fbh) 2937 && m_fbh.idx != _fbh.idx) 2938 { 2939 const FrameBufferVK& frameBuffer = m_frameBuffers[m_fbh.idx]; 2940 BX_UNUSED(frameBuffer); 2941 2942 for (uint8_t ii = 0, num = frameBuffer.m_num; ii < num; ++ii) 2943 { 2944 TextureVK& texture = m_textures[frameBuffer.m_texture[ii].idx]; 2945 texture.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 2946 } 2947 2948 if (isValid(frameBuffer.m_depth) ) 2949 { 2950 TextureVK& texture = m_textures[frameBuffer.m_depth.idx]; 2951 const bool writeOnly = 0 != (texture.m_flags&BGFX_TEXTURE_RT_WRITE_ONLY); 2952 if (!writeOnly) 2953 { 2954 texture.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 2955 } 2956 } 2957 } 2958 2959 if (!isValid(_fbh) ) 2960 { 2961 // m_rtvHandle = m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); 2962 // uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); 2963 // m_rtvHandle.ptr += m_backBufferColorIdx * rtvDescriptorSize; 2964 // m_dsvHandle = m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); 2965 // 2966 // m_currentColor = &m_rtvHandle; 2967 // m_currentDepthStencil = &m_dsvHandle; 2968 // m_commandList->OMSetRenderTargets(1, m_currentColor, true, m_currentDepthStencil); 2969 } 2970 else 2971 { 2972 const FrameBufferVK& frameBuffer = m_frameBuffers[_fbh.idx]; 2973 BX_UNUSED(frameBuffer); 2974 2975 if (0 < frameBuffer.m_num) 2976 { 2977 // D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = m_rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); 2978 // uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); 2979 // m_rtvHandle.ptr = rtvDescriptor.ptr + (BX_COUNTOF(m_backBufferColor) + _fbh.idx * BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) * rtvDescriptorSize; 2980 // m_currentColor = &m_rtvHandle; 2981 } 2982 else 2983 { 2984 // m_currentColor = NULL; 2985 } 2986 2987 if (isValid(frameBuffer.m_depth) ) 2988 { 2989 // D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = m_dsvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); 2990 // uint32_t dsvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); 2991 // m_dsvHandle.ptr = dsvDescriptor.ptr + (1 + _fbh.idx) * dsvDescriptorSize; 2992 // m_currentDepthStencil = &m_dsvHandle; 2993 } 2994 else 2995 { 2996 // m_currentDepthStencil = NULL; 2997 } 2998 2999 for (uint8_t ii = 0, num = frameBuffer.m_num; ii < num; ++ii) 3000 { 3001 TextureVK& texture = m_textures[frameBuffer.m_texture[ii].idx]; 3002 texture.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 3003 } 3004 3005 if (isValid(frameBuffer.m_depth) ) 3006 { 3007 TextureVK& texture = m_textures[frameBuffer.m_depth.idx]; 3008 texture.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); 3009 } 3010 3011 // m_commandList->OMSetRenderTargets(frameBuffer.m_num 3012 // , m_currentColor 3013 // , true 3014 // , m_currentDepthStencil 3015 // ); 3016 } 3017 3018 m_fbh = _fbh; 3019 // m_rtMsaa = _msaa; 3020 } 3021 setBlendStatebgfx::vk::RendererContextVK3022 void setBlendState(VkPipelineColorBlendStateCreateInfo& _desc, uint64_t _state, uint32_t _rgba = 0) 3023 { 3024 VkPipelineColorBlendAttachmentState* bas = const_cast<VkPipelineColorBlendAttachmentState*>(_desc.pAttachments); 3025 3026 uint8_t writeMask = 0; 3027 writeMask |= (_state & BGFX_STATE_WRITE_R) ? VK_COLOR_COMPONENT_R_BIT : 0; 3028 writeMask |= (_state & BGFX_STATE_WRITE_G) ? VK_COLOR_COMPONENT_G_BIT : 0; 3029 writeMask |= (_state & BGFX_STATE_WRITE_B) ? VK_COLOR_COMPONENT_B_BIT : 0; 3030 writeMask |= (_state & BGFX_STATE_WRITE_A) ? VK_COLOR_COMPONENT_A_BIT : 0; 3031 3032 bas->blendEnable = !!(BGFX_STATE_BLEND_MASK & _state); 3033 3034 { 3035 const uint32_t blend = uint32_t( (_state & BGFX_STATE_BLEND_MASK ) >> BGFX_STATE_BLEND_SHIFT); 3036 const uint32_t equation = uint32_t( (_state & BGFX_STATE_BLEND_EQUATION_MASK) >> BGFX_STATE_BLEND_EQUATION_SHIFT); 3037 3038 const uint32_t srcRGB = (blend ) & 0xf; 3039 const uint32_t dstRGB = (blend >> 4) & 0xf; 3040 const uint32_t srcA = (blend >> 8) & 0xf; 3041 const uint32_t dstA = (blend >> 12) & 0xf; 3042 3043 const uint32_t equRGB = (equation ) & 0x7; 3044 const uint32_t equA = (equation >> 3) & 0x7; 3045 3046 bas->srcColorBlendFactor = s_blendFactor[srcRGB][0]; 3047 bas->dstColorBlendFactor = s_blendFactor[dstRGB][0]; 3048 bas->colorBlendOp = s_blendEquation[equRGB]; 3049 3050 bas->srcAlphaBlendFactor = s_blendFactor[srcA][1]; 3051 bas->dstAlphaBlendFactor = s_blendFactor[dstA][1]; 3052 bas->alphaBlendOp = s_blendEquation[equA]; 3053 3054 bas->colorWriteMask = writeMask; 3055 } 3056 3057 uint32_t numAttachments = 1; 3058 if (isValid(m_fbh) ) 3059 { 3060 const FrameBufferVK& frameBuffer = m_frameBuffers[m_fbh.idx]; 3061 numAttachments = frameBuffer.m_num; 3062 } 3063 3064 if (!!(BGFX_STATE_BLEND_INDEPENDENT & _state) && m_deviceFeatures.independentBlend ) 3065 { 3066 for (uint32_t ii = 1, rgba = _rgba; ii < numAttachments; ++ii, rgba >>= 11) 3067 { 3068 ++bas; 3069 bas->blendEnable = 0 != (rgba & 0x7ff); 3070 3071 const uint32_t src = (rgba ) & 0xf; 3072 const uint32_t dst = (rgba >> 4) & 0xf; 3073 const uint32_t equation = (rgba >> 8) & 0x7; 3074 3075 bas->srcColorBlendFactor = s_blendFactor[src][0]; 3076 bas->dstColorBlendFactor = s_blendFactor[dst][0]; 3077 bas->colorBlendOp = s_blendEquation[equation]; 3078 3079 bas->srcAlphaBlendFactor = s_blendFactor[src][1]; 3080 bas->dstAlphaBlendFactor = s_blendFactor[dst][1]; 3081 bas->alphaBlendOp = s_blendEquation[equation]; 3082 3083 bas->colorWriteMask = writeMask; 3084 } 3085 } 3086 else 3087 { 3088 for (uint32_t ii = 1; ii < numAttachments; ++ii) 3089 { 3090 bx::memCopy(&bas[ii], bas, sizeof(VkPipelineColorBlendAttachmentState) ); 3091 } 3092 } 3093 3094 _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 3095 _desc.pNext = NULL; 3096 _desc.flags = 0; 3097 _desc.logicOpEnable = VK_FALSE; 3098 _desc.logicOp = VK_LOGIC_OP_CLEAR; 3099 _desc.attachmentCount = numAttachments; 3100 _desc.blendConstants[0] = 0.0f; 3101 _desc.blendConstants[1] = 0.0f; 3102 _desc.blendConstants[2] = 0.0f; 3103 _desc.blendConstants[3] = 0.0f; 3104 } 3105 setRasterizerStatebgfx::vk::RendererContextVK3106 void setRasterizerState(VkPipelineRasterizationStateCreateInfo& _desc, uint64_t _state, bool _wireframe = false) 3107 { 3108 const uint32_t cull = (_state&BGFX_STATE_CULL_MASK) >> BGFX_STATE_CULL_SHIFT; 3109 3110 _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 3111 _desc.pNext = NULL; 3112 _desc.flags = 0; 3113 _desc.depthClampEnable = m_depthClamp; 3114 _desc.rasterizerDiscardEnable = VK_FALSE; 3115 _desc.polygonMode = _wireframe 3116 ? VK_POLYGON_MODE_LINE 3117 : VK_POLYGON_MODE_FILL 3118 ; 3119 _desc.cullMode = s_cullMode[cull]; 3120 _desc.frontFace = (_state&BGFX_STATE_FRONT_CCW) ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE; 3121 _desc.depthBiasEnable = VK_FALSE; 3122 _desc.depthBiasConstantFactor = 0.0f; 3123 _desc.depthBiasClamp = 0.0f; 3124 _desc.depthBiasSlopeFactor = 0.0f; 3125 _desc.lineWidth = 1.0f; 3126 } 3127 setDepthStencilStatebgfx::vk::RendererContextVK3128 void setDepthStencilState(VkPipelineDepthStencilStateCreateInfo& _desc, uint64_t _state, uint64_t _stencil = 0) 3129 { 3130 const uint32_t fstencil = unpackStencil(0, _stencil); 3131 uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT; 3132 3133 _desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 3134 _desc.pNext = NULL; 3135 _desc.flags = 0; 3136 _desc.depthTestEnable = 0 != func; 3137 _desc.depthWriteEnable = !!(BGFX_STATE_WRITE_Z & _state); 3138 _desc.depthCompareOp = s_cmpFunc[func]; 3139 _desc.depthBoundsTestEnable = VK_FALSE; 3140 3141 _desc.stencilTestEnable = 0 != _stencil; 3142 3143 uint32_t bstencil = unpackStencil(1, _stencil); 3144 uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil; 3145 bstencil = frontAndBack ? bstencil : fstencil; 3146 3147 _desc.front.failOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT]; 3148 _desc.front.passOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT]; 3149 _desc.front.depthFailOp = s_stencilOp[(fstencil & BGFX_STENCIL_OP_FAIL_Z_MASK) >> BGFX_STENCIL_OP_FAIL_Z_SHIFT]; 3150 _desc.front.compareOp = s_cmpFunc[(fstencil & BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT]; 3151 _desc.front.compareMask = UINT32_MAX; 3152 _desc.front.writeMask = UINT32_MAX; 3153 _desc.front.reference = 0; 3154 3155 _desc.back.failOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_FAIL_S_MASK) >> BGFX_STENCIL_OP_FAIL_S_SHIFT]; 3156 _desc.back.passOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_PASS_Z_MASK) >> BGFX_STENCIL_OP_PASS_Z_SHIFT]; 3157 _desc.back.depthFailOp = s_stencilOp[(bstencil & BGFX_STENCIL_OP_FAIL_Z_MASK) >> BGFX_STENCIL_OP_FAIL_Z_SHIFT]; 3158 _desc.back.compareOp = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT]; 3159 _desc.back.compareMask = UINT32_MAX; 3160 _desc.back.writeMask = UINT32_MAX; 3161 _desc.back.reference = 0; 3162 3163 _desc.minDepthBounds = 0.0f; 3164 _desc.maxDepthBounds = 1.0f; 3165 } 3166 setInputLayoutbgfx::vk::RendererContextVK3167 void setInputLayout(VkPipelineVertexInputStateCreateInfo& _vertexInputState, uint8_t _numStream, const VertexLayout** _layout, const ProgramVK& _program, uint8_t _numInstanceData) 3168 { 3169 _vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 3170 _vertexInputState.pNext = NULL; 3171 _vertexInputState.flags = 0; 3172 3173 _vertexInputState.vertexBindingDescriptionCount = 0; 3174 _vertexInputState.vertexAttributeDescriptionCount = 0; 3175 3176 uint16_t unsettedAttr[Attrib::Count]; 3177 bx::memCopy(unsettedAttr, _program.m_vsh->m_attrMask, sizeof(uint16_t) * Attrib::Count); 3178 for (uint8_t stream = 0; stream < _numStream; ++stream) 3179 { 3180 VertexLayout layout; 3181 bx::memCopy(&layout, _layout[stream], sizeof(VertexLayout) ); 3182 const uint16_t* attrMask = _program.m_vsh->m_attrMask; 3183 3184 for (uint32_t ii = 0; ii < Attrib::Count; ++ii) 3185 { 3186 uint16_t mask = attrMask[ii]; 3187 uint16_t attr = (layout.m_attributes[ii] & mask); 3188 layout.m_attributes[ii] = attr == 0 || attr == UINT16_MAX ? UINT16_MAX : attr; 3189 if (unsettedAttr[ii] && attr != UINT16_MAX) 3190 { 3191 unsettedAttr[ii] = 0; 3192 } 3193 } 3194 3195 fillVertexLayout(_program.m_vsh, _vertexInputState, layout); 3196 } 3197 3198 for (uint32_t ii = 0; ii < Attrib::Count; ++ii) 3199 { 3200 if (0 < unsettedAttr[ii]) 3201 { 3202 uint32_t numAttribs = _vertexInputState.vertexAttributeDescriptionCount; 3203 VkVertexInputAttributeDescription* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs); 3204 inputAttrib->location = _program.m_vsh->m_attrRemap[ii]; 3205 inputAttrib->binding = 0; 3206 inputAttrib->format = VK_FORMAT_R32G32B32_SFLOAT; 3207 inputAttrib->offset = 0; 3208 _vertexInputState.vertexAttributeDescriptionCount++; 3209 } 3210 } 3211 3212 if (0 < _numInstanceData) 3213 { 3214 fillInstanceBinding(_program.m_vsh, _vertexInputState, _numInstanceData); 3215 } 3216 } 3217 getRenderPassHashkeybgfx::vk::RendererContextVK3218 uint32_t getRenderPassHashkey(uint8_t _num, const Attachment* attachments) 3219 { 3220 if (_num == 0) 3221 return 0; 3222 bx::HashMurmur2A hash; 3223 hash.begin(0); 3224 for (uint8_t ii = 0; ii < _num; ++ii) 3225 { 3226 hash.add(attachments[ii].access); 3227 hash.add(attachments[ii].layer); 3228 hash.add(attachments[ii].mip); 3229 hash.add(attachments[ii].resolve); 3230 3231 TextureVK& texture = m_textures[attachments[ii].handle.idx]; 3232 hash.add(texture.m_textureFormat); 3233 } 3234 return hash.end(); 3235 } 3236 getRenderPassbgfx::vk::RendererContextVK3237 VkRenderPass getRenderPass(uint8_t _num, const Attachment* _attachments) 3238 { 3239 VkRenderPass renderPass = VK_NULL_HANDLE; 3240 uint32_t hashKey = getRenderPassHashkey(_num, _attachments); 3241 renderPass = (VkRenderPass)m_renderPassCache.find(hashKey); 3242 if (renderPass != VK_NULL_HANDLE) 3243 return renderPass; 3244 3245 // cache missed 3246 VkAttachmentDescription ad[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; 3247 VkAttachmentReference colorAr[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; 3248 VkAttachmentReference resolveAr[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; 3249 VkAttachmentReference depthAr; 3250 uint32_t numColorAr = 0; 3251 3252 depthAr.attachment = VK_ATTACHMENT_UNUSED; 3253 depthAr.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 3254 3255 for (uint8_t ii = 0; ii < _num; ++ii) 3256 { 3257 TextureVK& texture = m_textures[_attachments[ii].handle.idx]; 3258 ad[ii].flags = 0; 3259 ad[ii].format = texture.m_vkTextureFormat; 3260 ad[ii].samples = VK_SAMPLE_COUNT_1_BIT; 3261 3262 if (texture.m_vkTextureAspect & VK_IMAGE_ASPECT_COLOR_BIT) 3263 { 3264 ad[ii].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 3265 ad[ii].storeOp = VK_ATTACHMENT_STORE_OP_STORE; 3266 ad[ii].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 3267 ad[ii].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 3268 ad[ii].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 3269 ad[ii].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 3270 colorAr[numColorAr].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 3271 colorAr[numColorAr].attachment = ii; 3272 numColorAr++; 3273 } 3274 else if (texture.m_vkTextureAspect & VK_IMAGE_ASPECT_DEPTH_BIT) 3275 { 3276 ad[ii].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 3277 ad[ii].storeOp = VK_ATTACHMENT_STORE_OP_STORE; 3278 ad[ii].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 3279 ad[ii].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; 3280 ad[ii].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 3281 ad[ii].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 3282 depthAr.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 3283 depthAr.attachment = ii; 3284 } 3285 3286 resolveAr[ii].attachment = VK_ATTACHMENT_UNUSED; 3287 resolveAr[ii].layout = ad[ii].initialLayout; 3288 } 3289 3290 VkSubpassDescription sd[1]; 3291 sd[0].flags = 0; 3292 sd[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 3293 sd[0].inputAttachmentCount = 0; 3294 sd[0].pInputAttachments = NULL; 3295 sd[0].colorAttachmentCount = numColorAr; 3296 sd[0].pColorAttachments = colorAr; 3297 sd[0].pResolveAttachments = resolveAr; 3298 sd[0].pDepthStencilAttachment = &depthAr; 3299 sd[0].preserveAttachmentCount = 0; 3300 sd[0].pPreserveAttachments = NULL; 3301 3302 VkRenderPassCreateInfo rpi; 3303 rpi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 3304 rpi.pNext = NULL; 3305 rpi.flags = 0; 3306 rpi.attachmentCount = _num; 3307 rpi.pAttachments = ad; 3308 rpi.subpassCount = BX_COUNTOF(sd); 3309 rpi.pSubpasses = sd; 3310 rpi.dependencyCount = 0; 3311 rpi.pDependencies = NULL; 3312 3313 VK_CHECK( vkCreateRenderPass(m_device, &rpi, m_allocatorCb, &renderPass) ); 3314 3315 m_renderPassCache.add(hashKey, renderPass); 3316 return renderPass; 3317 } 3318 getSamplerbgfx::vk::RendererContextVK3319 VkSampler getSampler(uint32_t _samplerFlags, uint32_t _mipLevels) 3320 { 3321 bx::HashMurmur2A hash; 3322 hash.begin(); 3323 hash.add(_samplerFlags); 3324 hash.add(_mipLevels); 3325 uint32_t hashKey = hash.end(); 3326 3327 VkSampler sampler = m_samplerCache.find(hashKey); 3328 if (sampler != VK_NULL_HANDLE) 3329 { 3330 return sampler; 3331 } 3332 3333 const uint32_t cmpFunc = (_samplerFlags&BGFX_SAMPLER_COMPARE_MASK)>>BGFX_SAMPLER_COMPARE_SHIFT; 3334 3335 VkSamplerCreateInfo sci; 3336 sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 3337 sci.pNext = NULL; 3338 sci.flags = 0; 3339 sci.magFilter = VK_FILTER_LINEAR; 3340 sci.minFilter = VK_FILTER_LINEAR; 3341 sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; 3342 sci.addressModeU = s_textureAddress[(_samplerFlags&BGFX_SAMPLER_U_MASK)>>BGFX_SAMPLER_U_SHIFT]; 3343 sci.addressModeV = s_textureAddress[(_samplerFlags&BGFX_SAMPLER_V_MASK)>>BGFX_SAMPLER_V_SHIFT]; 3344 sci.addressModeW = s_textureAddress[(_samplerFlags&BGFX_SAMPLER_W_MASK)>>BGFX_SAMPLER_W_SHIFT]; 3345 sci.mipLodBias = 0.0f; 3346 sci.anisotropyEnable = VK_FALSE; 3347 sci.maxAnisotropy = 4.0f; 3348 sci.compareEnable = 0 != cmpFunc; 3349 sci.compareOp = s_cmpFunc[cmpFunc]; 3350 sci.minLod = 0.0f; 3351 sci.maxLod = (float)_mipLevels; 3352 sci.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; 3353 sci.unnormalizedCoordinates = VK_FALSE; 3354 3355 switch (_samplerFlags & BGFX_SAMPLER_MAG_MASK) 3356 { 3357 case BGFX_SAMPLER_MAG_POINT: sci.magFilter = VK_FILTER_NEAREST; break; 3358 case BGFX_SAMPLER_MAG_ANISOTROPIC: sci.anisotropyEnable = VK_TRUE; break; 3359 } 3360 3361 switch (_samplerFlags & BGFX_SAMPLER_MIN_MASK) 3362 { 3363 case BGFX_SAMPLER_MIN_POINT: sci.minFilter = VK_FILTER_NEAREST; break; 3364 case BGFX_SAMPLER_MIN_ANISOTROPIC: sci.anisotropyEnable = VK_TRUE; break; 3365 } 3366 3367 uint32_t borderColor = ((_samplerFlags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT); 3368 if (borderColor > 0) 3369 { 3370 sci.borderColor = VK_BORDER_COLOR_INT_OPAQUE_WHITE; 3371 } 3372 3373 VK_CHECK(vkCreateSampler(m_device, &sci, m_allocatorCb, &sampler)); 3374 3375 m_samplerCache.add(hashKey, sampler); 3376 return sampler; 3377 } 3378 getPipelinebgfx::vk::RendererContextVK3379 VkPipeline getPipeline(ProgramHandle _program) 3380 { 3381 ProgramVK& program = m_program[_program.idx]; 3382 3383 bx::HashMurmur2A murmur; 3384 murmur.begin(); 3385 murmur.add(program.m_vsh->m_hash); 3386 const uint32_t hash = murmur.end(); 3387 3388 VkPipeline pipeline = m_pipelineStateCache.find(hash); 3389 3390 if (VK_NULL_HANDLE != pipeline) 3391 { 3392 return pipeline; 3393 } 3394 3395 VkComputePipelineCreateInfo cpci; 3396 cpci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; 3397 cpci.pNext = NULL; 3398 cpci.flags = 0; 3399 3400 cpci.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 3401 cpci.stage.pNext = NULL; 3402 cpci.stage.flags = 0; 3403 cpci.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; 3404 cpci.stage.module = program.m_vsh->m_module; 3405 cpci.stage.pName = "main"; 3406 cpci.stage.pSpecializationInfo = NULL; 3407 3408 cpci.layout = program.m_pipelineLayout; 3409 cpci.basePipelineHandle = VK_NULL_HANDLE; 3410 cpci.basePipelineIndex = 0; 3411 3412 VK_CHECK( vkCreateComputePipelines(m_device, m_pipelineCache, 1, &cpci, m_allocatorCb, &pipeline) ); 3413 3414 m_pipelineStateCache.add(hash, pipeline); 3415 3416 return pipeline; 3417 } 3418 getPipelinebgfx::vk::RendererContextVK3419 VkPipeline getPipeline(uint64_t _state, uint64_t _stencil, uint8_t _numStreams, const VertexLayout** _layouts, ProgramHandle _program, uint8_t _numInstanceData) 3420 { 3421 ProgramVK& program = m_program[_program.idx]; 3422 3423 _state &= 0 3424 | BGFX_STATE_WRITE_RGB 3425 | BGFX_STATE_WRITE_A 3426 | BGFX_STATE_WRITE_Z 3427 | BGFX_STATE_DEPTH_TEST_MASK 3428 | BGFX_STATE_BLEND_MASK 3429 | BGFX_STATE_BLEND_EQUATION_MASK 3430 | BGFX_STATE_BLEND_INDEPENDENT 3431 | BGFX_STATE_BLEND_ALPHA_TO_COVERAGE 3432 | BGFX_STATE_CULL_MASK 3433 | BGFX_STATE_MSAA 3434 | BGFX_STATE_LINEAA 3435 | BGFX_STATE_CONSERVATIVE_RASTER 3436 | BGFX_STATE_PT_MASK 3437 ; 3438 3439 _stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK); 3440 3441 VertexLayout layout; 3442 if (0 < _numStreams) 3443 { 3444 bx::memCopy(&layout, _layouts[0], sizeof(VertexLayout) ); 3445 const uint16_t* attrMask = program.m_vsh->m_attrMask; 3446 3447 for (uint32_t ii = 0; ii < Attrib::Count; ++ii) 3448 { 3449 uint16_t mask = attrMask[ii]; 3450 uint16_t attr = (layout.m_attributes[ii] & mask); 3451 layout.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; 3452 } 3453 } 3454 3455 bx::HashMurmur2A murmur; 3456 murmur.begin(); 3457 murmur.add(_state); 3458 murmur.add(_stencil); 3459 murmur.add(program.m_vsh->m_hash); 3460 murmur.add(program.m_vsh->m_attrMask, sizeof(program.m_vsh->m_attrMask) ); 3461 murmur.add(program.m_fsh->m_hash); 3462 for (uint8_t ii = 0; ii < _numStreams; ++ii) 3463 { 3464 murmur.add(_layouts[ii]->m_hash); 3465 } 3466 murmur.add(layout.m_attributes, sizeof(layout.m_attributes) ); 3467 murmur.add(m_fbh.idx); 3468 murmur.add(_numInstanceData); 3469 const uint32_t hash = murmur.end(); 3470 3471 VkPipeline pipeline = m_pipelineStateCache.find(hash); 3472 3473 if (VK_NULL_HANDLE != pipeline) 3474 { 3475 return pipeline; 3476 } 3477 3478 VkPipelineColorBlendAttachmentState blendAttachmentState[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; 3479 VkPipelineColorBlendStateCreateInfo colorBlendState; 3480 colorBlendState.pAttachments = blendAttachmentState; 3481 setBlendState(colorBlendState, _state); 3482 3483 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState; 3484 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 3485 inputAssemblyState.pNext = NULL; 3486 inputAssemblyState.flags = 0; 3487 inputAssemblyState.topology = s_primInfo[(_state&BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT].m_topology; 3488 inputAssemblyState.primitiveRestartEnable = VK_FALSE; 3489 3490 VkPipelineRasterizationStateCreateInfo rasterizationState; 3491 setRasterizerState(rasterizationState, _state); 3492 3493 VkPipelineDepthStencilStateCreateInfo depthStencilState; 3494 setDepthStencilState(depthStencilState, _state, _stencil); 3495 3496 VkVertexInputBindingDescription inputBinding[Attrib::Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; 3497 VkVertexInputAttributeDescription inputAttrib[Attrib::Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; 3498 3499 VkPipelineVertexInputStateCreateInfo vertexInputState; 3500 vertexInputState.pVertexBindingDescriptions = inputBinding; 3501 vertexInputState.pVertexAttributeDescriptions = inputAttrib; 3502 setInputLayout(vertexInputState, _numStreams, _layouts, program, _numInstanceData); 3503 3504 const VkDynamicState dynamicStates[] = 3505 { 3506 VK_DYNAMIC_STATE_VIEWPORT, 3507 VK_DYNAMIC_STATE_SCISSOR, 3508 VK_DYNAMIC_STATE_BLEND_CONSTANTS, 3509 VK_DYNAMIC_STATE_STENCIL_REFERENCE, 3510 }; 3511 3512 VkPipelineDynamicStateCreateInfo dynamicState; 3513 dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 3514 dynamicState.pNext = NULL; 3515 dynamicState.flags = 0; 3516 dynamicState.dynamicStateCount = BX_COUNTOF(dynamicStates); 3517 dynamicState.pDynamicStates = dynamicStates; 3518 3519 VkPipelineShaderStageCreateInfo shaderStages[2]; 3520 shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 3521 shaderStages[0].pNext = NULL; 3522 shaderStages[0].flags = 0; 3523 shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; 3524 shaderStages[0].module = program.m_vsh->m_module; 3525 shaderStages[0].pName = "main"; 3526 shaderStages[0].pSpecializationInfo = NULL; 3527 shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 3528 shaderStages[1].pNext = NULL; 3529 shaderStages[1].flags = 0; 3530 shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; 3531 shaderStages[1].module = program.m_fsh->m_module; 3532 shaderStages[1].pName = "main"; 3533 shaderStages[1].pSpecializationInfo = NULL; 3534 3535 VkPipelineViewportStateCreateInfo viewportState; 3536 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 3537 viewportState.pNext = NULL; 3538 viewportState.flags = 0; 3539 viewportState.viewportCount = 1; 3540 viewportState.pViewports = NULL; 3541 viewportState.scissorCount = 1; 3542 viewportState.pScissors = NULL; 3543 3544 VkPipelineMultisampleStateCreateInfo multisampleState; 3545 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 3546 multisampleState.pNext = NULL; 3547 multisampleState.flags = 0; 3548 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 3549 multisampleState.sampleShadingEnable = VK_FALSE; 3550 multisampleState.minSampleShading = !!(BGFX_STATE_CONSERVATIVE_RASTER & _state) ? 1.0f : 0.0f; 3551 multisampleState.pSampleMask = NULL; 3552 multisampleState.alphaToCoverageEnable = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state); 3553 multisampleState.alphaToOneEnable = VK_FALSE; 3554 3555 VkGraphicsPipelineCreateInfo graphicsPipeline; 3556 graphicsPipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 3557 graphicsPipeline.pNext = NULL; 3558 graphicsPipeline.flags = 0; 3559 graphicsPipeline.stageCount = BX_COUNTOF(shaderStages); 3560 graphicsPipeline.pStages = shaderStages; 3561 graphicsPipeline.pVertexInputState = &vertexInputState; 3562 graphicsPipeline.pInputAssemblyState = &inputAssemblyState; 3563 graphicsPipeline.pTessellationState = NULL; 3564 graphicsPipeline.pViewportState = &viewportState; 3565 graphicsPipeline.pRasterizationState = &rasterizationState; 3566 graphicsPipeline.pMultisampleState = &multisampleState; 3567 graphicsPipeline.pDepthStencilState = &depthStencilState; 3568 graphicsPipeline.pColorBlendState = &colorBlendState; 3569 graphicsPipeline.pDynamicState = &dynamicState; 3570 // graphicsPipeline.layout = m_pipelineLayout; 3571 graphicsPipeline.layout = program.m_pipelineLayout; 3572 graphicsPipeline.renderPass = isValid(m_fbh) ? m_frameBuffers[m_fbh.idx].m_renderPass : m_renderPass; 3573 graphicsPipeline.subpass = 0; 3574 graphicsPipeline.basePipelineHandle = VK_NULL_HANDLE; 3575 graphicsPipeline.basePipelineIndex = 0; 3576 3577 uint32_t length = g_callback->cacheReadSize(hash); 3578 bool cached = length > 0; 3579 3580 void* cachedData = NULL; 3581 3582 VkPipelineCacheCreateInfo pcci; 3583 pcci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 3584 pcci.pNext = NULL; 3585 pcci.flags = 0; 3586 pcci.initialDataSize = 0; 3587 pcci.pInitialData = NULL; 3588 3589 if (cached) 3590 { 3591 cachedData = BX_ALLOC(g_allocator, length); 3592 if (g_callback->cacheRead(hash, cachedData, length) ) 3593 { 3594 BX_TRACE("Loading cached pipeline state (size %d).", length); 3595 bx::MemoryReader reader(cachedData, length); 3596 3597 pcci.initialDataSize = (size_t)reader.remaining(); 3598 pcci.pInitialData = reader.getDataPtr(); 3599 } 3600 } 3601 3602 VkPipelineCache cache; 3603 VK_CHECK(vkCreatePipelineCache(m_device, &pcci, m_allocatorCb, &cache) ); 3604 3605 VK_CHECK(vkCreateGraphicsPipelines(m_device 3606 , cache 3607 , 1 3608 , &graphicsPipeline 3609 , m_allocatorCb 3610 , &pipeline 3611 ) ); 3612 m_pipelineStateCache.add(hash, pipeline); 3613 3614 size_t dataSize; 3615 VK_CHECK(vkGetPipelineCacheData(m_device, cache, &dataSize, NULL) ); 3616 3617 if (0 < dataSize) 3618 { 3619 if (length < dataSize) 3620 { 3621 cachedData = BX_REALLOC(g_allocator, cachedData, dataSize); 3622 } 3623 VK_CHECK(vkGetPipelineCacheData(m_device, cache, &dataSize, cachedData) ); 3624 g_callback->cacheWrite(hash, cachedData, (uint32_t)dataSize); 3625 } 3626 3627 VK_CHECK(vkMergePipelineCaches(m_device, m_pipelineCache, 1, &cache) ); 3628 vkDestroy(cache); 3629 3630 if (NULL != cachedData) 3631 { 3632 BX_FREE(g_allocator, cachedData); 3633 } 3634 3635 return pipeline; 3636 } 3637 allocDescriptorSetbgfx::vk::RendererContextVK3638 void allocDescriptorSet(ProgramVK& program, const RenderBind& renderBind, ScratchBufferVK& scratchBuffer) 3639 { 3640 VkDescriptorSetLayout dsl = m_descriptorSetLayoutCache.find(program.m_descriptorSetLayoutHash); 3641 VkDescriptorSetAllocateInfo dsai; 3642 dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 3643 dsai.pNext = NULL; 3644 dsai.descriptorPool = m_descriptorPool; 3645 dsai.descriptorSetCount = 1; 3646 dsai.pSetLayouts = &dsl; 3647 3648 VkDescriptorSet& descriptorSet = scratchBuffer.m_descriptorSet[scratchBuffer.m_currentDs]; 3649 vkAllocateDescriptorSets(m_device, &dsai, &descriptorSet); 3650 scratchBuffer.m_currentDs++; 3651 3652 VkDescriptorImageInfo imageInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; 3653 VkDescriptorBufferInfo bufferInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; 3654 VkWriteDescriptorSet wds[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; 3655 bx::memSet(wds, 0, sizeof(VkWriteDescriptorSet) * BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); 3656 uint32_t wdsCount = 0; 3657 uint32_t bufferCount = 0; 3658 uint32_t imageCount = 0; 3659 3660 for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) 3661 { 3662 const Binding& bind = renderBind.m_bind[stage]; 3663 if (kInvalidHandle != bind.m_idx) 3664 { 3665 const ShaderVK::BindInfo* bindInfo = NULL; 3666 if (isValid(program.m_vsh->m_bindInfo[stage].uniformHandle)) 3667 { 3668 bindInfo = &(program.m_vsh->m_bindInfo[stage]); 3669 } 3670 else if (NULL != program.m_fsh && isValid(program.m_fsh->m_bindInfo[stage].uniformHandle)) 3671 { 3672 bindInfo = &(program.m_fsh->m_bindInfo[stage]); 3673 } 3674 3675 if (NULL == bindInfo) 3676 { 3677 continue; 3678 } 3679 3680 if (ShaderVK::BindType::Storage == bindInfo->type) 3681 { 3682 VkDescriptorType descriptorType = (VkDescriptorType)bindInfo->samplerBinding; 3683 wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 3684 wds[wdsCount].pNext = NULL; 3685 wds[wdsCount].dstSet = descriptorSet; 3686 wds[wdsCount].dstBinding = bindInfo->binding; 3687 wds[wdsCount].dstArrayElement = 0; 3688 wds[wdsCount].descriptorCount = 1; 3689 wds[wdsCount].descriptorType = descriptorType; 3690 wds[wdsCount].pImageInfo = NULL; 3691 wds[wdsCount].pBufferInfo = NULL; 3692 wds[wdsCount].pTexelBufferView = NULL; 3693 3694 if (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == descriptorType) 3695 { 3696 VertexBufferVK& vb = m_vertexBuffers[bind.m_idx]; 3697 bufferInfo[bufferCount].buffer = vb.m_buffer; 3698 bufferInfo[bufferCount].offset = 0; 3699 bufferInfo[bufferCount].range = vb.m_size; 3700 wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount]; 3701 ++bufferCount; 3702 } 3703 else if (VK_DESCRIPTOR_TYPE_STORAGE_IMAGE == descriptorType) 3704 { 3705 TextureVK& texture = m_textures[bind.m_idx]; 3706 VkSampler sampler = getSampler( 3707 (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags) 3708 ? bind.m_samplerFlags 3709 : (uint32_t)texture.m_flags 3710 ) & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK) 3711 , (uint32_t)texture.m_numMips); 3712 3713 if (VK_IMAGE_LAYOUT_GENERAL != texture.m_currentImageLayout 3714 && VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL != texture.m_currentImageLayout) 3715 { 3716 texture.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 3717 } 3718 3719 imageInfo[imageCount].imageLayout = texture.m_currentImageLayout; 3720 imageInfo[imageCount].imageView = VK_NULL_HANDLE != texture.m_textureImageStorageView 3721 ? texture.m_textureImageStorageView 3722 : texture.m_textureImageView 3723 ; 3724 imageInfo[imageCount].sampler = sampler; 3725 wds[wdsCount].pImageInfo = &imageInfo[imageCount]; 3726 ++imageCount; 3727 } 3728 3729 ++wdsCount; 3730 } 3731 else if (ShaderVK::BindType::Sampler == bindInfo->type) 3732 { 3733 TextureVK& texture = m_textures[bind.m_idx]; 3734 VkSampler sampler = getSampler( 3735 (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags) 3736 ? bind.m_samplerFlags 3737 : (uint32_t)texture.m_flags 3738 ) & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK) 3739 , (uint32_t)texture.m_numMips); 3740 3741 if (VK_IMAGE_LAYOUT_GENERAL != texture.m_currentImageLayout 3742 && VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL != texture.m_currentImageLayout) 3743 { 3744 texture.setImageMemoryBarrier(m_commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 3745 } 3746 3747 imageInfo[imageCount].imageLayout = texture.m_currentImageLayout; 3748 imageInfo[imageCount].imageView = VK_NULL_HANDLE != texture.m_textureImageDepthView 3749 ? texture.m_textureImageDepthView 3750 : texture.m_textureImageView 3751 ; 3752 imageInfo[imageCount].sampler = sampler; 3753 3754 wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 3755 wds[wdsCount].pNext = NULL; 3756 wds[wdsCount].dstSet = descriptorSet; 3757 wds[wdsCount].dstBinding = bindInfo->binding; 3758 wds[wdsCount].dstArrayElement = 0; 3759 wds[wdsCount].descriptorCount = 1; 3760 wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 3761 wds[wdsCount].pImageInfo = &imageInfo[imageCount]; 3762 wds[wdsCount].pBufferInfo = NULL; 3763 wds[wdsCount].pTexelBufferView = NULL; 3764 ++wdsCount; 3765 3766 wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 3767 wds[wdsCount].pNext = NULL; 3768 wds[wdsCount].dstSet = descriptorSet; 3769 wds[wdsCount].dstBinding = bindInfo->samplerBinding; 3770 wds[wdsCount].dstArrayElement = 0; 3771 wds[wdsCount].descriptorCount = 1; 3772 wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 3773 wds[wdsCount].pImageInfo = &imageInfo[imageCount]; 3774 wds[wdsCount].pBufferInfo = NULL; 3775 wds[wdsCount].pTexelBufferView = NULL; 3776 ++wdsCount; 3777 3778 ++imageCount; 3779 } 3780 } 3781 } 3782 3783 const uint32_t align = uint32_t(m_deviceProperties.limits.minUniformBufferOffsetAlignment); 3784 const uint32_t vsize = bx::strideAlign(program.m_vsh->m_size, align); 3785 const uint32_t fsize = bx::strideAlign((NULL != program.m_fsh ? program.m_fsh->m_size : 0), align); 3786 const uint32_t total = vsize + fsize; 3787 3788 if (0 < total) 3789 { 3790 uint32_t vsUniformBinding = program.m_vsh->m_uniformBinding; 3791 uint32_t fsUniformBinding = program.m_fsh ? program.m_fsh->m_uniformBinding : 0; 3792 3793 if (vsize > 0) 3794 { 3795 bufferInfo[bufferCount].buffer = scratchBuffer.m_buffer; 3796 bufferInfo[bufferCount].offset = 0; 3797 bufferInfo[bufferCount].range = vsize; 3798 3799 wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 3800 wds[wdsCount].pNext = NULL; 3801 wds[wdsCount].dstSet = descriptorSet; 3802 wds[wdsCount].dstBinding = vsUniformBinding; 3803 wds[wdsCount].dstArrayElement = 0; 3804 wds[wdsCount].descriptorCount = 1; 3805 wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 3806 wds[wdsCount].pImageInfo = NULL; 3807 wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount]; 3808 wds[wdsCount].pTexelBufferView = NULL; 3809 ++wdsCount; 3810 ++bufferCount; 3811 } 3812 3813 if (fsize > 0) 3814 { 3815 bufferInfo[bufferCount].buffer = scratchBuffer.m_buffer; 3816 bufferInfo[bufferCount].offset = 0; 3817 bufferInfo[bufferCount].range = fsize; 3818 3819 wds[wdsCount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 3820 wds[wdsCount].pNext = NULL; 3821 wds[wdsCount].dstSet = descriptorSet; 3822 wds[wdsCount].dstBinding = fsUniformBinding; 3823 wds[wdsCount].dstArrayElement = 0; 3824 wds[wdsCount].descriptorCount = 1; 3825 wds[wdsCount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 3826 wds[wdsCount].pImageInfo = NULL; 3827 wds[wdsCount].pBufferInfo = &bufferInfo[bufferCount]; 3828 wds[wdsCount].pTexelBufferView = NULL; 3829 ++wdsCount; 3830 ++bufferCount; 3831 } 3832 } 3833 3834 vkUpdateDescriptorSets(m_device, wdsCount, wds, 0, NULL); 3835 } 3836 commitbgfx::vk::RendererContextVK3837 void commit(UniformBuffer& _uniformBuffer) 3838 { 3839 _uniformBuffer.reset(); 3840 3841 for (;;) 3842 { 3843 uint32_t opcode = _uniformBuffer.read(); 3844 3845 if (UniformType::End == opcode) 3846 { 3847 break; 3848 } 3849 3850 UniformType::Enum type; 3851 uint16_t loc; 3852 uint16_t num; 3853 uint16_t copy; 3854 UniformBuffer::decodeOpcode(opcode, type, loc, num, copy); 3855 3856 const char* data; 3857 if (copy) 3858 { 3859 data = _uniformBuffer.read(g_uniformTypeSize[type]*num); 3860 } 3861 else 3862 { 3863 UniformHandle handle; 3864 bx::memCopy(&handle, _uniformBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) ); 3865 data = (const char*)m_uniforms[handle.idx]; 3866 } 3867 3868 #define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \ 3869 case UniformType::_uniform: \ 3870 case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \ 3871 { \ 3872 setShaderUniform(uint8_t(type), loc, data, num); \ 3873 } \ 3874 break; 3875 3876 switch ( (uint32_t)type) 3877 { 3878 case UniformType::Mat3: 3879 case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT: 3880 { 3881 float* value = (float*)data; 3882 for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9) 3883 { 3884 Matrix4 mtx; 3885 mtx.un.val[ 0] = value[0]; 3886 mtx.un.val[ 1] = value[1]; 3887 mtx.un.val[ 2] = value[2]; 3888 mtx.un.val[ 3] = 0.0f; 3889 mtx.un.val[ 4] = value[3]; 3890 mtx.un.val[ 5] = value[4]; 3891 mtx.un.val[ 6] = value[5]; 3892 mtx.un.val[ 7] = 0.0f; 3893 mtx.un.val[ 8] = value[6]; 3894 mtx.un.val[ 9] = value[7]; 3895 mtx.un.val[10] = value[8]; 3896 mtx.un.val[11] = 0.0f; 3897 setShaderUniform(uint8_t(type), loc, &mtx.un.val[0], 3); 3898 } 3899 } 3900 break; 3901 3902 case UniformType::Sampler: 3903 case UniformType::Sampler|BGFX_UNIFORM_FRAGMENTBIT: 3904 // do nothing, but VkDescriptorSetImageInfo would be set before drawing 3905 break; 3906 // CASE_IMPLEMENT_UNIFORM(Sampler, I, int); 3907 CASE_IMPLEMENT_UNIFORM(Vec4, F, float); 3908 CASE_IMPLEMENT_UNIFORM(Mat4, F, float); 3909 3910 case UniformType::End: 3911 break; 3912 3913 default: 3914 BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy); 3915 break; 3916 } 3917 #undef CASE_IMPLEMENT_UNIFORM 3918 } 3919 } 3920 clearQuadbgfx::vk::RendererContextVK3921 void clearQuad(const Rect& _rect, const Clear& _clear, const float _palette[][4]) 3922 { 3923 VkClearRect rect[1]; 3924 rect[0].rect.offset.x = _rect.m_x; 3925 rect[0].rect.offset.y = _rect.m_y; 3926 rect[0].rect.extent.width = _rect.m_width; 3927 rect[0].rect.extent.height = _rect.m_height; 3928 rect[0].baseArrayLayer = 0; 3929 rect[0].layerCount = 1; 3930 3931 uint32_t numMrt = 1; 3932 FrameBufferHandle fbh = m_fbh; 3933 if (isValid(fbh) ) 3934 { 3935 const FrameBufferVK& fb = m_frameBuffers[fbh.idx]; 3936 numMrt = bx::max((uint8_t)1, fb.m_num); 3937 } 3938 3939 VkClearAttachment attachments[BGFX_CONFIG_MAX_FRAME_BUFFERS]; 3940 uint32_t mrt = 0; 3941 3942 if (true //NULL != m_currentColor 3943 && BGFX_CLEAR_COLOR & _clear.m_flags) 3944 { 3945 if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags) 3946 { 3947 for (uint32_t ii = 0; ii < numMrt; ++ii) 3948 { 3949 attachments[mrt].colorAttachment = mrt; 3950 attachments[mrt].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3951 uint8_t index = bx::min<uint8_t>(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]); 3952 bx::memCopy(&attachments[mrt].clearValue.color.float32, _palette[index], 16); 3953 ++mrt; 3954 } 3955 } 3956 else 3957 { 3958 float frgba[4] = 3959 { 3960 _clear.m_index[0] * 1.0f / 255.0f, 3961 _clear.m_index[1] * 1.0f / 255.0f, 3962 _clear.m_index[2] * 1.0f / 255.0f, 3963 _clear.m_index[3] * 1.0f / 255.0f, 3964 }; 3965 3966 for (uint32_t ii = 0; ii < numMrt; ++ii) 3967 { 3968 attachments[mrt].colorAttachment = mrt; 3969 attachments[mrt].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 3970 bx::memCopy(&attachments[mrt].clearValue.color.float32, frgba, 16); 3971 ++mrt; 3972 } 3973 } 3974 } 3975 3976 if (true //NULL != m_currentDepthStencil 3977 && (BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL) & _clear.m_flags) 3978 { 3979 attachments[mrt].colorAttachment = mrt; 3980 attachments[mrt].aspectMask = 0; 3981 attachments[mrt].aspectMask |= (_clear.m_flags & BGFX_CLEAR_DEPTH ) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0; 3982 attachments[mrt].aspectMask |= (_clear.m_flags & BGFX_CLEAR_STENCIL) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0; 3983 3984 attachments[mrt].clearValue.depthStencil.stencil = _clear.m_stencil; 3985 attachments[mrt].clearValue.depthStencil.depth = _clear.m_depth; 3986 ++mrt; 3987 } 3988 3989 if (mrt > 0) 3990 { 3991 vkCmdClearAttachments(m_commandBuffer 3992 , mrt 3993 , attachments 3994 , BX_COUNTOF(rect) 3995 , rect 3996 ); 3997 } 3998 } 3999 kickbgfx::vk::RendererContextVK4000 uint64_t kick(VkSemaphore _wait = VK_NULL_HANDLE, VkSemaphore _signal = VK_NULL_HANDLE) 4001 { 4002 VkPipelineStageFlags stageFlags = 0 4003 | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT 4004 ; 4005 4006 VkSubmitInfo si; 4007 si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4008 si.pNext = NULL; 4009 si.waitSemaphoreCount = VK_NULL_HANDLE != _wait; 4010 si.pWaitSemaphores = &_wait; 4011 si.pWaitDstStageMask = &stageFlags; 4012 si.commandBufferCount = 1; 4013 si.pCommandBuffers = &m_commandBuffers[m_backBufferColorIdx]; 4014 si.signalSemaphoreCount = VK_NULL_HANDLE != _signal; 4015 si.pSignalSemaphores = &_signal; 4016 4017 // VK_CHECK(vkResetFences(m_device, 1, &m_fence) ); 4018 VK_CHECK(vkQueueSubmit(m_queueGraphics, 1, &si, VK_NULL_HANDLE) ); 4019 return 0; 4020 } 4021 finishbgfx::vk::RendererContextVK4022 void finish() 4023 { 4024 finishAll(); 4025 } 4026 finishAllbgfx::vk::RendererContextVK4027 void finishAll() 4028 { 4029 VK_CHECK(vkQueueWaitIdle(m_queueGraphics) ); 4030 // VK_CHECK(vkWaitForFences(m_device, 1, &m_fence, true, INT64_MAX) ); 4031 } 4032 selectMemoryTypebgfx::vk::RendererContextVK4033 uint32_t selectMemoryType(uint32_t _memoryTypeBits, uint32_t _propertyFlags) const 4034 { 4035 for (uint32_t ii = 0, num = m_memoryProperties.memoryTypeCount; ii < num; ++ii) 4036 { 4037 const VkMemoryType& memType = m_memoryProperties.memoryTypes[ii]; 4038 if ( (0 != ( (1<<ii) & _memoryTypeBits) ) 4039 && ( (memType.propertyFlags & _propertyFlags) == _propertyFlags) ) 4040 { 4041 return ii; 4042 } 4043 } 4044 4045 BX_TRACE("Failed to find memory that supports flags 0x%08x.", _propertyFlags); 4046 return 0; 4047 } 4048 beginNewCommandbgfx::vk::RendererContextVK4049 VkCommandBuffer beginNewCommand(VkCommandBufferUsageFlagBits commandBufferUsageFlag = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) 4050 { 4051 VkCommandBufferAllocateInfo cbai; 4052 cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 4053 cbai.pNext = NULL; 4054 cbai.commandPool = m_commandPool; 4055 cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 4056 cbai.commandBufferCount = 1; 4057 4058 VkCommandBuffer commandBuffer; 4059 VK_CHECK(vkAllocateCommandBuffers(m_device, &cbai, &commandBuffer)); 4060 4061 VkCommandBufferBeginInfo cbbi; 4062 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 4063 cbbi.pNext = NULL; 4064 cbbi.flags = commandBufferUsageFlag; 4065 cbbi.pInheritanceInfo = NULL; 4066 VK_CHECK(vkBeginCommandBuffer(commandBuffer, &cbbi)); 4067 4068 return commandBuffer; 4069 } 4070 submitCommandAndWaitbgfx::vk::RendererContextVK4071 void submitCommandAndWait(VkCommandBuffer commandBuffer) 4072 { 4073 vkEndCommandBuffer(commandBuffer); 4074 4075 VkSubmitInfo submitInfo; 4076 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 4077 submitInfo.pNext = NULL; 4078 submitInfo.commandBufferCount = 1; 4079 submitInfo.pCommandBuffers = &commandBuffer; 4080 submitInfo.waitSemaphoreCount = 0; 4081 submitInfo.pWaitSemaphores = NULL; 4082 submitInfo.signalSemaphoreCount = 0; 4083 submitInfo.pSignalSemaphores = NULL; 4084 submitInfo.pWaitDstStageMask = NULL; 4085 4086 VK_CHECK(vkQueueSubmit(m_queueGraphics, 1, &submitInfo, VK_NULL_HANDLE)); 4087 VK_CHECK(vkQueueWaitIdle(m_queueGraphics)); 4088 4089 vkFreeCommandBuffers(m_device, m_commandPool, 1, &commandBuffer); 4090 } 4091 4092 #define NUM_SWAPCHAIN_IMAGE 4 4093 VkAllocationCallbacks* m_allocatorCb; 4094 VkDebugReportCallbackEXT m_debugReportCallback; 4095 VkInstance m_instance; 4096 VkPhysicalDevice m_physicalDevice; 4097 4098 VkPhysicalDeviceProperties m_deviceProperties; 4099 VkPhysicalDeviceMemoryProperties m_memoryProperties; 4100 VkPhysicalDeviceFeatures m_deviceFeatures; 4101 4102 VkSwapchainCreateInfoKHR m_sci; 4103 VkSurfaceKHR m_surface; 4104 VkSwapchainKHR m_swapchain; 4105 uint32_t m_numSwapchainImages; 4106 VkImageLayout m_backBufferColorImageLayout[NUM_SWAPCHAIN_IMAGE]; 4107 VkImage m_backBufferColorImage[NUM_SWAPCHAIN_IMAGE]; 4108 VkImageView m_backBufferColorImageView[NUM_SWAPCHAIN_IMAGE]; 4109 VkFramebuffer m_backBufferColor[NUM_SWAPCHAIN_IMAGE]; 4110 VkCommandBuffer m_commandBuffers[NUM_SWAPCHAIN_IMAGE]; 4111 VkCommandBuffer m_commandBuffer; 4112 bool m_needToRefreshSwapchain; 4113 4114 VkFormat m_backBufferDepthStencilFormat; 4115 VkDeviceMemory m_backBufferDepthStencilMemory; 4116 VkImage m_backBufferDepthStencilImage; 4117 VkImageView m_backBufferDepthStencilImageView; 4118 4119 ScratchBufferVK m_scratchBuffer[NUM_SWAPCHAIN_IMAGE]; 4120 VkSemaphore m_presentDone[NUM_SWAPCHAIN_IMAGE]; 4121 4122 uint32_t m_qfiGraphics; 4123 uint32_t m_qfiCompute; 4124 4125 VkDevice m_device; 4126 VkQueue m_queueGraphics; 4127 VkQueue m_queueCompute; 4128 VkFence m_fence; 4129 VkRenderPass m_renderPass; 4130 VkDescriptorPool m_descriptorPool; 4131 // VkDescriptorSetLayout m_descriptorSetLayout; 4132 // VkPipelineLayout m_pipelineLayout; 4133 VkPipelineCache m_pipelineCache; 4134 VkCommandPool m_commandPool; 4135 4136 void* m_renderDocDll; 4137 void* m_vulkan1Dll; 4138 4139 IndexBufferVK m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS]; 4140 VertexBufferVK m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS]; 4141 ShaderVK m_shaders[BGFX_CONFIG_MAX_SHADERS]; 4142 ProgramVK m_program[BGFX_CONFIG_MAX_PROGRAMS]; 4143 TextureVK m_textures[BGFX_CONFIG_MAX_TEXTURES]; 4144 VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; 4145 FrameBufferVK m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; 4146 void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS]; 4147 Matrix4 m_predefinedUniforms[PredefinedUniform::Count]; 4148 UniformRegistry m_uniformReg; 4149 4150 StateCacheT<VkPipeline> m_pipelineStateCache; 4151 StateCacheT<VkDescriptorSetLayout> m_descriptorSetLayoutCache; 4152 StateCacheT<VkRenderPass> m_renderPassCache; 4153 StateCacheT<VkSampler> m_samplerCache; 4154 4155 Resolution m_resolution; 4156 uint32_t m_maxAnisotropy; 4157 bool m_depthClamp; 4158 bool m_wireframe; 4159 4160 TextVideoMem m_textVideoMem; 4161 4162 uint8_t m_fsScratch[64<<10]; 4163 uint8_t m_vsScratch[64<<10]; 4164 uint32_t m_fsChanges; 4165 uint32_t m_vsChanges; 4166 4167 uint32_t m_backBufferColorIdx; 4168 FrameBufferHandle m_fbh; 4169 }; 4170 4171 static RendererContextVK* s_renderVK; 4172 rendererCreate(const Init & _init)4173 RendererContextI* rendererCreate(const Init& _init) 4174 { 4175 s_renderVK = BX_NEW(g_allocator, RendererContextVK); 4176 if (!s_renderVK->init(_init) ) 4177 { 4178 BX_DELETE(g_allocator, s_renderVK); 4179 s_renderVK = NULL; 4180 } 4181 return s_renderVK; 4182 } 4183 rendererDestroy()4184 void rendererDestroy() 4185 { 4186 s_renderVK->shutdown(); 4187 BX_DELETE(g_allocator, s_renderVK); 4188 s_renderVK = NULL; 4189 } 4190 4191 #define VK_DESTROY_FUNC(_name) \ 4192 void vkDestroy(Vk##_name& _obj) \ 4193 { \ 4194 if (VK_NULL_HANDLE != _obj) \ 4195 { \ 4196 vkDestroy##_name(s_renderVK->m_device, _obj, s_renderVK->m_allocatorCb); \ 4197 _obj = VK_NULL_HANDLE; \ 4198 } \ 4199 } 4200 VK_DESTROY 4201 #undef VK_DESTROY_FUNC 4202 create(uint32_t _size,uint32_t _maxDescriptors)4203 void ScratchBufferVK::create(uint32_t _size, uint32_t _maxDescriptors) 4204 { 4205 m_maxDescriptors = _maxDescriptors; 4206 m_currentDs = 0; 4207 m_descriptorSet = (VkDescriptorSet*)BX_ALLOC(g_allocator, m_maxDescriptors * sizeof(VkDescriptorSet) ); 4208 bx::memSet(m_descriptorSet, 0, sizeof(VkDescriptorSet) * m_maxDescriptors); 4209 4210 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 4211 VkDevice device = s_renderVK->m_device; 4212 4213 VkBufferCreateInfo bci; 4214 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 4215 bci.pNext = NULL; 4216 bci.flags = 0; 4217 bci.size = _size; 4218 bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 4219 bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 4220 bci.queueFamilyIndexCount = 0; 4221 bci.pQueueFamilyIndices = NULL; 4222 4223 VK_CHECK(vkCreateBuffer( 4224 device 4225 , &bci 4226 , allocatorCb 4227 , &m_buffer 4228 ) ); 4229 4230 VkMemoryRequirements mr; 4231 vkGetBufferMemoryRequirements( 4232 device 4233 , m_buffer 4234 , &mr 4235 ); 4236 4237 VkMemoryAllocateInfo ma; 4238 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4239 ma.pNext = NULL; 4240 ma.allocationSize = mr.size; 4241 ma.memoryTypeIndex = s_renderVK->selectMemoryType(mr.memoryTypeBits 4242 , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 4243 ); 4244 VK_CHECK(vkAllocateMemory(device 4245 , &ma 4246 , allocatorCb 4247 , &m_deviceMem 4248 ) ); 4249 4250 m_size = (uint32_t)mr.size; 4251 m_pos = 0; 4252 4253 VK_CHECK(vkBindBufferMemory(device, m_buffer, m_deviceMem, 0) ); 4254 4255 VK_CHECK(vkMapMemory(device, m_deviceMem, 0, ma.allocationSize, 0, (void**)&m_data) ); 4256 } 4257 destroy()4258 void ScratchBufferVK::destroy() 4259 { 4260 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 4261 VkDevice device = s_renderVK->m_device; 4262 4263 reset(); 4264 BX_FREE(g_allocator, m_descriptorSet); 4265 4266 vkUnmapMemory(device, m_deviceMem); 4267 vkDestroy(m_buffer); 4268 vkFreeMemory(device 4269 , m_deviceMem 4270 , allocatorCb 4271 ); 4272 } 4273 reset()4274 void ScratchBufferVK::reset() 4275 { 4276 if (m_currentDs > 0) 4277 { 4278 vkFreeDescriptorSets( 4279 s_renderVK->m_device 4280 , s_renderVK->m_descriptorPool 4281 , m_currentDs 4282 , m_descriptorSet 4283 ); 4284 } 4285 4286 bx::memSet(m_descriptorSet, 0, sizeof(VkDescriptorSet) * m_maxDescriptors); 4287 m_pos = 0; 4288 m_currentDs = 0; 4289 } 4290 create(VkFormat _format,const VkExtent3D & _extent)4291 VkResult ImageVK::create(VkFormat _format, const VkExtent3D& _extent) 4292 { 4293 VkResult result; 4294 4295 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 4296 VkDevice device = s_renderVK->m_device; 4297 4298 VkImageCreateInfo ici; 4299 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 4300 ici.pNext = NULL; 4301 ici.flags = 0; 4302 ici.imageType = VK_IMAGE_TYPE_2D; 4303 ici.format = _format; 4304 ici.extent = _extent; 4305 ici.mipLevels = 1; 4306 ici.arrayLayers = 1; 4307 ici.samples = VK_SAMPLE_COUNT_1_BIT; 4308 ici.tiling = VK_IMAGE_TILING_OPTIMAL; 4309 ici.usage = 0 4310 | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT 4311 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT 4312 ; 4313 ici.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 4314 ici.queueFamilyIndexCount = 0; 4315 ici.pQueueFamilyIndices = 0; 4316 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 4317 result = vkCreateImage(device, &ici, allocatorCb, &m_image); 4318 4319 if (VK_SUCCESS != result) 4320 { 4321 BX_TRACE("vkCreateImage failed %d: %s.", result, getName(result) ); 4322 return result; 4323 } 4324 4325 VkMemoryRequirements mr; 4326 vkGetImageMemoryRequirements(device, m_image, &mr); 4327 4328 VkMemoryAllocateInfo ma; 4329 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4330 ma.pNext = NULL; 4331 ma.allocationSize = mr.size; 4332 ma.memoryTypeIndex = s_renderVK->selectMemoryType( 4333 mr.memoryTypeBits 4334 , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 4335 ); 4336 result = vkAllocateMemory(device, &ma, allocatorCb, &m_memory); 4337 4338 if (VK_SUCCESS != result) 4339 { 4340 BX_TRACE("vkAllocateMemory failed %d: %s.", result, getName(result) ); 4341 destroy(); 4342 return result; 4343 } 4344 4345 result = vkBindImageMemory(device, m_image, m_memory, 0); 4346 4347 if (VK_SUCCESS != result) 4348 { 4349 BX_TRACE("vkBindImageMemory failed %d: %s.", result, getName(result) ); 4350 destroy(); 4351 return result; 4352 } 4353 4354 VkImageViewCreateInfo ivci; 4355 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 4356 ivci.pNext = NULL; 4357 ivci.flags = 0; 4358 ivci.image = m_image; 4359 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; 4360 ivci.format = _format; 4361 ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 4362 ivci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 4363 ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 4364 ivci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 4365 ivci.subresourceRange.aspectMask = 0 4366 | VK_IMAGE_ASPECT_DEPTH_BIT 4367 | VK_IMAGE_ASPECT_STENCIL_BIT 4368 ; 4369 ivci.subresourceRange.baseMipLevel = 0; 4370 ivci.subresourceRange.levelCount = 1; 4371 ivci.subresourceRange.baseArrayLayer = 0; 4372 ivci.subresourceRange.layerCount = 1; 4373 result = vkCreateImageView(device, &ivci, allocatorCb, &m_imageView); 4374 4375 if (VK_SUCCESS != result) 4376 { 4377 BX_TRACE("vkCreateImageView failed %d: %s.", result, getName(result) ); 4378 destroy(); 4379 return result; 4380 } 4381 4382 return VK_SUCCESS; 4383 } 4384 destroy()4385 void ImageVK::destroy() 4386 { 4387 vkDestroy(m_imageView); 4388 vkDestroy(m_image); 4389 if (VK_NULL_HANDLE != m_memory) 4390 { 4391 vkFreeMemory(s_renderVK->m_device, m_memory, s_renderVK->m_allocatorCb); 4392 m_memory = VK_NULL_HANDLE; 4393 } 4394 } 4395 create(uint32_t _size,void * _data,uint16_t _flags,bool _vertex,uint32_t _stride)4396 void BufferVK::create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride) 4397 { 4398 BX_UNUSED(_stride); 4399 4400 m_size = _size; 4401 m_flags = _flags; 4402 m_dynamic = NULL == _data; 4403 4404 bool storage = m_flags & BGFX_BUFFER_COMPUTE_READ_WRITE; 4405 bool indirect = m_flags & BGFX_BUFFER_DRAW_INDIRECT; 4406 VkBufferCreateInfo bci; 4407 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 4408 bci.pNext = NULL; 4409 bci.flags = 0; 4410 bci.size = _size; 4411 bci.usage = 0 4412 // | (m_dynamic ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0) 4413 | (_vertex ? VK_BUFFER_USAGE_VERTEX_BUFFER_BIT : VK_BUFFER_USAGE_INDEX_BUFFER_BIT) 4414 | (storage || indirect ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0) 4415 | (indirect ? VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT : 0) 4416 | VK_BUFFER_USAGE_TRANSFER_DST_BIT 4417 ; 4418 bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 4419 bci.queueFamilyIndexCount = 0; 4420 bci.pQueueFamilyIndices = NULL; 4421 4422 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 4423 VkDevice device = s_renderVK->m_device; 4424 VK_CHECK(vkCreateBuffer(device 4425 , &bci 4426 , allocatorCb 4427 , &m_buffer 4428 ) ); 4429 4430 VkMemoryRequirements mr; 4431 vkGetBufferMemoryRequirements(device, m_buffer, &mr); 4432 4433 VkMemoryAllocateInfo ma; 4434 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4435 ma.pNext = NULL; 4436 ma.allocationSize = mr.size; 4437 ma.memoryTypeIndex = s_renderVK->selectMemoryType( 4438 mr.memoryTypeBits 4439 , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 4440 ); 4441 VK_CHECK(vkAllocateMemory(device, &ma, allocatorCb, &m_deviceMem) ); 4442 4443 VK_CHECK(vkBindBufferMemory(device, m_buffer, m_deviceMem, 0)); 4444 4445 if (!m_dynamic) 4446 { 4447 // void* dst; 4448 // VK_CHECK(vkMapMemory(device, m_deviceMem, 0, ma.allocationSize, 0, &dst) ); 4449 // bx::memCopy(dst, _data, _size); 4450 // vkUnmapMemory(device, m_deviceMem); 4451 4452 // staging buffer 4453 VkBuffer stagingBuffer; 4454 VkDeviceMemory stagingMem; 4455 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 4456 bci.pNext = NULL; 4457 bci.flags = 0; 4458 bci.size = _size; 4459 bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 4460 bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 4461 bci.queueFamilyIndexCount = 0; 4462 bci.pQueueFamilyIndices = NULL; 4463 4464 VK_CHECK(vkCreateBuffer(device 4465 , &bci 4466 , allocatorCb 4467 , &stagingBuffer 4468 )); 4469 4470 vkGetBufferMemoryRequirements(device, stagingBuffer, &mr); 4471 4472 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4473 ma.pNext = NULL; 4474 ma.allocationSize = mr.size; 4475 ma.memoryTypeIndex = s_renderVK->selectMemoryType(mr.memoryTypeBits 4476 , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT 4477 ); 4478 VK_CHECK(vkAllocateMemory(device 4479 , &ma 4480 , allocatorCb 4481 , &stagingMem 4482 )); 4483 4484 VK_CHECK(vkBindBufferMemory(device, stagingBuffer, stagingMem, 0)); 4485 4486 void* dst; 4487 VK_CHECK(vkMapMemory(device, stagingMem, 0, ma.allocationSize, 0, &dst)); 4488 bx::memCopy(dst, _data, _size); 4489 vkUnmapMemory(device, stagingMem); 4490 4491 VkCommandBuffer commandBuffer = s_renderVK->beginNewCommand(); 4492 // copy buffer to buffer 4493 { 4494 VkBufferCopy region; 4495 region.srcOffset = 0; 4496 region.dstOffset = 0; 4497 region.size = _size; 4498 4499 vkCmdCopyBuffer(commandBuffer, stagingBuffer, m_buffer, 1, ®ion); 4500 } 4501 s_renderVK->submitCommandAndWait(commandBuffer); 4502 4503 vkFreeMemory(device, stagingMem, allocatorCb); 4504 vkDestroy(stagingBuffer); 4505 } 4506 } 4507 update(VkCommandBuffer _commandBuffer,uint32_t _offset,uint32_t _size,void * _data,bool _discard)4508 void BufferVK::update(VkCommandBuffer _commandBuffer, uint32_t _offset, uint32_t _size, void* _data, bool _discard) 4509 { 4510 BX_UNUSED(_commandBuffer, _discard); 4511 // void* dst; 4512 // VkDevice device = s_renderVK->m_device; 4513 // VK_CHECK(vkMapMemory(device, m_deviceMem, _offset, _size, 0, &dst) ); 4514 // bx::memCopy(dst, _data, _size); 4515 // vkUnmapMemory(device, m_deviceMem); 4516 4517 // staging buffer 4518 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 4519 VkDevice device = s_renderVK->m_device; 4520 VkBuffer stagingBuffer; 4521 VkDeviceMemory stagingMem; 4522 VkBufferCreateInfo bci; 4523 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 4524 bci.pNext = NULL; 4525 bci.flags = 0; 4526 bci.size = _size; 4527 bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 4528 bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 4529 bci.queueFamilyIndexCount = 0; 4530 bci.pQueueFamilyIndices = NULL; 4531 4532 VK_CHECK(vkCreateBuffer(device 4533 , &bci 4534 , allocatorCb 4535 , &stagingBuffer 4536 )); 4537 4538 VkMemoryRequirements mr; 4539 vkGetBufferMemoryRequirements(device 4540 , stagingBuffer 4541 , &mr 4542 ); 4543 4544 VkMemoryAllocateInfo ma; 4545 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4546 ma.pNext = NULL; 4547 ma.allocationSize = mr.size; 4548 ma.memoryTypeIndex = s_renderVK->selectMemoryType(mr.memoryTypeBits 4549 , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT 4550 ); 4551 VK_CHECK(vkAllocateMemory(device 4552 , &ma 4553 , allocatorCb 4554 , &stagingMem 4555 )); 4556 4557 VK_CHECK(vkBindBufferMemory(device, stagingBuffer, stagingMem, 0)); 4558 4559 void* dst; 4560 VK_CHECK(vkMapMemory(device, stagingMem, 0, ma.allocationSize, 0, &dst)); 4561 bx::memCopy(dst, _data, _size); 4562 vkUnmapMemory(device, stagingMem); 4563 4564 VkCommandBuffer commandBuffer = s_renderVK->beginNewCommand(); 4565 4566 // copy buffer to buffer 4567 { 4568 VkBufferCopy region; 4569 region.srcOffset = 0; 4570 region.dstOffset = _offset; 4571 region.size = _size; 4572 4573 vkCmdCopyBuffer(commandBuffer, stagingBuffer, m_buffer, 1, ®ion); 4574 } 4575 4576 s_renderVK->submitCommandAndWait(commandBuffer); 4577 4578 vkFreeMemory(device, stagingMem, allocatorCb); 4579 vkDestroy(stagingBuffer); 4580 } 4581 destroy()4582 void BufferVK::destroy() 4583 { 4584 if (VK_NULL_HANDLE != m_buffer) 4585 { 4586 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 4587 VkDevice device = s_renderVK->m_device; 4588 4589 vkDestroy(m_buffer); 4590 vkFreeMemory(device 4591 , m_deviceMem 4592 , allocatorCb 4593 ); 4594 m_dynamic = false; 4595 } 4596 } 4597 create(uint32_t _size,void * _data,VertexLayoutHandle _layoutHandle,uint16_t _flags)4598 void VertexBufferVK::create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags) 4599 { 4600 BufferVK::create(_size, _data, _flags, true); 4601 m_layoutHandle = _layoutHandle; 4602 } 4603 create(const Memory * _mem)4604 void ShaderVK::create(const Memory* _mem) 4605 { 4606 bx::MemoryReader reader(_mem->data, _mem->size); 4607 4608 uint32_t magic; 4609 bx::read(&reader, magic); 4610 4611 VkShaderStageFlagBits shaderStage; 4612 BX_UNUSED(shaderStage); 4613 4614 if (isShaderType(magic, 'C') ) 4615 { 4616 shaderStage = VK_SHADER_STAGE_COMPUTE_BIT; 4617 } 4618 else if (isShaderType(magic, 'F') ) 4619 { 4620 shaderStage = VK_SHADER_STAGE_FRAGMENT_BIT; 4621 } 4622 else if (isShaderType(magic, 'V') ) 4623 { 4624 shaderStage = VK_SHADER_STAGE_VERTEX_BIT; 4625 } 4626 4627 const bool fragment = isShaderType(magic, 'F'); 4628 4629 uint32_t hashIn; 4630 bx::read(&reader, hashIn); 4631 4632 uint32_t hashOut; 4633 4634 if (isShaderVerLess(magic, 6) ) 4635 { 4636 hashOut = hashIn; 4637 } 4638 else 4639 { 4640 bx::read(&reader, hashOut); 4641 } 4642 4643 uint16_t count; 4644 bx::read(&reader, count); 4645 4646 m_numPredefined = 0; 4647 m_numUniforms = count; 4648 4649 BX_TRACE("%s Shader consts %d" 4650 , getShaderTypeName(magic) 4651 , count 4652 ); 4653 4654 uint8_t fragmentBit = fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0; 4655 4656 for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++ii) 4657 { 4658 m_bindInfo[ii].uniformHandle = BGFX_INVALID_HANDLE; 4659 m_bindInfo[ii].type = BindType::Count; 4660 m_bindInfo[ii].binding = 0; 4661 m_bindInfo[ii].samplerBinding = 0; 4662 } 4663 4664 if (0 < count) 4665 { 4666 for (uint32_t ii = 0; ii < count; ++ii) 4667 { 4668 uint8_t nameSize = 0; 4669 bx::read(&reader, nameSize); 4670 4671 char name[256]; 4672 bx::read(&reader, &name, nameSize); 4673 name[nameSize] = '\0'; 4674 4675 uint8_t type = 0; 4676 bx::read(&reader, type); 4677 4678 uint8_t num; 4679 bx::read(&reader, num); 4680 4681 uint16_t regIndex; 4682 bx::read(&reader, regIndex); 4683 4684 uint16_t regCount; 4685 bx::read(&reader, regCount); 4686 4687 const char* kind = "invalid"; 4688 4689 PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name); 4690 if (PredefinedUniform::Count != predefined) 4691 { 4692 kind = "predefined"; 4693 m_predefined[m_numPredefined].m_loc = regIndex; 4694 m_predefined[m_numPredefined].m_count = regCount; 4695 m_predefined[m_numPredefined].m_type = uint8_t(predefined|fragmentBit); 4696 m_numPredefined++; 4697 } 4698 else if (UniformType::End == (~BGFX_UNIFORM_MASK & type)) 4699 { 4700 m_bindInfo[num].uniformHandle = { 0 }; 4701 m_bindInfo[num].type = BindType::Storage; 4702 m_bindInfo[num].binding = regCount; // regCount is used for buffer binding index 4703 m_bindInfo[num].samplerBinding = regIndex; // regIndex is used for descriptor type 4704 4705 kind = "storage"; 4706 } 4707 else if (UniformType::Sampler == (~BGFX_UNIFORM_MASK & type) ) 4708 { 4709 const UniformRegInfo* info = s_renderVK->m_uniformReg.find(name); 4710 BX_CHECK(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name); 4711 4712 m_bindInfo[num].uniformHandle = info->m_handle; 4713 m_bindInfo[num].type = BindType::Sampler; 4714 m_bindInfo[num].binding = regIndex; // regIndex is used for image binding index 4715 m_bindInfo[num].samplerBinding = regCount; // regCount is used for sampler binding index 4716 4717 kind = "sampler"; 4718 } 4719 else 4720 { 4721 const UniformRegInfo* info = s_renderVK->m_uniformReg.find(name); 4722 BX_CHECK(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name); 4723 4724 if (NULL != info) 4725 { 4726 if (NULL == m_constantBuffer) 4727 { 4728 m_constantBuffer = UniformBuffer::create(1024); 4729 } 4730 4731 kind = "user"; 4732 m_constantBuffer->writeUniformHandle( (UniformType::Enum)(type|fragmentBit), regIndex, info->m_handle, regCount); 4733 } 4734 } 4735 4736 4737 BX_TRACE("\t%s: %s (%s), num %2d, r.index %3d, r.count %2d" 4738 , kind 4739 , name 4740 , getUniformTypeName(UniformType::Enum(type&~BGFX_UNIFORM_MASK) ) 4741 , num 4742 , regIndex 4743 , regCount 4744 ); 4745 BX_UNUSED(kind); 4746 } 4747 4748 if (NULL != m_constantBuffer) 4749 { 4750 m_constantBuffer->finish(); 4751 } 4752 } 4753 4754 uint32_t shaderSize; 4755 bx::read(&reader, shaderSize); 4756 4757 const void* code = reader.getDataPtr(); 4758 bx::skip(&reader, shaderSize+1); 4759 4760 m_code = alloc(shaderSize); 4761 bx::memCopy(m_code->data, code, shaderSize); 4762 4763 VkShaderModuleCreateInfo smci; 4764 smci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 4765 smci.pNext = NULL; 4766 smci.flags = 0; 4767 smci.codeSize = m_code->size; 4768 smci.pCode = (const uint32_t*)m_code->data; 4769 4770 // disassemble(bx::getDebugOut(), m_code->data, m_code->size); 4771 4772 VK_CHECK(vkCreateShaderModule( 4773 s_renderVK->m_device 4774 , &smci 4775 , s_renderVK->m_allocatorCb 4776 , &m_module 4777 ) ); 4778 4779 bx::memSet(m_attrMask, 0, sizeof(m_attrMask) ); 4780 bx::memSet(m_attrRemap, 0, sizeof(m_attrRemap) ); 4781 4782 bx::read(&reader, m_numAttrs); 4783 4784 for (uint8_t ii = 0; ii < m_numAttrs; ++ii) 4785 { 4786 uint16_t id; 4787 bx::read(&reader, id); 4788 4789 Attrib::Enum attr = idToAttrib(id); 4790 4791 if (Attrib::Count != attr) 4792 { 4793 m_attrMask[attr] = UINT16_MAX; 4794 m_attrRemap[attr] = ii; 4795 } 4796 } 4797 4798 bx::HashMurmur2A murmur; 4799 murmur.begin(); 4800 murmur.add(hashIn); 4801 murmur.add(hashOut); 4802 murmur.add(m_code->data, m_code->size); 4803 murmur.add(m_numAttrs); 4804 murmur.add(m_attrMask, m_numAttrs); 4805 murmur.add(m_attrRemap, m_numAttrs); 4806 m_hash = murmur.end(); 4807 4808 bx::read(&reader, m_size); 4809 4810 // fill binding description with uniform informations 4811 { 4812 uint16_t bidx = 0; 4813 if (m_size > 0) 4814 { 4815 m_uniformBinding = fragment ? 48 : 0; 4816 m_bindings[bidx].stageFlags = VK_SHADER_STAGE_ALL; 4817 m_bindings[bidx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 4818 m_bindings[bidx].binding = m_uniformBinding; 4819 m_bindings[bidx].pImmutableSamplers = NULL; 4820 m_bindings[bidx].descriptorCount = 1; 4821 bidx++; 4822 } 4823 4824 for (uint32_t ii = 0; ii < BX_COUNTOF(m_bindInfo); ++ii) 4825 { 4826 switch (m_bindInfo[ii].type) 4827 { 4828 case BindType::Storage: 4829 m_bindings[bidx].stageFlags = VK_SHADER_STAGE_ALL; 4830 m_bindings[bidx].descriptorType = (VkDescriptorType)m_bindInfo[ii].samplerBinding; 4831 m_bindings[bidx].binding = m_bindInfo[ii].binding; 4832 m_bindings[bidx].pImmutableSamplers = NULL; 4833 m_bindings[bidx].descriptorCount = 1; 4834 bidx++; 4835 break; 4836 4837 case BindType::Sampler: 4838 m_bindings[bidx].stageFlags = VK_SHADER_STAGE_ALL; 4839 m_bindings[bidx].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 4840 m_bindings[bidx].binding = m_bindInfo[ii].binding; 4841 m_bindings[bidx].pImmutableSamplers = NULL; 4842 m_bindings[bidx].descriptorCount = 1; 4843 bidx++; 4844 4845 m_bindings[bidx].stageFlags = VK_SHADER_STAGE_ALL; 4846 m_bindings[bidx].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; 4847 m_bindings[bidx].binding = m_bindInfo[ii].samplerBinding; 4848 m_bindings[bidx].pImmutableSamplers = NULL; 4849 m_bindings[bidx].descriptorCount = 1; 4850 bidx++; 4851 break; 4852 4853 default: 4854 break; 4855 } 4856 } 4857 4858 m_numBindings = bidx; 4859 } 4860 } 4861 destroy()4862 void ShaderVK::destroy() 4863 { 4864 if (NULL != m_constantBuffer) 4865 { 4866 UniformBuffer::destroy(m_constantBuffer); 4867 m_constantBuffer = NULL; 4868 } 4869 4870 m_numPredefined = 0; 4871 4872 if (NULL != m_code) 4873 { 4874 release(m_code); 4875 m_code = NULL; 4876 m_hash = 0; 4877 } 4878 4879 if (VK_NULL_HANDLE != m_module) 4880 { 4881 vkDestroy(m_module); 4882 } 4883 } 4884 create(const ShaderVK * _vsh,const ShaderVK * _fsh)4885 void ProgramVK::create(const ShaderVK* _vsh, const ShaderVK* _fsh) 4886 { 4887 BX_CHECK(NULL != _vsh->m_code, "Vertex shader doesn't exist."); 4888 m_vsh = _vsh; 4889 bx::memCopy( 4890 &m_predefined[0] 4891 , _vsh->m_predefined 4892 , _vsh->m_numPredefined * sizeof(PredefinedUniform) 4893 ); 4894 m_numPredefined = _vsh->m_numPredefined; 4895 4896 if (NULL != _fsh) 4897 { 4898 BX_CHECK(NULL != _fsh->m_code, "Fragment shader doesn't exist."); 4899 m_fsh = _fsh; 4900 bx::memCopy( 4901 &m_predefined[m_numPredefined] 4902 , _fsh->m_predefined 4903 , _fsh->m_numPredefined * sizeof(PredefinedUniform) 4904 ); 4905 m_numPredefined += _fsh->m_numPredefined; 4906 } 4907 4908 // create exact pipeline layout 4909 VkDescriptorSetLayout dsl = VK_NULL_HANDLE; 4910 4911 uint32_t numBindings = m_vsh->m_numBindings + (m_fsh ? m_fsh->m_numBindings : 0); 4912 if (0 < numBindings) 4913 { 4914 // generate descriptor set layout hash 4915 bx::HashMurmur2A murmur; 4916 murmur.begin(); 4917 murmur.add(m_vsh->m_bindings, sizeof(VkDescriptorSetLayoutBinding) * m_vsh->m_numBindings); 4918 if (NULL != m_fsh) 4919 { 4920 murmur.add(m_fsh->m_bindings, sizeof(VkDescriptorSetLayoutBinding) * m_fsh->m_numBindings); 4921 } 4922 m_descriptorSetLayoutHash = murmur.end(); 4923 4924 dsl = s_renderVK->m_descriptorSetLayoutCache.find(m_descriptorSetLayoutHash); 4925 4926 if (VK_NULL_HANDLE == dsl) 4927 { 4928 VkDescriptorSetLayoutBinding bindings[64]; 4929 bx::memCopy( 4930 bindings 4931 , m_vsh->m_bindings 4932 , sizeof(VkDescriptorSetLayoutBinding) * m_vsh->m_numBindings 4933 ); 4934 if (NULL != m_fsh) 4935 { 4936 bx::memCopy( 4937 bindings + m_vsh->m_numBindings 4938 , m_fsh->m_bindings 4939 , sizeof(VkDescriptorSetLayoutBinding) * m_fsh->m_numBindings 4940 ); 4941 } 4942 4943 VkDescriptorSetLayoutCreateInfo dslci; 4944 dslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 4945 dslci.pNext = NULL; 4946 dslci.flags = 0; 4947 dslci.bindingCount = numBindings; 4948 dslci.pBindings = bindings; 4949 4950 VK_CHECK(vkCreateDescriptorSetLayout( 4951 s_renderVK->m_device 4952 , &dslci 4953 , s_renderVK->m_allocatorCb 4954 , &dsl 4955 )); 4956 4957 s_renderVK->m_descriptorSetLayoutCache.add(m_descriptorSetLayoutHash, dsl); 4958 } 4959 } 4960 4961 VkPipelineLayoutCreateInfo plci; 4962 plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 4963 plci.pNext = NULL; 4964 plci.flags = 0; 4965 plci.pushConstantRangeCount = 0; 4966 plci.pPushConstantRanges = NULL; 4967 plci.setLayoutCount = (dsl == VK_NULL_HANDLE ? 0 : 1); 4968 plci.pSetLayouts = &dsl; 4969 4970 VK_CHECK(vkCreatePipelineLayout( 4971 s_renderVK->m_device 4972 , &plci 4973 , s_renderVK->m_allocatorCb 4974 , &m_pipelineLayout 4975 )); 4976 } 4977 destroy()4978 void ProgramVK::destroy() 4979 { 4980 vkDestroy(m_pipelineLayout); 4981 m_numPredefined = 0; 4982 m_vsh = NULL; 4983 m_fsh = NULL; 4984 } 4985 create(const Memory * _mem,uint64_t _flags,uint8_t _skip)4986 void* TextureVK::create(const Memory* _mem, uint64_t _flags, uint8_t _skip) 4987 { 4988 bimg::ImageContainer imageContainer; 4989 4990 if (bimg::imageParse(imageContainer, _mem->data, _mem->size)) 4991 { 4992 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 4993 VkDevice device = s_renderVK->m_device; 4994 4995 const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(imageContainer.m_format); 4996 const uint8_t startLod = bx::min<uint8_t>(_skip, imageContainer.m_numMips - 1); 4997 4998 bimg::TextureInfo ti; 4999 bimg::imageGetSize( 5000 &ti 5001 , uint16_t(imageContainer.m_width >> startLod) 5002 , uint16_t(imageContainer.m_height >> startLod) 5003 , uint16_t(imageContainer.m_depth >> startLod) 5004 , imageContainer.m_cubeMap 5005 , 1 < imageContainer.m_numMips 5006 , imageContainer.m_numLayers 5007 , imageContainer.m_format 5008 ); 5009 5010 ti.numMips = bx::min<uint8_t>(imageContainer.m_numMips - startLod, ti.numMips); 5011 5012 m_flags = _flags; 5013 m_width = ti.width; 5014 m_height = ti.height; 5015 m_depth = ti.depth; 5016 m_numLayers = ti.numLayers; 5017 m_requestedFormat = uint8_t(imageContainer.m_format); 5018 m_textureFormat = uint8_t(getViableTextureFormat(imageContainer)); 5019 m_vkTextureFormat = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) 5020 ? s_textureFormat[m_textureFormat].m_fmtDsv 5021 : s_textureFormat[m_textureFormat].m_fmt 5022 ; 5023 5024 const bool convert = m_textureFormat != m_requestedFormat; 5025 const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat)); 5026 m_vkTextureAspect = bimg::isDepth((bimg::TextureFormat::Enum)m_textureFormat) 5027 ? VK_IMAGE_ASPECT_DEPTH_BIT 5028 : VK_IMAGE_ASPECT_COLOR_BIT 5029 ; 5030 5031 if (m_vkTextureFormat == VK_FORMAT_S8_UINT 5032 || m_vkTextureFormat == VK_FORMAT_D16_UNORM_S8_UINT 5033 || m_vkTextureFormat == VK_FORMAT_D24_UNORM_S8_UINT 5034 || m_vkTextureFormat == VK_FORMAT_D32_SFLOAT_S8_UINT) 5035 { 5036 m_vkTextureAspect |= VK_IMAGE_ASPECT_STENCIL_BIT; 5037 } 5038 5039 if (imageContainer.m_cubeMap) 5040 { 5041 m_type = VK_IMAGE_VIEW_TYPE_CUBE; 5042 } 5043 else if (imageContainer.m_depth > 1) 5044 { 5045 m_type = VK_IMAGE_VIEW_TYPE_3D; 5046 } 5047 else 5048 { 5049 m_type = VK_IMAGE_VIEW_TYPE_2D; 5050 } 5051 5052 m_numMips = ti.numMips; 5053 m_numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1); 5054 const uint16_t numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1); 5055 const uint32_t numSrd = numSides * ti.numMips; 5056 5057 uint32_t kk = 0; 5058 5059 const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat)); 5060 const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE); 5061 5062 const bool writeOnly = 0 != (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY); 5063 const bool computeWrite = 0 != (m_flags & BGFX_TEXTURE_COMPUTE_WRITE); 5064 const bool renderTarget = 0 != (m_flags & BGFX_TEXTURE_RT_MASK); 5065 const bool blit = 0 != (m_flags & BGFX_TEXTURE_BLIT_DST); 5066 5067 BX_UNUSED(swizzle, writeOnly, computeWrite, renderTarget, blit); 5068 5069 BX_TRACE( 5070 "Texture %3d: %s (requested: %s), %dx%d%s RT[%c], BO[%c], CW[%c]%s." 5071 , (int)(this - s_renderVK->m_textures) 5072 , getName((TextureFormat::Enum)m_textureFormat) 5073 , getName((TextureFormat::Enum)m_requestedFormat) 5074 , ti.width 5075 , ti.height 5076 , imageContainer.m_cubeMap ? "x6" : "" 5077 , renderTarget ? 'x' : ' ' 5078 , writeOnly ? 'x' : ' ' 5079 , computeWrite ? 'x' : ' ' 5080 , swizzle ? " (swizzle BGRA8 -> RGBA8)" : "" 5081 ); 5082 5083 // decode images 5084 struct ImageInfo 5085 { 5086 uint8_t* data; 5087 uint32_t width; 5088 uint32_t height; 5089 uint32_t depth; 5090 uint32_t pitch; 5091 uint32_t slice; 5092 uint32_t size; 5093 uint8_t mipLevel; 5094 uint8_t layer; 5095 }; 5096 5097 ImageInfo* imageInfos = (ImageInfo*)BX_ALLOC(g_allocator, sizeof(ImageInfo) * numSrd); 5098 bx::memSet(imageInfos, 0, sizeof(ImageInfo) * numSrd); 5099 uint32_t alignment = 1; // tightly aligned buffer 5100 for (uint8_t side = 0; side < numSides; ++side) 5101 { 5102 for (uint8_t lod = 0; lod < ti.numMips; ++lod) 5103 { 5104 bimg::ImageMip mip; 5105 if (bimg::imageGetRawData(imageContainer, side, lod + startLod, _mem->data, _mem->size, mip)) 5106 { 5107 if (convert) 5108 { 5109 const uint32_t pitch = bx::strideAlign(bx::max<uint32_t>(mip.m_width, 4) * bpp / 8, alignment); 5110 const uint32_t slice = bx::strideAlign(bx::max<uint32_t>(mip.m_height, 4) * pitch, alignment); 5111 const uint32_t size = slice * mip.m_depth; 5112 5113 uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, size); 5114 bimg::imageDecodeToBgra8( 5115 g_allocator 5116 , temp 5117 , mip.m_data 5118 , mip.m_width 5119 , mip.m_height 5120 , pitch 5121 , mip.m_format 5122 ); 5123 5124 imageInfos[kk].data = temp; 5125 imageInfos[kk].width = mip.m_width; 5126 imageInfos[kk].height = mip.m_height; 5127 imageInfos[kk].depth = mip.m_depth; 5128 imageInfos[kk].pitch = pitch; 5129 imageInfos[kk].slice = slice; 5130 imageInfos[kk].size = size; 5131 imageInfos[kk].mipLevel = lod; 5132 imageInfos[kk].layer = side; 5133 } 5134 else if (compressed) 5135 { 5136 const uint32_t pitch = bx::strideAlign((mip.m_width / blockInfo.blockWidth) * mip.m_blockSize, alignment); 5137 const uint32_t slice = bx::strideAlign((mip.m_height / blockInfo.blockHeight) * pitch, alignment); 5138 const uint32_t size = slice * mip.m_depth; 5139 5140 uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, size); 5141 bimg::imageCopy( 5142 temp 5143 , mip.m_height / blockInfo.blockHeight 5144 , (mip.m_width / blockInfo.blockWidth) * mip.m_blockSize 5145 , mip.m_depth 5146 , mip.m_data 5147 , pitch 5148 ); 5149 5150 imageInfos[kk].data = temp; 5151 imageInfos[kk].width = mip.m_width; 5152 imageInfos[kk].height = mip.m_height; 5153 imageInfos[kk].depth = mip.m_depth; 5154 imageInfos[kk].pitch = pitch; 5155 imageInfos[kk].slice = slice; 5156 imageInfos[kk].size = size; 5157 imageInfos[kk].mipLevel = lod; 5158 imageInfos[kk].layer = side; 5159 } 5160 else 5161 { 5162 const uint32_t pitch = bx::strideAlign(mip.m_width * mip.m_bpp / 8, alignment); 5163 const uint32_t slice = bx::strideAlign(mip.m_height * pitch, alignment); 5164 5165 uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, slice); 5166 bimg::imageCopy(temp 5167 , mip.m_height 5168 , mip.m_width * mip.m_bpp / 8 5169 , mip.m_depth 5170 , mip.m_data 5171 , pitch 5172 ); 5173 5174 imageInfos[kk].data = temp; 5175 imageInfos[kk].width = mip.m_width; 5176 imageInfos[kk].height = mip.m_height; 5177 imageInfos[kk].depth = mip.m_depth; 5178 imageInfos[kk].pitch = pitch; 5179 imageInfos[kk].slice = slice; 5180 imageInfos[kk].size = slice; 5181 imageInfos[kk].mipLevel = lod; 5182 imageInfos[kk].layer = side; 5183 } 5184 } 5185 ++kk; 5186 } 5187 } 5188 5189 uint32_t totalMemSize = 0; 5190 VkBufferImageCopy* bufferCopyInfo = (VkBufferImageCopy*)BX_ALLOC(g_allocator, sizeof(VkBufferImageCopy) * numSrd); 5191 for (uint32_t ii = 0; ii < numSrd; ++ii) 5192 { 5193 uint32_t idealWidth = bx::max<uint32_t>(1, m_width >> imageInfos[ii].mipLevel); 5194 uint32_t idealHeight = bx::max<uint32_t>(1, m_height >> imageInfos[ii].mipLevel); 5195 bufferCopyInfo[ii].bufferOffset = totalMemSize; 5196 bufferCopyInfo[ii].bufferRowLength = 0; // assume that image data are tightly aligned 5197 bufferCopyInfo[ii].bufferImageHeight = 0; // assume that image data are tightly aligned 5198 bufferCopyInfo[ii].imageSubresource.aspectMask = m_vkTextureAspect; 5199 bufferCopyInfo[ii].imageSubresource.mipLevel = imageInfos[ii].mipLevel; 5200 bufferCopyInfo[ii].imageSubresource.baseArrayLayer = imageInfos[ii].layer; 5201 bufferCopyInfo[ii].imageSubresource.layerCount = 1; 5202 bufferCopyInfo[ii].imageOffset = { 0, 0, 0 }; 5203 bufferCopyInfo[ii].imageExtent = { idealWidth, idealHeight, imageInfos[ii].depth }; 5204 totalMemSize += imageInfos[ii].size; 5205 } 5206 5207 VkBuffer stagingBuffer = VK_NULL_HANDLE; 5208 VkDeviceMemory stagingDeviceMem = VK_NULL_HANDLE; 5209 if (totalMemSize > 0) 5210 { 5211 // staging buffer creation 5212 VkBufferCreateInfo bci; 5213 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 5214 bci.pNext = NULL; 5215 bci.flags = 0; 5216 bci.size = totalMemSize; 5217 bci.queueFamilyIndexCount = 0; 5218 bci.pQueueFamilyIndices = NULL; 5219 bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 5220 bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 5221 VK_CHECK(vkCreateBuffer( 5222 device 5223 , &bci 5224 , allocatorCb 5225 , &stagingBuffer 5226 )); 5227 5228 VkMemoryRequirements mr; 5229 vkGetBufferMemoryRequirements( 5230 device 5231 , stagingBuffer 5232 , &mr 5233 ); 5234 5235 VkMemoryAllocateInfo ma; 5236 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 5237 ma.pNext = NULL; 5238 ma.allocationSize = mr.size; 5239 ma.memoryTypeIndex = s_renderVK->selectMemoryType( 5240 mr.memoryTypeBits 5241 , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT 5242 ); 5243 VK_CHECK(vkAllocateMemory( 5244 device 5245 , &ma 5246 , allocatorCb 5247 , &stagingDeviceMem 5248 )); 5249 5250 VK_CHECK(vkBindBufferMemory( 5251 device 5252 , stagingBuffer 5253 , stagingDeviceMem 5254 , 0 5255 )); 5256 VK_CHECK(vkMapMemory( 5257 device 5258 , stagingDeviceMem 5259 , 0 5260 , ma.allocationSize 5261 , 0 5262 , (void**)& m_directAccessPtr 5263 )); 5264 5265 uint8_t* mappedMemory = (uint8_t*)m_directAccessPtr; 5266 5267 // copy image to staging buffer 5268 for (uint32_t ii = 0; ii < numSrd; ++ii) 5269 { 5270 bx::memCopy(mappedMemory, imageInfos[ii].data, imageInfos[ii].size); 5271 mappedMemory += imageInfos[ii].size; 5272 } 5273 5274 vkUnmapMemory(device, stagingDeviceMem); 5275 } 5276 5277 // create texture and allocate its device memory 5278 VkImageCreateInfo ici; 5279 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 5280 ici.pNext = NULL; 5281 ici.flags = VK_IMAGE_VIEW_TYPE_CUBE == m_type 5282 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT 5283 : 0 5284 ; 5285 ici.pQueueFamilyIndices = NULL; 5286 ici.queueFamilyIndexCount = 0; 5287 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 5288 ici.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 5289 ici.usage = 0 5290 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT 5291 | VK_IMAGE_USAGE_TRANSFER_DST_BIT 5292 | VK_IMAGE_USAGE_SAMPLED_BIT 5293 | (_flags & BGFX_TEXTURE_RT_MASK 5294 ? (bimg::isDepth((bimg::TextureFormat::Enum)m_textureFormat) 5295 ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT 5296 : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) 5297 : 0 5298 ) 5299 | (_flags & BGFX_TEXTURE_COMPUTE_WRITE ? VK_IMAGE_USAGE_STORAGE_BIT : 0) 5300 ; 5301 ici.format = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) 5302 ? s_textureFormat[m_textureFormat].m_fmtDsv 5303 : s_textureFormat[m_textureFormat].m_fmt 5304 ; 5305 ici.samples = VK_SAMPLE_COUNT_1_BIT; 5306 ici.mipLevels = m_numMips; 5307 ici.arrayLayers = m_numSides; 5308 ici.extent.width = m_width; 5309 ici.extent.height = m_height; 5310 ici.extent.depth = m_depth; 5311 ici.imageType = VK_IMAGE_VIEW_TYPE_3D == m_type 5312 ? VK_IMAGE_TYPE_3D 5313 : VK_IMAGE_TYPE_2D 5314 ; 5315 ici.tiling = VK_IMAGE_TILING_OPTIMAL; 5316 5317 VK_CHECK(vkCreateImage(device, &ici, allocatorCb, &m_textureImage)); 5318 5319 VkMemoryRequirements imageMemReq; 5320 vkGetImageMemoryRequirements(device, m_textureImage, &imageMemReq); 5321 5322 VkMemoryAllocateInfo imai; 5323 imai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 5324 imai.pNext = NULL; 5325 imai.allocationSize = imageMemReq.size; 5326 imai.memoryTypeIndex = s_renderVK->selectMemoryType( 5327 imageMemReq.memoryTypeBits 5328 , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 5329 ); 5330 5331 VK_CHECK(vkAllocateMemory(device, &imai, allocatorCb, &m_textureDeviceMem)); 5332 5333 vkBindImageMemory(device, m_textureImage, m_textureDeviceMem, 0); 5334 5335 if (stagingBuffer) 5336 { 5337 copyBufferToTexture(stagingBuffer, numSrd, bufferCopyInfo); 5338 } 5339 else 5340 { 5341 VkCommandBuffer commandBuffer = s_renderVK->beginNewCommand(); 5342 setImageMemoryBarrier( 5343 commandBuffer 5344 , (m_flags & BGFX_TEXTURE_COMPUTE_WRITE 5345 ? VK_IMAGE_LAYOUT_GENERAL 5346 : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 5347 ) 5348 ); 5349 s_renderVK->submitCommandAndWait(commandBuffer); 5350 } 5351 5352 vkFreeMemory(device, stagingDeviceMem, allocatorCb); 5353 vkDestroy(stagingBuffer); 5354 5355 BX_FREE(g_allocator, bufferCopyInfo); 5356 for (uint32_t ii = 0; ii < numSrd; ++ii) 5357 { 5358 BX_FREE(g_allocator, imageInfos[ii].data); 5359 } 5360 BX_FREE(g_allocator, imageInfos); 5361 5362 // image view creation 5363 { 5364 VkImageViewCreateInfo viewInfo; 5365 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 5366 viewInfo.pNext = NULL; 5367 viewInfo.flags = 0; 5368 viewInfo.image = m_textureImage; 5369 viewInfo.viewType = m_type; 5370 viewInfo.format = m_vkTextureFormat; 5371 viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 5372 viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 5373 viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 5374 viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 5375 viewInfo.subresourceRange.aspectMask = m_vkTextureAspect; 5376 viewInfo.subresourceRange.baseMipLevel = 0; 5377 viewInfo.subresourceRange.levelCount = m_numMips; //m_numMips; 5378 viewInfo.subresourceRange.baseArrayLayer = 0; 5379 viewInfo.subresourceRange.layerCount = m_numSides; //(m_type == VK_IMAGE_VIEW_TYPE_CUBE ? 6 : m_numLayers); 5380 VK_CHECK(vkCreateImageView( 5381 device 5382 , &viewInfo 5383 , allocatorCb 5384 , &m_textureImageView 5385 )); 5386 } 5387 5388 if ((m_vkTextureAspect & VK_IMAGE_ASPECT_DEPTH_BIT) 5389 && (m_vkTextureAspect & VK_IMAGE_ASPECT_STENCIL_BIT)) 5390 { 5391 VkImageViewCreateInfo viewInfo; 5392 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 5393 viewInfo.pNext = NULL; 5394 viewInfo.flags = 0; 5395 viewInfo.image = m_textureImage; 5396 viewInfo.viewType = m_type; 5397 viewInfo.format = m_vkTextureFormat; 5398 viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 5399 viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 5400 viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 5401 viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 5402 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 5403 viewInfo.subresourceRange.baseMipLevel = 0; 5404 viewInfo.subresourceRange.levelCount = m_numMips; //m_numMips; 5405 viewInfo.subresourceRange.baseArrayLayer = 0; 5406 viewInfo.subresourceRange.layerCount = m_numSides; //(m_type == VK_IMAGE_VIEW_TYPE_CUBE ? 6 : m_numLayers); 5407 VK_CHECK(vkCreateImageView( 5408 device 5409 , &viewInfo 5410 , allocatorCb 5411 , &m_textureImageDepthView 5412 )); 5413 } 5414 5415 // image view creation for storage if needed 5416 if (m_flags & BGFX_TEXTURE_COMPUTE_WRITE) 5417 { 5418 VkImageViewCreateInfo viewInfo; 5419 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 5420 viewInfo.pNext = NULL; 5421 viewInfo.flags = 0; 5422 viewInfo.image = m_textureImage; 5423 viewInfo.viewType = (m_type == VK_IMAGE_VIEW_TYPE_CUBE ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : m_type); 5424 viewInfo.format = m_vkTextureFormat; 5425 viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 5426 viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 5427 viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 5428 viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 5429 viewInfo.subresourceRange.aspectMask = m_vkTextureAspect; 5430 viewInfo.subresourceRange.baseMipLevel = 0; 5431 viewInfo.subresourceRange.levelCount = m_numMips; //m_numMips; 5432 viewInfo.subresourceRange.baseArrayLayer = 0; 5433 viewInfo.subresourceRange.layerCount = m_numSides; //(m_type == VK_IMAGE_VIEW_TYPE_CUBE ? 6 : m_numLayers); 5434 VK_CHECK(vkCreateImageView( 5435 device 5436 , &viewInfo 5437 , allocatorCb 5438 , &m_textureImageStorageView 5439 )); 5440 } 5441 } 5442 5443 return m_directAccessPtr; 5444 } 5445 destroy()5446 void TextureVK::destroy() 5447 { 5448 if (m_textureImage) 5449 { 5450 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 5451 VkDevice device = s_renderVK->m_device; 5452 5453 vkFreeMemory(device, m_textureDeviceMem, allocatorCb); 5454 5455 vkDestroy(m_textureImageStorageView); 5456 vkDestroy(m_textureImageDepthView); 5457 vkDestroy(m_textureImageView); 5458 vkDestroy(m_textureImage); 5459 5460 m_currentImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; 5461 } 5462 } 5463 update(VkCommandPool _commandPool,uint8_t _side,uint8_t _mip,const Rect & _rect,uint16_t _z,uint16_t _depth,uint16_t _pitch,const Memory * _mem)5464 void TextureVK::update(VkCommandPool _commandPool, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) 5465 { 5466 BX_UNUSED(_commandPool); 5467 5468 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 5469 VkDevice device = s_renderVK->m_device; 5470 5471 VkBuffer stagingBuffer = VK_NULL_HANDLE; 5472 VkDeviceMemory stagingDeviceMem = VK_NULL_HANDLE; 5473 5474 // staging buffer creation 5475 VkBufferCreateInfo bci; 5476 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 5477 bci.pNext = NULL; 5478 bci.flags = 0; 5479 bci.size = (_pitch == UINT16_MAX ? _mem->size :_rect.m_height * _pitch * _depth); 5480 bci.queueFamilyIndexCount = 0; 5481 bci.pQueueFamilyIndices = NULL; 5482 bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 5483 bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 5484 VK_CHECK(vkCreateBuffer( 5485 device 5486 , &bci 5487 , allocatorCb 5488 , &stagingBuffer 5489 )); 5490 5491 VkMemoryRequirements mr; 5492 vkGetBufferMemoryRequirements( 5493 device 5494 , stagingBuffer 5495 , &mr 5496 ); 5497 5498 VkMemoryAllocateInfo ma; 5499 ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 5500 ma.pNext = NULL; 5501 ma.allocationSize = mr.size; 5502 ma.memoryTypeIndex = s_renderVK->selectMemoryType( 5503 mr.memoryTypeBits 5504 , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT 5505 ); 5506 VK_CHECK(vkAllocateMemory( 5507 device 5508 , &ma 5509 , allocatorCb 5510 , &stagingDeviceMem 5511 )); 5512 5513 void* directAccessPtr = NULL; 5514 VK_CHECK(vkBindBufferMemory(device, stagingBuffer, stagingDeviceMem, 0)); 5515 VK_CHECK(vkMapMemory(device, stagingDeviceMem, 0, ma.allocationSize, 0, (void**)&directAccessPtr)); 5516 bx::memCopy(directAccessPtr, _mem->data, size_t(bci.size)); 5517 vkUnmapMemory(device, stagingDeviceMem); 5518 5519 const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); 5520 VkBufferImageCopy region; 5521 region.bufferOffset = 0; 5522 region.bufferRowLength = (_pitch == UINT16_MAX ? 0 : _pitch * 8 / bpp); 5523 region.bufferImageHeight = 0; 5524 region.imageSubresource.aspectMask = m_vkTextureAspect; 5525 region.imageSubresource.mipLevel = _mip; 5526 region.imageSubresource.baseArrayLayer = _side; 5527 region.imageSubresource.layerCount = 1; 5528 region.imageOffset = { _rect.m_x, _rect.m_y, _z }; 5529 region.imageExtent = { _rect.m_width, _rect.m_height, _depth }; 5530 5531 copyBufferToTexture(stagingBuffer, 1, ®ion); 5532 5533 vkFreeMemory(device, stagingDeviceMem, allocatorCb); 5534 vkDestroy(stagingBuffer); 5535 } 5536 copyBufferToTexture(VkBuffer stagingBuffer,uint32_t bufferImageCopyCount,VkBufferImageCopy * bufferImageCopy)5537 void TextureVK::copyBufferToTexture(VkBuffer stagingBuffer, uint32_t bufferImageCopyCount, VkBufferImageCopy* bufferImageCopy) 5538 { 5539 VkCommandBuffer commandBuffer = s_renderVK->beginNewCommand(); 5540 5541 // image Layout transition into destination optimal 5542 setImageMemoryBarrier(commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 5543 5544 // copy buffer to image 5545 vkCmdCopyBufferToImage( 5546 commandBuffer 5547 , stagingBuffer 5548 , m_textureImage 5549 , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 5550 , bufferImageCopyCount 5551 , bufferImageCopy 5552 ); 5553 5554 setImageMemoryBarrier(commandBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 5555 s_renderVK->submitCommandAndWait(commandBuffer); 5556 } 5557 setImageMemoryBarrier(VkCommandBuffer commandBuffer,VkImageLayout newImageLayout)5558 void TextureVK::setImageMemoryBarrier(VkCommandBuffer commandBuffer, VkImageLayout newImageLayout) 5559 { 5560 if (m_currentImageLayout == newImageLayout) 5561 return; 5562 bgfx::vk::setImageMemoryBarrier(commandBuffer 5563 , m_textureImage 5564 , m_vkTextureAspect 5565 , m_currentImageLayout 5566 , newImageLayout 5567 , m_numMips 5568 , m_numSides 5569 ); 5570 m_currentImageLayout = newImageLayout; 5571 } 5572 create(uint8_t _num,const Attachment * _attachment)5573 void FrameBufferVK::create(uint8_t _num, const Attachment* _attachment) 5574 { 5575 // create frame buffer object 5576 m_numAttachment = _num; 5577 bx::memCopy(m_attachment, _attachment, sizeof(Attachment) * _num); 5578 5579 VkDevice device = s_renderVK->m_device; 5580 VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; 5581 VkRenderPass renderPass = s_renderVK->getRenderPass(_num, _attachment); 5582 5583 TextureVK& firstTexture = s_renderVK->m_textures[m_attachment[0].handle.idx]; 5584 ::VkImageView textureImageViews[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; 5585 5586 m_num = 0; 5587 for (uint8_t ii = 0; ii < m_numAttachment; ++ii) 5588 { 5589 TextureVK& texture = s_renderVK->m_textures[m_attachment[ii].handle.idx]; 5590 textureImageViews[ii] = texture.m_textureImageView; 5591 if (texture.m_vkTextureAspect & VK_IMAGE_ASPECT_COLOR_BIT) 5592 { 5593 m_texture[m_num] = m_attachment[ii].handle; 5594 m_num++; 5595 } 5596 else if (texture.m_vkTextureAspect & VK_IMAGE_ASPECT_DEPTH_BIT) 5597 { 5598 m_depth = m_attachment[ii].handle; 5599 } 5600 } 5601 5602 VkFramebufferCreateInfo fci; 5603 fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 5604 fci.pNext = NULL; 5605 fci.flags = 0; 5606 fci.renderPass = renderPass; 5607 fci.attachmentCount = m_numAttachment; 5608 fci.pAttachments = textureImageViews; 5609 fci.width = firstTexture.m_width >> m_attachment[0].mip; 5610 fci.height = firstTexture.m_height >> m_attachment[0].mip; 5611 fci.layers = firstTexture.m_numSides; 5612 VK_CHECK( vkCreateFramebuffer(device, &fci, allocatorCb, &m_framebuffer) ); 5613 m_renderPass = renderPass; 5614 } 5615 destroy()5616 void FrameBufferVK::destroy() 5617 { 5618 vkDestroy(m_framebuffer); 5619 } 5620 submitBlit(BlitState & _bs,uint16_t _view)5621 void RendererContextVK::submitBlit(BlitState& _bs, uint16_t _view) 5622 { 5623 TextureHandle currentSrc = { kInvalidHandle }; 5624 TextureHandle currentDst = { kInvalidHandle }; 5625 VkImageLayout oldSrcLayout = VK_IMAGE_LAYOUT_UNDEFINED; 5626 VkImageLayout oldDstLayout = VK_IMAGE_LAYOUT_UNDEFINED; 5627 5628 VkCommandBuffer commandBuffer = beginNewCommand(); 5629 while (_bs.hasItem(_view) ) 5630 { 5631 const BlitItem& blit = _bs.advance(); 5632 5633 TextureVK& src = m_textures[blit.m_src.idx]; 5634 TextureVK& dst = m_textures[blit.m_dst.idx]; 5635 5636 if (currentSrc.idx != blit.m_src.idx) 5637 { 5638 if (oldSrcLayout != VK_IMAGE_LAYOUT_UNDEFINED) 5639 { 5640 m_textures[currentSrc.idx].setImageMemoryBarrier(commandBuffer, oldSrcLayout); 5641 } 5642 oldSrcLayout = src.m_currentImageLayout; 5643 src.setImageMemoryBarrier(commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 5644 currentSrc = blit.m_src; 5645 } 5646 5647 if (currentDst.idx != blit.m_dst.idx) 5648 { 5649 if (oldDstLayout != VK_IMAGE_LAYOUT_UNDEFINED) 5650 { 5651 m_textures[currentDst.idx].setImageMemoryBarrier(commandBuffer, oldDstLayout); 5652 } 5653 oldDstLayout = dst.m_currentImageLayout; 5654 dst.setImageMemoryBarrier(commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 5655 currentDst = blit.m_dst; 5656 } 5657 5658 uint32_t srcZ = (VK_IMAGE_VIEW_TYPE_CUBE == src.m_type ? 0 : blit.m_srcZ); 5659 uint32_t dstZ = (VK_IMAGE_VIEW_TYPE_CUBE == dst.m_type ? 0 : blit.m_dstZ); 5660 uint32_t srcLayer = (VK_IMAGE_VIEW_TYPE_CUBE == src.m_type ? blit.m_srcZ : 0); 5661 uint32_t dstLayer = (VK_IMAGE_VIEW_TYPE_CUBE == dst.m_type ? blit.m_dstZ : 0); 5662 uint32_t depth = (blit.m_depth == UINT16_MAX ? 1 : blit.m_depth); 5663 5664 VkImageBlit blitInfo; 5665 blitInfo.srcSubresource.aspectMask = src.m_vkTextureAspect; 5666 blitInfo.srcSubresource.mipLevel = blit.m_srcMip; 5667 blitInfo.srcSubresource.baseArrayLayer = srcLayer; 5668 blitInfo.srcSubresource.layerCount = 1; 5669 blitInfo.srcOffsets[0].x = blit.m_srcX; 5670 blitInfo.srcOffsets[0].y = blit.m_srcY; 5671 blitInfo.srcOffsets[0].z = srcZ; 5672 blitInfo.srcOffsets[1].x = blit.m_srcX + blit.m_width; 5673 blitInfo.srcOffsets[1].y = blit.m_srcY + blit.m_height; 5674 blitInfo.srcOffsets[1].z = srcZ + depth; 5675 blitInfo.dstSubresource.aspectMask = dst.m_vkTextureAspect; 5676 blitInfo.dstSubresource.mipLevel = blit.m_dstMip; 5677 blitInfo.dstSubresource.baseArrayLayer = dstLayer; 5678 blitInfo.dstSubresource.layerCount = 1; 5679 blitInfo.dstOffsets[0].x = blit.m_dstX; 5680 blitInfo.dstOffsets[0].y = blit.m_dstY; 5681 blitInfo.dstOffsets[0].z = dstZ; 5682 blitInfo.dstOffsets[1].x = blit.m_dstX + blit.m_width; 5683 blitInfo.dstOffsets[1].y = blit.m_dstY + blit.m_height; 5684 blitInfo.dstOffsets[1].z = dstZ + depth; 5685 vkCmdBlitImage( 5686 commandBuffer 5687 , src.m_textureImage 5688 , src.m_currentImageLayout 5689 , dst.m_textureImage 5690 , dst.m_currentImageLayout 5691 , 1 5692 , &blitInfo 5693 , VK_FILTER_LINEAR 5694 ); 5695 } 5696 5697 if (oldSrcLayout != VK_IMAGE_LAYOUT_UNDEFINED) 5698 { 5699 m_textures[currentSrc.idx].setImageMemoryBarrier(commandBuffer, oldSrcLayout); 5700 } 5701 if (oldDstLayout != VK_IMAGE_LAYOUT_UNDEFINED) 5702 { 5703 m_textures[currentDst.idx].setImageMemoryBarrier(commandBuffer, oldDstLayout); 5704 } 5705 submitCommandAndWait(commandBuffer); 5706 } 5707 submit(Frame * _render,ClearQuad & _clearQuad,TextVideoMemBlitter & _textVideoMemBlitter)5708 void RendererContextVK::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) 5709 { 5710 BX_UNUSED(_render, _clearQuad, _textVideoMemBlitter); 5711 5712 updateResolution(_render->m_resolution); 5713 5714 int64_t timeBegin = bx::getHPCounter(); 5715 int64_t captureElapsed = 0; 5716 5717 // m_gpuTimer.begin(m_commandList); 5718 5719 if (0 < _render->m_iboffset) 5720 { 5721 BGFX_PROFILER_SCOPE("bgfx/Update transient index buffer", kColorResource); 5722 TransientIndexBuffer* ib = _render->m_transientIb; 5723 m_indexBuffers[ib->handle.idx].update(/*m_commandList*/NULL, 0, _render->m_iboffset, ib->data); 5724 } 5725 5726 if (0 < _render->m_vboffset) 5727 { 5728 BGFX_PROFILER_SCOPE("bgfx/Update transient vertex buffer", kColorResource); 5729 TransientVertexBuffer* vb = _render->m_transientVb; 5730 m_vertexBuffers[vb->handle.idx].update(/*m_commandList*/NULL, 0, _render->m_vboffset, vb->data); 5731 } 5732 5733 _render->sort(); 5734 5735 RenderDraw currentState; 5736 currentState.clear(); 5737 currentState.m_stateFlags = BGFX_STATE_NONE; 5738 currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); 5739 5740 static ViewState viewState; 5741 viewState.reset(_render); 5742 5743 // bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME); 5744 // setDebugWireframe(wireframe); 5745 5746 uint16_t currentSamplerStateIdx = kInvalidHandle; 5747 ProgramHandle currentProgram = BGFX_INVALID_HANDLE; 5748 uint32_t currentBindHash = 0; 5749 uint32_t currentDslHash = 0; 5750 bool hasPredefined = false; 5751 bool commandListChanged = false; 5752 VkPipeline currentPipeline = VK_NULL_HANDLE; 5753 SortKey key; 5754 uint16_t view = UINT16_MAX; 5755 FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS }; 5756 5757 BlitState bs(_render); 5758 5759 uint32_t blendFactor = 0; 5760 5761 const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0; 5762 uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT); 5763 PrimInfo prim = s_primInfo[primIndex]; 5764 5765 bool wasCompute = false; 5766 bool viewHasScissor = false; 5767 bool restoreScissor = false; 5768 Rect viewScissorRect; 5769 viewScissorRect.clear(); 5770 5771 const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings; 5772 BX_UNUSED(maxComputeBindings); 5773 5774 uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {}; 5775 uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {}; 5776 uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {}; 5777 uint32_t statsNumIndices = 0; 5778 uint32_t statsKeyType[2] = {}; 5779 5780 VkSemaphore renderWait = m_presentDone[m_backBufferColorIdx]; 5781 VkResult result = vkAcquireNextImageKHR( 5782 m_device 5783 , m_swapchain 5784 , UINT64_MAX 5785 , renderWait 5786 , VK_NULL_HANDLE 5787 , &m_backBufferColorIdx 5788 ); 5789 5790 if (VK_ERROR_OUT_OF_DATE_KHR == result 5791 || VK_SUBOPTIMAL_KHR == result) 5792 { 5793 m_needToRefreshSwapchain = true; 5794 return; 5795 } 5796 5797 // const uint64_t f0 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_FACTOR, BGFX_STATE_BLEND_FACTOR); 5798 // const uint64_t f1 = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_FACTOR, BGFX_STATE_BLEND_INV_FACTOR); 5799 const uint64_t f0 = BGFX_STATE_BLEND_FACTOR; 5800 const uint64_t f1 = BGFX_STATE_BLEND_INV_FACTOR; 5801 const uint64_t f2 = BGFX_STATE_BLEND_FACTOR<<4; 5802 const uint64_t f3 = BGFX_STATE_BLEND_INV_FACTOR<<4; 5803 5804 ScratchBufferVK& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx]; 5805 scratchBuffer.reset(); 5806 5807 VkCommandBufferBeginInfo cbbi; 5808 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 5809 cbbi.pNext = NULL; 5810 cbbi.flags = 0 5811 | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT 5812 // | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT 5813 ; 5814 cbbi.pInheritanceInfo = NULL; 5815 5816 m_commandBuffer = m_commandBuffers[m_backBufferColorIdx]; 5817 VK_CHECK(vkBeginCommandBuffer(m_commandBuffer, &cbbi) ); 5818 5819 setImageMemoryBarrier(m_commandBuffer 5820 , m_backBufferColorImage[m_backBufferColorIdx] 5821 , VK_IMAGE_ASPECT_COLOR_BIT 5822 , m_backBufferColorImageLayout[m_backBufferColorIdx] 5823 , VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 5824 , 1, 1); 5825 m_backBufferColorImageLayout[m_backBufferColorIdx] = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 5826 5827 VkRenderPassBeginInfo rpbi; 5828 rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 5829 rpbi.pNext = NULL; 5830 rpbi.renderPass = m_renderPass; 5831 rpbi.framebuffer = m_backBufferColor[m_backBufferColorIdx]; 5832 rpbi.renderArea.offset.x = 0; 5833 rpbi.renderArea.offset.y = 0; 5834 rpbi.renderArea.extent = m_sci.imageExtent; 5835 rpbi.clearValueCount = 0; 5836 rpbi.pClearValues = NULL; 5837 5838 bool beginRenderPass = false; 5839 5840 if (0 == (_render->m_debug&BGFX_DEBUG_IFH) ) 5841 { 5842 // m_batch.begin(); 5843 5844 viewState.m_rect = _render->m_view[0].m_rect; 5845 5846 int32_t numItems = _render->m_numRenderItems; 5847 for (int32_t item = 0; item < numItems;) 5848 { 5849 const uint64_t encodedKey = _render->m_sortKeys[item]; 5850 const bool isCompute = key.decode(encodedKey, _render->m_viewRemap); 5851 statsKeyType[isCompute]++; 5852 5853 const bool viewChanged = 0 5854 || key.m_view != view 5855 || item == numItems 5856 ; 5857 5858 const uint32_t itemIdx = _render->m_sortValues[item]; 5859 const RenderItem& renderItem = _render->m_renderItem[itemIdx]; 5860 const RenderBind& renderBind = _render->m_renderItemBind[itemIdx]; 5861 ++item; 5862 5863 if (viewChanged || isCompute || wasCompute) 5864 { 5865 if (beginRenderPass) 5866 { 5867 vkCmdEndRenderPass(m_commandBuffer); 5868 beginRenderPass = false; 5869 5870 if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) && s_extension[Extension::EXT_debug_utils].m_supported ) 5871 { 5872 vkCmdEndDebugUtilsLabelEXT(m_commandBuffer); 5873 } 5874 } 5875 5876 VK_CHECK(vkEndCommandBuffer(m_commandBuffer) ); 5877 5878 // m_batch.flush(m_commandList, true); 5879 kick(renderWait); 5880 renderWait = VK_NULL_HANDLE; 5881 finishAll(); 5882 5883 view = key.m_view; 5884 currentPipeline = VK_NULL_HANDLE; 5885 currentSamplerStateIdx = kInvalidHandle; 5886 BX_UNUSED(currentSamplerStateIdx); 5887 currentProgram = BGFX_INVALID_HANDLE; 5888 hasPredefined = false; 5889 5890 VK_CHECK(vkBeginCommandBuffer(m_commandBuffer, &cbbi) ); 5891 fbh = _render->m_view[view].m_fbh; 5892 setFrameBuffer(fbh); 5893 5894 viewState.m_rect = _render->m_view[view].m_rect; 5895 const Rect& rect = _render->m_view[view].m_rect; 5896 const Rect& scissorRect = _render->m_view[view].m_scissor; 5897 viewHasScissor = !scissorRect.isZero(); 5898 viewScissorRect = viewHasScissor ? scissorRect : rect; 5899 5900 rpbi.framebuffer = isValid(m_fbh) ? m_frameBuffers[m_fbh.idx].m_framebuffer : m_backBufferColor[m_backBufferColorIdx]; 5901 rpbi.renderPass = isValid(m_fbh) ? m_frameBuffers[m_fbh.idx].m_renderPass : m_renderPass; 5902 rpbi.renderArea.offset.x = rect.m_x; 5903 rpbi.renderArea.offset.y = rect.m_y; 5904 rpbi.renderArea.extent.width = rect.m_width; 5905 rpbi.renderArea.extent.height = rect.m_height; 5906 5907 if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) && s_extension[Extension::EXT_debug_utils].m_supported ) 5908 { 5909 VkDebugUtilsLabelEXT dul; 5910 dul.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; 5911 dul.pNext = NULL; 5912 dul.pLabelName = s_viewName[view]; 5913 dul.color[0] = 1.0f; 5914 dul.color[1] = 1.0f; 5915 dul.color[2] = 1.0f; 5916 dul.color[3] = 1.0f; 5917 vkCmdBeginDebugUtilsLabelEXT(m_commandBuffer, &dul); 5918 } 5919 5920 if (!isCompute && !beginRenderPass) 5921 { 5922 vkCmdBeginRenderPass(m_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE); 5923 beginRenderPass = true; 5924 5925 VkViewport vp; 5926 vp.x = rect.m_x; 5927 vp.y = rect.m_y; 5928 vp.width = rect.m_width; 5929 vp.height = rect.m_height; 5930 vp.minDepth = 0.0f; 5931 vp.maxDepth = 1.0f; 5932 vkCmdSetViewport(m_commandBuffer, 0, 1, &vp); 5933 5934 VkRect2D rc; 5935 rc.offset.x = viewScissorRect.m_x; 5936 rc.offset.y = viewScissorRect.m_y; 5937 rc.extent.width = viewScissorRect.m_width; 5938 rc.extent.height = viewScissorRect.m_height; 5939 vkCmdSetScissor(m_commandBuffer, 0, 1, &rc); 5940 5941 restoreScissor = false; 5942 5943 Clear& clr = _render->m_view[view].m_clear; 5944 if (BGFX_CLEAR_NONE != clr.m_flags) 5945 { 5946 Rect clearRect = rect; 5947 clearRect.setIntersect(rect, viewScissorRect); 5948 clearQuad(clearRect, clr, _render->m_colorPalette); 5949 } 5950 5951 prim = s_primInfo[Topology::Count]; // Force primitive type update. 5952 5953 submitBlit(bs, view); 5954 } 5955 } 5956 5957 if (isCompute) 5958 { 5959 if (!wasCompute) 5960 { 5961 wasCompute = true; 5962 5963 // m_commandList->SetComputeRootSignature(m_rootSignature); 5964 // ID3D12DescriptorHeap* heaps[] = { 5965 // m_samplerAllocator.getHeap(), 5966 // scratchBuffer.getHeap(), 5967 // }; 5968 // m_commandList->SetDescriptorHeaps(BX_COUNTOF(heaps), heaps); 5969 } 5970 5971 const RenderCompute& compute = renderItem.compute; 5972 5973 VkPipeline pipeline = getPipeline(key.m_program); 5974 if (pipeline != currentPipeline) 5975 { 5976 currentPipeline = pipeline; 5977 vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); 5978 currentBindHash = 0; 5979 currentDslHash = 0; 5980 } 5981 5982 bool constantsChanged = false; 5983 if (compute.m_uniformBegin < compute.m_uniformEnd 5984 || currentProgram.idx != key.m_program.idx) 5985 { 5986 rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); 5987 5988 currentProgram = key.m_program; 5989 ProgramVK& program = m_program[currentProgram.idx]; 5990 5991 UniformBuffer* vcb = program.m_vsh->m_constantBuffer; 5992 if (NULL != vcb) 5993 { 5994 commit(*vcb); 5995 } 5996 5997 hasPredefined = 0 < program.m_numPredefined; 5998 constantsChanged = true; 5999 } 6000 6001 ProgramVK& program = m_program[currentProgram.idx]; 6002 if (constantsChanged 6003 || hasPredefined) 6004 { 6005 viewState.setPredefined<4>(this, view, program, _render, compute); 6006 // commitShaderConstants(key.m_program, gpuAddress); 6007 // m_commandList->SetComputeRootConstantBufferView(Rdt::CBV, gpuAddress); 6008 } 6009 6010 uint32_t bindHash = bx::hash<bx::HashMurmur2A>(renderBind.m_bind, sizeof(renderBind.m_bind) ); 6011 if (currentBindHash != bindHash 6012 || currentDslHash != program.m_descriptorSetLayoutHash) 6013 { 6014 currentBindHash = bindHash; 6015 currentDslHash = program.m_descriptorSetLayoutHash; 6016 6017 allocDescriptorSet(program, renderBind, scratchBuffer); 6018 } 6019 6020 uint32_t offset = 0; 6021 6022 if (constantsChanged 6023 || hasPredefined) 6024 { 6025 const uint32_t align = uint32_t(m_deviceProperties.limits.minUniformBufferOffsetAlignment); 6026 const uint32_t vsize = bx::strideAlign(program.m_vsh->m_size, align); 6027 6028 offset = scratchBuffer.m_pos; 6029 6030 m_vsChanges = 0; 6031 m_fsChanges = 0; 6032 6033 bx::memCopy(&scratchBuffer.m_data[scratchBuffer.m_pos], m_vsScratch, program.m_vsh->m_size); 6034 6035 scratchBuffer.m_pos += vsize; 6036 } 6037 6038 vkCmdBindDescriptorSets( 6039 m_commandBuffer 6040 , VK_PIPELINE_BIND_POINT_COMPUTE 6041 , program.m_pipelineLayout 6042 , 0 6043 , 1 6044 , &scratchBuffer.getCurrentDS() 6045 , constantsChanged || hasPredefined ? 1 : 0 6046 , &offset 6047 ); 6048 6049 if (isValid(compute.m_indirectBuffer) ) 6050 { 6051 const VertexBufferVK& vb = m_vertexBuffers[compute.m_indirectBuffer.idx]; 6052 6053 uint32_t numDrawIndirect = UINT16_MAX == compute.m_numIndirect 6054 ? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE 6055 : compute.m_numIndirect 6056 ; 6057 6058 uint32_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; 6059 for (uint32_t ii = 0; ii < numDrawIndirect; ++ii) 6060 { 6061 vkCmdDispatchIndirect(m_commandBuffer, vb.m_buffer, args); 6062 args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE; 6063 } 6064 } 6065 else 6066 { 6067 vkCmdDispatch(m_commandBuffer, compute.m_numX, compute.m_numY, compute.m_numZ); 6068 } 6069 6070 continue; 6071 } 6072 6073 const RenderDraw& draw = renderItem.draw; 6074 6075 const bool hasOcclusionQuery = false; //0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY); 6076 { 6077 const bool occluded = false //true 6078 // && isValid(draw.m_occlusionQuery) 6079 // && !hasOcclusionQuery 6080 // && !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) 6081 ; 6082 6083 if (occluded 6084 || _render->m_frameCache.isZeroArea(viewScissorRect, draw.m_scissor) ) 6085 { 6086 // if (resetState) 6087 // { 6088 // currentState.clear(); 6089 // currentState.m_scissor = !draw.m_scissor; 6090 // currentBind.clear(); 6091 // } 6092 6093 continue; 6094 } 6095 } 6096 6097 const uint64_t newFlags = draw.m_stateFlags; 6098 uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags; 6099 currentState.m_stateFlags = newFlags; 6100 6101 const uint64_t newStencil = draw.m_stencil; 6102 uint64_t changedStencil = (currentState.m_stencil ^ draw.m_stencil) & BGFX_STENCIL_FUNC_REF_MASK; 6103 currentState.m_stencil = newStencil; 6104 6105 if (viewChanged 6106 || wasCompute) 6107 { 6108 if (wasCompute) 6109 { 6110 wasCompute = false; 6111 } 6112 6113 if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) 6114 { 6115 BX_UNUSED(s_viewName); 6116 // wchar_t* viewNameW = s_viewNameW[view]; 6117 // viewNameW[3] = L' '; 6118 // PIX_ENDEVENT(); 6119 // PIX_BEGINEVENT(toRgba8(0xff, 0x00, 0x00, 0xff), viewNameW); 6120 } 6121 6122 commandListChanged = true; 6123 } 6124 6125 if (commandListChanged) 6126 { 6127 commandListChanged = false; 6128 6129 // m_commandList->SetGraphicsRootSignature(m_rootSignature); 6130 // ID3D12DescriptorHeap* heaps[] = { 6131 // m_samplerAllocator.getHeap(), 6132 // scratchBuffer.getHeap(), 6133 // }; 6134 // m_commandList->SetDescriptorHeaps(BX_COUNTOF(heaps), heaps); 6135 6136 currentPipeline = VK_NULL_HANDLE; 6137 currentBindHash = 0; 6138 currentDslHash = 0; 6139 currentSamplerStateIdx = kInvalidHandle; 6140 currentProgram = BGFX_INVALID_HANDLE; 6141 currentState.clear(); 6142 currentState.m_scissor = !draw.m_scissor; 6143 changedFlags = BGFX_STATE_MASK; 6144 changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK); 6145 currentState.m_stateFlags = newFlags; 6146 currentState.m_stencil = newStencil; 6147 6148 const uint64_t pt = newFlags&BGFX_STATE_PT_MASK; 6149 primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); 6150 } 6151 6152 rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); 6153 6154 if (0 != draw.m_streamMask) 6155 { 6156 currentState.m_streamMask = draw.m_streamMask; 6157 6158 const uint64_t state = draw.m_stateFlags; 6159 bool hasFactor = 0 6160 || f0 == (state & f0) 6161 || f1 == (state & f1) 6162 || f2 == (state & f2) 6163 || f3 == (state & f3) 6164 ; 6165 6166 const VertexLayout* layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS]; 6167 uint8_t numStreams = 0; 6168 if (UINT8_MAX != draw.m_streamMask) 6169 { 6170 for (uint32_t idx = 0, streamMask = draw.m_streamMask 6171 ; 0 != streamMask 6172 ; streamMask >>= 1, idx += 1, ++numStreams 6173 ) 6174 { 6175 const uint32_t ntz = bx::uint32_cnttz(streamMask); 6176 streamMask >>= ntz; 6177 idx += ntz; 6178 6179 currentState.m_stream[idx].m_layoutHandle = draw.m_stream[idx].m_layoutHandle; 6180 currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; 6181 currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; 6182 6183 uint16_t handle = draw.m_stream[idx].m_handle.idx; 6184 const VertexBufferVK& vb = m_vertexBuffers[handle]; 6185 const uint16_t decl = isValid(draw.m_stream[idx].m_layoutHandle) 6186 ? draw.m_stream[idx].m_layoutHandle.idx 6187 : vb.m_layoutHandle.idx; 6188 const VertexLayout& layout = m_vertexLayouts[decl]; 6189 6190 layouts[numStreams] = &layout; 6191 } 6192 } 6193 6194 VkPipeline pipeline = 6195 getPipeline(state 6196 , draw.m_stencil 6197 , numStreams 6198 , layouts 6199 , key.m_program 6200 , uint8_t(draw.m_instanceDataStride/16) 6201 ); 6202 6203 uint16_t scissor = draw.m_scissor; 6204 uint32_t bindHash = bx::hash<bx::HashMurmur2A>(renderBind.m_bind, sizeof(renderBind.m_bind) ); 6205 6206 if (pipeline != currentPipeline 6207 || 0 != changedStencil) 6208 { 6209 const uint32_t fstencil = unpackStencil(0, draw.m_stencil); 6210 const uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT; 6211 vkCmdSetStencilReference(m_commandBuffer, VK_STENCIL_FRONT_AND_BACK, ref); 6212 } 6213 6214 if (pipeline != currentPipeline 6215 || (hasFactor && blendFactor != draw.m_rgba) ) 6216 { 6217 blendFactor = draw.m_rgba; 6218 6219 float bf[4]; 6220 bf[0] = ( (draw.m_rgba>>24) )/255.0f; 6221 bf[1] = ( (draw.m_rgba>>16)&0xff)/255.0f; 6222 bf[2] = ( (draw.m_rgba>> 8)&0xff)/255.0f; 6223 bf[3] = ( (draw.m_rgba )&0xff)/255.0f; 6224 vkCmdSetBlendConstants(m_commandBuffer, bf); 6225 } 6226 6227 if (0 != (BGFX_STATE_PT_MASK & changedFlags) 6228 || prim.m_topology != s_primInfo[primIndex].m_topology) 6229 { 6230 const uint64_t pt = newFlags&BGFX_STATE_PT_MASK; 6231 primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); 6232 prim = s_primInfo[primIndex]; 6233 // m_commandList->IASetPrimitiveTopology(prim.m_topology); 6234 } 6235 6236 if (currentState.m_scissor != scissor) 6237 { 6238 currentState.m_scissor = scissor; 6239 6240 if (UINT16_MAX == scissor) 6241 { 6242 if (restoreScissor 6243 || viewHasScissor) 6244 { 6245 restoreScissor = false; 6246 VkRect2D rc; 6247 rc.offset.x = viewScissorRect.m_x; 6248 rc.offset.y = viewScissorRect.m_y; 6249 rc.extent.width = viewScissorRect.m_width; 6250 rc.extent.height = viewScissorRect.m_height; 6251 vkCmdSetScissor(m_commandBuffer, 0, 1, &rc); 6252 } 6253 } 6254 else 6255 { 6256 restoreScissor = true; 6257 Rect scissorRect; 6258 scissorRect.setIntersect(viewScissorRect, _render->m_frameCache.m_rectCache.m_cache[scissor]); 6259 6260 VkRect2D rc; 6261 rc.offset.x = scissorRect.m_x; 6262 rc.offset.y = scissorRect.m_y; 6263 rc.extent.width = scissorRect.m_width; 6264 rc.extent.height = scissorRect.m_height; 6265 vkCmdSetScissor(m_commandBuffer, 0, 1, &rc); 6266 } 6267 } 6268 6269 if (pipeline != currentPipeline) 6270 { 6271 currentPipeline = pipeline; 6272 vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 6273 } 6274 6275 bool constantsChanged = false; 6276 if (draw.m_uniformBegin < draw.m_uniformEnd 6277 || currentProgram.idx != key.m_program.idx 6278 || BGFX_STATE_ALPHA_REF_MASK & changedFlags) 6279 { 6280 currentProgram = key.m_program; 6281 ProgramVK& program = m_program[currentProgram.idx]; 6282 6283 UniformBuffer* vcb = program.m_vsh->m_constantBuffer; 6284 if (NULL != vcb) 6285 { 6286 commit(*vcb); 6287 } 6288 6289 UniformBuffer* fcb = program.m_fsh->m_constantBuffer; 6290 if (NULL != fcb) 6291 { 6292 commit(*fcb); 6293 } 6294 6295 hasPredefined = 0 < program.m_numPredefined; 6296 constantsChanged = true; 6297 } 6298 6299 ProgramVK& program = m_program[currentProgram.idx]; 6300 if (hasPredefined) 6301 { 6302 uint32_t ref = (newFlags & BGFX_STATE_ALPHA_REF_MASK) >> BGFX_STATE_ALPHA_REF_SHIFT; 6303 viewState.m_alphaRef = ref / 255.0f; 6304 viewState.setPredefined<4>(this, view, program, _render, draw); 6305 } 6306 6307 if (currentBindHash != bindHash 6308 || currentDslHash != program.m_descriptorSetLayoutHash) 6309 { 6310 currentBindHash = bindHash; 6311 currentDslHash = program.m_descriptorSetLayoutHash; 6312 6313 allocDescriptorSet(program, renderBind, scratchBuffer); 6314 } 6315 6316 uint32_t numOffset = 0; 6317 uint32_t offsets[2] = {0, 0}; 6318 if (constantsChanged 6319 || hasPredefined) 6320 { 6321 const uint32_t align = uint32_t(m_deviceProperties.limits.minUniformBufferOffsetAlignment); 6322 const uint32_t vsize = bx::strideAlign(program.m_vsh->m_size, align); 6323 const uint32_t fsize = bx::strideAlign((NULL != program.m_fsh ? program.m_fsh->m_size : 0), align); 6324 const uint32_t total = vsize + fsize; 6325 if (vsize > 0) 6326 { 6327 offsets[numOffset++] = scratchBuffer.m_pos; 6328 bx::memCopy(&scratchBuffer.m_data[scratchBuffer.m_pos], m_vsScratch, program.m_vsh->m_size); 6329 } 6330 if (fsize > 0) 6331 { 6332 offsets[numOffset++] = scratchBuffer.m_pos + vsize; 6333 bx::memCopy(&scratchBuffer.m_data[scratchBuffer.m_pos + vsize], m_fsScratch, program.m_fsh->m_size); 6334 } 6335 6336 m_vsChanges = 0; 6337 m_fsChanges = 0; 6338 scratchBuffer.m_pos += total; 6339 } 6340 6341 vkCmdBindDescriptorSets( 6342 m_commandBuffer 6343 , VK_PIPELINE_BIND_POINT_GRAPHICS 6344 , program.m_pipelineLayout 6345 , 0 6346 , 1 6347 , &scratchBuffer.getCurrentDS() 6348 , numOffset 6349 , offsets 6350 ); 6351 6352 6353 // if (constantsChanged 6354 // || hasPredefined) 6355 // { 6356 // ProgramVK& program = m_program[currentProgram.idx]; 6357 // uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT; 6358 // viewState.m_alphaRef = ref/255.0f; 6359 // viewState.setPredefined<4>(this, view, program, _render, draw); 6360 // commitShaderUniforms(m_commandBuffer, key.m_program); //, gpuAddress); 6361 // } 6362 6363 // vb.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); 6364 6365 uint32_t numIndices = 0; 6366 for (uint32_t ii = 0; ii < numStreams; ++ii) 6367 { 6368 VkDeviceSize offset = 0; 6369 vkCmdBindVertexBuffers(m_commandBuffer 6370 , ii 6371 , 1 6372 , &m_vertexBuffers[draw.m_stream[ii].m_handle.idx].m_buffer 6373 , &offset 6374 ); 6375 } 6376 6377 if (isValid(draw.m_instanceDataBuffer)) 6378 { 6379 VkDeviceSize instanceOffset = draw.m_instanceDataOffset; 6380 VertexBufferVK& instanceBuffer = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; 6381 vkCmdBindVertexBuffers(m_commandBuffer 6382 , numStreams 6383 , 1 6384 , &instanceBuffer.m_buffer 6385 , &instanceOffset 6386 ); 6387 } 6388 6389 if (!isValid(draw.m_indexBuffer) ) 6390 { 6391 const VertexBufferVK& vertexBuffer = m_vertexBuffers[draw.m_stream[0].m_handle.idx]; 6392 const VertexLayout& layout = m_vertexLayouts[draw.m_stream[0].m_layoutHandle.idx]; 6393 6394 const uint32_t numVertices = UINT32_MAX == draw.m_numVertices 6395 ? vertexBuffer.m_size / layout.m_stride 6396 : draw.m_numVertices 6397 ; 6398 vkCmdDraw(m_commandBuffer 6399 , numVertices 6400 , draw.m_numInstances 6401 , draw.m_stream[0].m_startVertex 6402 , 0 6403 ); 6404 } 6405 else 6406 { 6407 BufferVK& ib = m_indexBuffers[draw.m_indexBuffer.idx]; 6408 6409 const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32); 6410 const uint32_t indexSize = hasIndex16 ? 2 : 4; 6411 6412 numIndices = UINT32_MAX == draw.m_numIndices 6413 ? ib.m_size / indexSize 6414 : draw.m_numIndices 6415 ; 6416 6417 vkCmdBindIndexBuffer(m_commandBuffer 6418 , ib.m_buffer 6419 , 0 6420 , hasIndex16 6421 ? VK_INDEX_TYPE_UINT16 6422 : VK_INDEX_TYPE_UINT32 6423 ); 6424 vkCmdDrawIndexed(m_commandBuffer 6425 , numIndices 6426 , draw.m_numInstances 6427 , draw.m_startIndex 6428 , draw.m_stream[0].m_startVertex 6429 , 0 6430 ); 6431 } 6432 6433 uint32_t numPrimsSubmitted = numIndices / prim.m_div - prim.m_sub; 6434 uint32_t numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; 6435 6436 statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted; 6437 statsNumPrimsRendered[primIndex] += numPrimsRendered; 6438 statsNumInstances[primIndex] += draw.m_numInstances; 6439 statsNumIndices += numIndices; 6440 6441 if (hasOcclusionQuery) 6442 { 6443 // m_occlusionQuery.begin(m_commandList, _render, draw.m_occlusionQuery); 6444 // m_batch.flush(m_commandList); 6445 // m_occlusionQuery.end(m_commandList); 6446 } 6447 } 6448 } 6449 6450 submitBlit(bs, BGFX_CONFIG_MAX_VIEWS); 6451 6452 // m_batch.end(m_commandList); 6453 } 6454 6455 int64_t timeEnd = bx::getHPCounter(); 6456 int64_t frameTime = timeEnd - timeBegin; 6457 6458 static int64_t min = frameTime; 6459 static int64_t max = frameTime; 6460 min = bx::min<int64_t>(min, frameTime); 6461 max = bx::max<int64_t>(max, frameTime); 6462 6463 static uint32_t maxGpuLatency = 0; 6464 static double maxGpuElapsed = 0.0f; 6465 double elapsedGpuMs = 0.0; 6466 BX_UNUSED(maxGpuLatency, maxGpuElapsed, elapsedGpuMs); 6467 6468 static int64_t presentMin = 0; //m_presentElapsed; 6469 static int64_t presentMax = 0; //m_presentElapsed; 6470 BX_UNUSED(presentMin, presentMax); 6471 // presentMin = bx::min<int64_t>(presentMin, m_presentElapsed); 6472 // presentMax = bx::max<int64_t>(presentMax, m_presentElapsed); 6473 6474 // m_gpuTimer.end(m_commandList); 6475 6476 // while (m_gpuTimer.get() ) 6477 // { 6478 // double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); 6479 // elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; 6480 // maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; 6481 // } 6482 // maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); 6483 6484 const int64_t timerFreq = bx::getHPFrequency(); 6485 6486 Stats& perfStats = _render->m_perfStats; 6487 perfStats.cpuTimeBegin = timeBegin; 6488 perfStats.cpuTimeEnd = timeEnd; 6489 perfStats.cpuTimerFreq = timerFreq; 6490 // perfStats.gpuTimeBegin = m_gpuTimer.m_begin; 6491 // perfStats.gpuTimeEnd = m_gpuTimer.m_end; 6492 // perfStats.gpuTimerFreq = m_gpuTimer.m_frequency; 6493 // perfStats.numDraw = statsKeyType[0]; 6494 // perfStats.numCompute = statsKeyType[1]; 6495 perfStats.numBlit = _render->m_numBlitItems; 6496 // perfStats.maxGpuLatency = maxGpuLatency; 6497 bx::memCopy(perfStats.numPrims, statsNumPrimsRendered, sizeof(perfStats.numPrims) ); 6498 perfStats.gpuMemoryMax = -INT64_MAX; 6499 perfStats.gpuMemoryUsed = -INT64_MAX; 6500 6501 if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) 6502 { 6503 // PIX_BEGINEVENT(toRgba8(0x40, 0x40, 0x40, 0xff), L"debugstats"); 6504 6505 // m_needPresent = true; 6506 TextVideoMem& tvm = m_textVideoMem; 6507 6508 static int64_t next = timeEnd; 6509 6510 if (timeEnd >= next) 6511 { 6512 next = timeEnd + timerFreq; 6513 6514 double freq = double(timerFreq); 6515 double toMs = 1000.0 / freq; 6516 6517 tvm.clear(); 6518 uint16_t pos = 0; 6519 tvm.printf(0, pos++, BGFX_CONFIG_DEBUG ? 0x8c : 0x8f 6520 , " %s / " BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME " " 6521 , getRendererName() 6522 ); 6523 6524 const VkPhysicalDeviceProperties& pdp = m_deviceProperties; 6525 tvm.printf(0, pos++, 0x8f, " Device: %s (%s)" 6526 , pdp.deviceName 6527 , getName(pdp.deviceType) 6528 ); 6529 6530 if (s_extension[Extension::EXT_memory_budget].m_supported) 6531 { 6532 VkPhysicalDeviceMemoryBudgetPropertiesEXT dmbp; 6533 dmbp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; 6534 dmbp.pNext = NULL; 6535 6536 VkPhysicalDeviceMemoryProperties2 pdmp2; 6537 pdmp2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; 6538 pdmp2.pNext = &dmbp; 6539 6540 vkGetPhysicalDeviceMemoryProperties2KHR(m_physicalDevice, &pdmp2); 6541 6542 for (uint32_t ii = 0; ii < VK_MAX_MEMORY_HEAPS; ++ii) 6543 { 6544 if (dmbp.heapBudget[ii] == 0) 6545 { 6546 continue; 6547 } 6548 6549 char budget[16]; 6550 bx::prettify(budget, BX_COUNTOF(budget), dmbp.heapBudget[ii]); 6551 6552 char usage[16]; 6553 bx::prettify(usage, BX_COUNTOF(usage), dmbp.heapUsage[ii]); 6554 6555 tvm.printf(0, pos++, 0x8f, " Memory %d - Budget: %12s, Usage: %12s" 6556 , ii 6557 , budget 6558 , usage 6559 ); 6560 } 6561 } 6562 6563 pos = 10; 6564 tvm.printf(10, pos++, 0x8b, " Frame: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS " 6565 , double(frameTime)*toMs 6566 , double(min)*toMs 6567 , double(max)*toMs 6568 , freq/frameTime 6569 ); 6570 // tvm.printf(10, pos++, 0x8b, " Present: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] " 6571 // , double(m_presentElapsed)*toMs 6572 // , double(presentMin)*toMs 6573 // , double(presentMax)*toMs 6574 // ); 6575 6576 const uint32_t msaa = (m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT; 6577 tvm.printf(10, pos++, 0x8b, " Reset flags: [%c] vsync, [%c] MSAAx%d, [%c] MaxAnisotropy " 6578 , !!(m_resolution.reset&BGFX_RESET_VSYNC) ? '\xfe' : ' ' 6579 , 0 != msaa ? '\xfe' : ' ' 6580 , 1<<msaa 6581 , !!(m_resolution.reset&BGFX_RESET_MAXANISOTROPY) ? '\xfe' : ' ' 6582 ); 6583 6584 double elapsedCpuMs = double(frameTime)*toMs; 6585 tvm.printf(10, pos++, 0x8b, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] " 6586 , _render->m_numRenderItems 6587 , statsKeyType[0] 6588 , statsKeyType[1] 6589 , elapsedCpuMs 6590 ); 6591 6592 for (uint32_t ii = 0; ii < Topology::Count; ++ii) 6593 { 6594 tvm.printf(10, pos++, 0x8b, " %9s: %7d (#inst: %5d), submitted: %7d " 6595 , getName(Topology::Enum(ii) ) 6596 , statsNumPrimsRendered[ii] 6597 , statsNumInstances[ii] 6598 , statsNumPrimsSubmitted[ii] 6599 ); 6600 } 6601 6602 // tvm.printf(10, pos++, 0x8b, " Batch: %7dx%d indirect, %7d immediate " 6603 // , m_batch.m_stats.m_numIndirect[BatchD3D12::Draw] 6604 // , m_batch.m_maxDrawPerBatch 6605 // , m_batch.m_stats.m_numImmediate[BatchD3D12::Draw] 6606 // ); 6607 6608 // tvm.printf(10, pos++, 0x8b, " %7dx%d indirect, %7d immediate " 6609 // , m_batch.m_stats.m_numIndirect[BatchD3D12::DrawIndexed] 6610 // , m_batch.m_maxDrawPerBatch 6611 // , m_batch.m_stats.m_numImmediate[BatchD3D12::DrawIndexed] 6612 // ); 6613 6614 if (NULL != m_renderDocDll) 6615 { 6616 tvm.printf(tvm.m_width-27, 0, 0x4f, " [F11 - RenderDoc capture] "); 6617 } 6618 6619 tvm.printf(10, pos++, 0x8b, " Indices: %7d ", statsNumIndices); 6620 // tvm.printf(10, pos++, 0x8b, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); 6621 tvm.printf(10, pos++, 0x8b, " DVB size: %7d ", _render->m_vboffset); 6622 tvm.printf(10, pos++, 0x8b, " DIB size: %7d ", _render->m_iboffset); 6623 6624 pos++; 6625 tvm.printf(10, pos++, 0x8b, " State cache: "); 6626 tvm.printf(10, pos++, 0x8b, " PSO | DSL | DS | Queued "); 6627 tvm.printf(10, pos++, 0x8b, " %6d | %6d | %6d | %6d " 6628 , m_pipelineStateCache.getCount() 6629 , m_descriptorSetLayoutCache.getCount() 6630 , scratchBuffer.m_currentDs 6631 // , m_cmd.m_control.available() 6632 ); 6633 pos++; 6634 6635 double captureMs = double(captureElapsed)*toMs; 6636 tvm.printf(10, pos++, 0x8b, " Capture: %7.4f [ms] ", captureMs); 6637 6638 uint8_t attr[2] = { 0x8c, 0x8a }; 6639 uint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender; 6640 6641 tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %7.4f [ms] ", _render->m_waitSubmit*toMs); 6642 tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %7.4f [ms] ", _render->m_waitRender*toMs); 6643 6644 min = frameTime; 6645 max = frameTime; 6646 // presentMin = m_presentElapsed; 6647 // presentMax = m_presentElapsed; 6648 } 6649 6650 blit(this, _textVideoMemBlitter, tvm); 6651 6652 // PIX_ENDEVENT(); 6653 } 6654 else if (_render->m_debug & BGFX_DEBUG_TEXT) 6655 { 6656 // PIX_BEGINEVENT(toRgba8(0x40, 0x40, 0x40, 0xff), L"debugtext"); 6657 6658 blit(this, _textVideoMemBlitter, _render->m_textVideoMem); 6659 6660 // PIX_ENDEVENT(); 6661 } 6662 6663 VkMappedMemoryRange range; 6664 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 6665 range.pNext = NULL; 6666 range.memory = scratchBuffer.m_deviceMem; 6667 range.offset = 0; 6668 range.size = scratchBuffer.m_pos; 6669 vkFlushMappedMemoryRanges(m_device, 1, &range); 6670 6671 if (beginRenderPass) 6672 { 6673 vkCmdEndRenderPass(m_commandBuffer); 6674 beginRenderPass = false; 6675 6676 if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) && s_extension[Extension::EXT_debug_utils].m_supported ) 6677 { 6678 vkCmdEndDebugUtilsLabelEXT(m_commandBuffer); 6679 } 6680 } 6681 6682 setImageMemoryBarrier(m_commandBuffer 6683 , m_backBufferColorImage[m_backBufferColorIdx] 6684 , VK_IMAGE_ASPECT_COLOR_BIT 6685 , m_backBufferColorImageLayout[m_backBufferColorIdx] 6686 , VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 6687 , 1, 1); 6688 m_backBufferColorImageLayout[m_backBufferColorIdx] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 6689 6690 VK_CHECK(vkEndCommandBuffer(m_commandBuffer) ); 6691 6692 kick(renderWait); //, m_presentDone[m_backBufferColorIdx]); 6693 finishAll(); 6694 6695 VK_CHECK(vkResetCommandPool(m_device, m_commandPool, 0) ); 6696 } 6697 6698 } /* namespace vk */ } // namespace bgfx 6699 6700 #else 6701 6702 namespace bgfx { namespace vk 6703 { rendererCreate(const Init & _init)6704 RendererContextI* rendererCreate(const Init& _init) 6705 { 6706 BX_UNUSED(_init); 6707 return NULL; 6708 } 6709 rendererDestroy()6710 void rendererDestroy() 6711 { 6712 } 6713 } /* namespace vk */ } // namespace bgfx 6714 6715 #endif // BGFX_CONFIG_RENDERER_VULKAN 6716