355 void initGpuTiming();
357 void writeGpuTimestampBegin();
359 void writeGpuTimestampEnd();
361 void readGpuFrameTiming();
364 bool gpuTimingAvailable()
const override;
366 float gpuFrameMs()
const override;
369 std::string getBackendName()
const override;
371 bool supportsRuntimeGlslCompilation()
const override;
374 void initWithWindow(
void *nativeWindow)
override;
380 void present()
override;
384 void onNativeWindowDestroyed()
override;
390 ensurePresentCaptureHook();
394 if (vsyncEnabled ==
enabled)
return;
398 markSwapchainDirty();
402 const int raw = samples > 1 ? samples : 0;
403 if (raw == msaaSamples)
return;
410 void setViewportSize(
int width,
int height,
int pixelwidth,
int pixelheight)
override;
431 void syncMaterialTable();
443 return gpuDrivenCaps_.gpuDrivenAvailable();
448 void drawDeferredLighting()
override;
451 return gpuDrivenEnabled_ && gpuDrivenCaps_.gpuDrivenAvailable();
456 uint32_t gpuDrivenMeshRecord(
Mesh *
mesh)
override;
460 return materialTableGetOrCreate(
material);
467 uint32_t gpuDrivenReflectionProbeSlot(
Texture *cubemap)
override;
475 Texture *getSceneLinearDepthTexture()
override;
480 bool canSubmitGpuParticles()
const override;
499 uint32_t debugBindlessIndex(
Texture *tex)
const;
501 uint32_t debugMeshRecordIndex(
Mesh *
mesh)
const;
505 void waitForSharedGpuResources();
508 return gpuDrivenEnabled_ && gpuDrivenCaps_.gpuDrivenCullAvailable();
515 void gpuDrivenCullEmit(
const glm::mat4 &
viewProj,
const glm::vec3 &
eye,
float fovYDeg,
516 float nearZ,
float farZ);
518 void gpuDrivenOpenScenePass();
520 void gpuDrivenDrawOpaque();
522 bool gpuDrivenResolveWanted()
const override;
524 void gpuDrivenRecordVisPass()
override;
526 void gpuDrivenResolve()
override;
530 uint32_t gpuDrivenVgAssetId(
Mesh *
mesh)
const override;
532 bool gpuDrivenVgAttachToMesh(
Mesh *
mesh, uint32_t vgAssetId)
override;
534 bool gpuDrivenVgSetInstance(uint32_t vgAssetId,
const glm::mat4 &
model,
535 uint32_t materialId)
override;
537 void gpuDrivenVgComputeSection(
const glm::mat4 &
viewProj,
const glm::vec3 &
eye,
538 float fovYDeg,
float nearZ,
float farZ)
override;
540 uint32_t debugGpuDrivenVgVisibleCount()
const;
542 uint32_t debugGpuDrivenVisibleCount()
const;
544 uint32_t debugGpuDrivenCulledDrawCount()
const;
547 void drawSolidRect(
float x,
float y,
float w,
float h,
const Color &
color,
552 void drawSolidRectRotated(
float cx,
float cy,
float w,
float h,
float degrees,
561 bool repeatV =
false)
override;
567 std::span<const uint8_t> rgba)
override;
570 std::span<const uint16_t> rgbaHalf)
override;
573 std::span<const uint8_t> rgba)
override;
575 Texture *newCubemap(
int faceSize,
const uint8_t *rgbaFaces)
override;
577 Texture *newCubemap(
int faceSize,
const uint8_t *rgbaFaces,
581 Texture *newHDRCubemap(
int faceSize)
override;
586 bool copyHDRCanvasesToCubemap(
Canvas *
const *sources,
int faceCount,
590 bool filterHDRReflectionCubemap(
Texture *cubemap,
int sampleCount = 64)
override;
600 float getMaxAnisotropy()
const override;
602 Texture *newTextureFromFile(
const std::string &filename)
override;
604 bool reloadTextureFromFile(
const std::string &filename)
override;
608 bool releaseTexture(
Texture *texture)
override;
611 const uint8_t *rgba)
override;
617 int height, std::span<const std::uint8_t> rgba,
618 std::size_t bytesPerRow = 0)
override;
621 Texture *texture, std::span<const TextureRegionUpload> regions)
override;
625 bool replaceTexturePixelsRGBA(
Texture *tex,
int w,
int h,
const uint8_t *rgba);
627 void drawTexturedRect(
Texture *texture,
float x,
float y,
float w,
float h,
const Color &
color)
override;
632 void drawTexturedRectUV(
Texture *texture,
float x,
float y,
float w,
float h,
float u0,
float v0,
633 float u1,
float v1,
const Color &
color)
override;
636 float h,
float u0,
float v0,
float u1,
float v1,
641 float w,
float h,
float degrees,
float u0,
float v0,
643 bool rotatedUV =
false,
661 SceneColorDistortionStatus drawSceneColorDistortionUVRotated(
663 float v0,
float u1,
float v1,
float strengthPixels,
float opacity,
664 bool rotatedUV =
false)
override;
675 Shader *newShaderFromSpv(
const std::vector<uint32_t> &vertSpv,
676 const std::vector<uint32_t> &fragSpv)
override;
678 Shader *newShaderFromSpvFile(
const std::string &vertPath,
const std::string &fragPath)
override;
680 Shader *newShader(
const std::string &vertGlsl,
const std::string &fragGlsl)
override;
682 Shader *newMeshShaderFromSpv(
const std::vector<uint32_t> &vertSpv,
683 const std::vector<uint32_t> &fragSpv)
override;
685 Shader *newMeshShaderFromWgsl(
const std::string &vertWgsl,
686 const std::string &fragWgsl)
override;
688 Shader *newShaderFromWgsl(
const std::string &vertWgsl,
689 const std::string &fragWgsl)
override;
693 const std::vector<uint32_t> &fragSpv)
override;
696 const std::vector<uint32_t> &fragSpv,
701 const std::string &fragWgsl)
override;
705 const std::string &fragGlsl)
override;
707 Shader *newMeshShader(
const std::string &vertGlsl,
const std::string &fragGlsl)
override;
709 Shader *newHairShaderFromSpv(
const std::vector<uint32_t> &vertSpv,
710 const std::vector<uint32_t> &fragSpv)
override;
712 Shader *newHairShaderFromWgsl(
const std::string &vertWgsl,
713 const std::string &fragWgsl)
override;
722 Mesh *newMeshFromAssimp(const ::aiMesh &
mesh)
override;
724 Mesh *newMeshFromAssimp(const ::aiMesh &
mesh,
const aiMatrix4x4 &worldTransform)
override;
726 Mesh *newMeshFromArrays(
const float *posXYZ,
const float *nrmXYZ,
const float *uvST,
735 Mesh *newMeshFromArraysColored(
const float *posXYZ,
const float *nrmXYZ,
const float *uvST,
739 [[nodiscard]] std::optional<eve::graphics::MeshBackendDescriptor> describeMesh(
Mesh *
mesh)
const override;
740 bool bakeMeshMorph(
Mesh *
mesh)
override;
742 bool updateMeshVertices(
Mesh *
mesh,
const float *posXYZ,
const float *nrmXYZ,
const float *uvST,
745 bool setMeshSkinningData(
Mesh *
mesh,
const uint16_t *joints4,
const float *weights4,
748 Mesh *newMeshSphere(
int slices = 32,
int stacks = 16)
override;
750 Mesh *newMeshCylinder(
int slices = 32,
int stacks = 1,
bool caps =
true)
override;
752 bool releaseMesh(
Mesh *
mesh)
override;
754 void begin3DFrame()
override;
756 void begin3DFrameToCanvas(
Canvas *canvas)
override;
758 void end3DFrameToCanvas()
override;
763 return lastOffscreen3DGpuDurationMs;
766 void setMesh3DViewProj(
const glm::mat4 &
viewProj)
override;
768 void setMesh3DView(
const glm::mat4 &
view)
override;
770 void setMesh3DClip(
float nearZ,
float farZ)
override;
772 Texture *getSceneColorTexture()
override;
775 const std::vector<eve::graphics::Graphics::EntityIdDraw> &draws,
const glm::mat4 &
viewProj,
780 image::ImageData *readDecalLayerToImageData(
const std::string &attachment)
override;
789 std::uint32_t
count)
override;
791 void drawVoxelFaceInstances(
const uint32_t *packed,
int count,
float originX,
float originY,
float originZ,
792 const std::string &faceDir,
Texture *atlas,
int tilesPerRow = 16,
793 const uint32_t *ao =
nullptr)
override;
797 void setMesh3DPackedNormalMask(
bool enabled)
override;
801 void setMesh3DVirtualTexture(
bool enabled,
int pageCountX,
int pageCountY,
802 int atlasSlotsX,
int atlasSlotsY,
803 float borderFraction)
override;
817 const std::string &alphaTechnique =
"cutoff")
override;
819 void setMesh3DTexCellBomb(
float cellScale,
float strength,
float rotAmount = 1.f)
override;
821 void setMesh3DParallax(
float scale,
float minLayers = 8.f,
float maxLayers = 32.f)
override;
823 void setMesh3DLodDither(
float weight,
bool reverse,
bool enabled)
override;
827 void setCloudShadows(
float strength,
float worldCell,
float time,
float windSpeed,
float windAngle,
float coverage,
832 void setMesh3DClusteredActive(
bool active)
override;
836 void setMesh3DLight(
const glm::vec3 &
dir,
const glm::vec3 &
color)
override;
838 void setMesh3DCameraPos(
const glm::vec3 &
eye)
override;
840 void setMesh3DEnv(
Texture *cube,
float intensity)
override;
842 void setMesh3DEnvProbe(
const glm::vec3 &
center,
const glm::vec3 &extent)
override;
846 [[nodiscard]]
Result<void> setSceneToneMapping(SceneToneMapping mode)
override;
850 [[nodiscard]]
Result<void> setDisplayOutputMode(DisplayOutputMode mode)
override;
852 [[nodiscard]]
Result<void> setDisplayHdrCalibration(
float paperWhiteNits,
float peakNits)
override;
856 [[nodiscard]]
Result<void> setScenePhotographicVignette(
float intensity)
override;
860 void setSceneExposure(
float exposure)
override { sceneExposure = std::max(exposure, 0.f); }
865 sceneColorFilter = glm::max(
color, glm::vec3(0.f));
871 const glm::vec3& gain)
override {
873 sceneInverseGamma = glm::max(inverseGamma, glm::vec3(0.001F));
884 float lensDistortion,
float lensScale)
override {
885 sceneTransitionVignette = std::clamp(vignette, 0.0F, 1.0F);
886 sceneTransitionVignetteSmoothness = std::clamp(vignetteSmoothness, 0.01F, 1.0F);
887 sceneTransitionLensDistortion = std::clamp(lensDistortion, 0.0F, 1.0F);
888 sceneTransitionLensScale = std::clamp(lensScale, 0.01F, 5.0F);
901 sceneAutoExposureMinEV = minEV;
902 sceneAutoExposureMaxEV = maxEV;
912 sceneBloomIntensity = intensity;
913 sceneBloomThreshold = threshold;
921 float farZ)
override {
922 sceneDofFocusDistance = focusDistance;
923 sceneDofMaxBlurPx = maxBlurPx;
924 sceneDofFocusRange = focusRange;
925 sceneDofNearZ = nearZ;
939 void setMesh3DShadows(
const ShadowUpload &upload)
override;
941 void setMesh3DShadowReceive(
bool receive)
override;
945 void beginShadowPass(
int cascadeIndex)
override;
947 void drawMeshShadow(
Mesh *
mesh,
const glm::mat4 &lightMVP,
bool doubleSided =
true)
override;
953 void endShadowPass()
override;
956 void beginGBufferPass(
int width,
int height)
override;
958 void drawMeshGBuffer(
Mesh *
mesh,
const glm::mat4 &
mvp,
const glm::mat4 &
model,
float nearZ,
959 float farZ,
Texture *
albedo =
nullptr,
float tintR = 1.f,
float tintG = 1.f,
960 float tintB = 1.f,
float motionX = 0.f,
float motionY = 0.f,
963 void drawMeshGBufferAlpha(
Mesh *
mesh,
const glm::mat4 &
mvp,
const glm::mat4 &
model,
float nearZ,
965 float tintG = 1.f,
float tintB = 1.f,
float motionX = 0.f,
966 float motionY = 0.f,
float roughness = 0.45f,
969 void endGBufferPass()
override;
974 void beginDecalPass(
int width,
int height)
override;
976 void setDecalCamera(
const glm::mat4 &
viewProj,
float nearZ,
float farZ)
override;
979 const float uvRect[4],
float fade,
float normalStrength,
float roughnessStrength,
980 float metalStrength,
float emissiveStrength,
int blendMode = 0,
981 int projectionMode = 0,
float blendSharpness = 4.f,
982 float parallaxScale = 0.f,
float parallaxMinLayers = 8.f,
983 float parallaxMaxLayers = 24.f,
float edgeFadeWidth = 0.06f)
override;
985 void endDecalPass()
override;
993 void setCanvas(
Canvas *canvas)
override;
995 bool isCanvasActive()
const override;
997 Canvas *getCanvas()
const override;
1000 Texture *getTexture()
override;
1007 void draw(
Canvas *C,
const glm::mat4 &matrix)
const override;
1009 void clear(std::optional<Color>
color, std::optional<int> stencil, std::optional<double>
depth)
override;
1011 Color getPixel(
int x,
int y)
override;
1034 return hdr ? hdrOffscreenRenderPass : offscreenRenderPass;
1038 return hdr ? hdrOffscreen3DRenderPass : offscreen3DRenderPass;
1051 createUiColorResources(
int(swapchain.extent.width),
int(swapchain.extent.height));
1065 void drawUiTextureRects(
void* commandBuffer,
const std::vector<UiTextureDraw>& draws, std::size_t bufferOffset = 0);
1088 struct GpuParticleDrawRequest;
1091 struct Mesh3dFrameSlots;
1092 struct Mesh3dClusteredFrameSlots;
1095 struct DecalSetKeyHash;
1097 void createSwapchainAndPipeline();
1098 void applyPreferredSwapchainFormats(vkb::SwapchainBuilder &builder);
1099 void createTexturedPipeline();
1100 void createLit2DPipeline();
1101 void createGpuParticlePipelines();
1102 void destroyGpuParticleResources();
1103 void recordGpuParticleCompute(vk::CommandBuffer cb);
1104 void drawGpuParticleRequest(vk::CommandBuffer cb,
const GpuParticleDrawRequest&
request);
1108 std::optional<PbrSurface> pbrSurface_;
1109 void destroyPbrResources();
1111 void createMesh3DPipeline();
1112 void createMesh3DClusteredPipeline();
1113 void createDeferredLightingPipeline();
1114 void destroyDeferredLightingResources();
1115 void createVoxelRectPipeline();
1116 vk::Pipeline buildVoxelRectPipeline(
const vkb::BuiltRenderPass &rp,
1117 vk::SampleCountFlagBits samples);
1118 void destroyVoxelRectResources();
1119 void ensureVoxelUnitQuad();
1120 vkb::BoundSet voxelRectSetFor(
GpuTexture *gpuTex);
1121 void createShadowResources();
1122 void destroyShadowResources();
1123 void createGBufferResources(
int width,
int height);
1124 void destroyGBufferResources();
1126 void destroyDecalResources();
1127 void recordDecalPass();
1128 void recordDecalPassInto(vk::CommandBuffer cb, DecalSlot &slot, GBufferSlot &gslot);
1129 void ensureDecalUnitBox();
1130 void ensureDecalPlaceholders();
1133 DecalSlot *currentDecalSlot();
1134 void createSceneColorResources(
int width,
int height);
1135 void destroySceneColorResources();
1136 void createUiColorResources(
int width,
int height);
1137 void destroyUiColorTargets();
1138 void destroyUiColorResources();
1139 void queueUiResolve();
1141 bool renderUiOverlayPass();
1143 void recordDeferredFrameGraph();
1144 void dropPendingOffscreenPasses();
1146 bool beginSwapchainRenderPass();
1148 void beginSwapchainColorPass();
1149 bool beginSceneColorRenderPass();
1150 void endSceneColorRenderPass();
1151 void ensureOffscreen3DResources();
1152 void destroyOffscreen3DResources();
1153 void queueSceneColorResolve();
1154 void materializeSceneColorResolve();
1155 void ensureClusteredBuffers(
size_t lightsBytes,
size_t tableBytes,
size_t indicesBytes);
1157 void ensureMesh3dStrides();
1158 void ensureMesh3dRing(Mesh3dFrameSlots &fslots);
1159 size_t uploadSkinPalette(
Mesh*
mesh, Mesh3dFrameSlots& fslots);
1160 vk::DescriptorSet skinPassSetFor(
GpuTexture *
albedo, Mesh3dFrameSlots &fslots);
1162 const glm::mat4 &
model,
const glm::vec4 &
clip,
1163 vk::DescriptorSet &set, uint32_t &uboOffset);
1164 void ensureMesh3dClusteredRing(Mesh3dClusteredFrameSlots &fslots);
1169 Mesh3dClusteredFrameSlots &fslots);
1170 void ensureOffscreenPipelines();
1171 void ensureHdrOffscreenPipelines();
1175 void destroyPresentGraphicsPipelines();
1177 void rebuildGpuParticleDrawPipelines(
const vkb::BuiltRenderPass &
target);
1179 void ensureHdrGpuParticleDrawPipelines();
1181 void ensurePresentComposeResources(
int width,
int height);
1182 void destroyPresentComposeResources();
1183 struct PresentComposeSlot;
1191 PresentComposeSlot *currentPresentComposeSlot();
1193 bool beginPresentComposePass();
1194 void endPresentComposePass();
1196 void encodePresentComposeToSwapchain(vk::CommandBuffer cb);
1197 vk::Pipeline createTexturedStylePipeline(
const std::vector<uint32_t> &
vert,
const std::vector<uint32_t> &
frag,
1198 const vkb::BuiltRenderPass &rp, vk::PipelineLayout
layout,
1200 vk::SampleCountFlagBits samples = vk::SampleCountFlagBits::e1);
1201 vk::Pipeline createMesh3DStylePipeline(
const std::vector<uint32_t> &
vert,
const std::vector<uint32_t> &
frag,
1202 vk::PipelineLayout
layout,
const vkb::BuiltRenderPass &rp,
1203 vk::SampleCountFlagBits samples,
BlendMode blend = BlendMode::Opaque,
1208 static constexpr size_t kMesh3DPipelineVariants = 20;
1210 static constexpr size_t kPrimitive3DPipelineVariants = 45;
1213 vk::Pipeline createMesh3DXrayPipeline(
const std::vector<uint32_t> &
vert,
1214 const std::vector<uint32_t> &
frag,
1215 vk::PipelineLayout
layout,
1216 const vkb::BuiltRenderPass &rp,
1217 vk::SampleCountFlagBits samples);
1218 vk::Pipeline createMesh3DHairPipeline(
const std::vector<uint32_t> &
vert,
1219 const std::vector<uint32_t> &
frag,
1220 vk::PipelineLayout
layout,
1221 const vkb::BuiltRenderPass &rp,
1222 vk::SampleCountFlagBits samples);
1224 void ensureScenePassPipelines(
const vkb::BuiltRenderPass &
target,
1225 vk::SampleCountFlagBits samples);
1226 void rebuildPrimitive3DPipelines(
const vkb::BuiltRenderPass &
target, vk::SampleCountFlagBits samples);
1227 void buildPrimitive3DPipelines(
const vkb::BuiltRenderPass &
target, vk::SampleCountFlagBits samples,
1228 std::array<vk::Pipeline, kPrimitive3DPipelineVariants> &pipelines);
1230 int clampMsaaSamples(
int requested)
const;
1232 const vkb::BuiltRenderPass &activeScenePass()
const {
1233 return sceneColorRenderPass ? sceneColorRenderPass : renderpass;
1236 vk::SampleCountFlagBits activeSceneSamples()
const {
1237 return sceneColorRenderPass ? sceneColorSamples : vk::SampleCountFlagBits::e1;
1239 void destroySwapchainResources();
1241 void flushToSwapchain();
1242 void flushToOffscreen(OffscreenCanvas *canvas);
1243 void abortOpen3DFrame();
1244 void noteSolidOverlay(uint32_t batchIndex);
1245 void noteTexturedOverlay(Texture *tex, uint32_t batchIndex);
1246 void noteLitOverlay(uint32_t batchIndex);
1247 void clear2DBatches();
1248 void drawLitBatches(vk::CommandBuffer cb,
int viewW,
int viewH, std::vector<LitBatch> &batches,
1249 std::vector<vkb::HostVertexBuffer> &texBufs,
size_t &texBufIndex,
bool offscreen,
1251 vkb::BoundSet lit2dSetFor(GpuTexture *
albedo, GpuTexture *
normal,
bool offscreen);
1252 vkb::BoundSet post2SetFor(GpuTexture *
color, GpuTexture *
depth,
1253 GpuTexture *motion =
nullptr, GpuTexture *extra =
nullptr,
1254 GpuTexture *specular =
nullptr);
1255 void ensureFlatNormalTexture();
1257 void ensureReadbackSlots();
1259 bool recordSwapchainReadback(vk::CommandBuffer cb);
1261 void syncReadbackCpu();
1263 void destroyReadbackResources();
1264 void ensurePresentCaptureHook();
1265 vkb::BoundSet mesh3dSetFor(GpuTexture *gpuTex, GpuTexture *normalTex, GpuTexture *envTex,
1266 GpuTexture *heightTex, GpuTexture *depthTex, GpuTexture *sceneColorTex,
1267 GpuTexture *decalAlbedo, GpuTexture *decalNormal,
1268 GpuTexture *decalParams, Mesh3dFrameSlots &fslots);
1269 void ensureDefaultEnvCubemap();
1270 void ensureFlatNormalTexture3D();
1271 void ensureFlatHeightTexture3D();
1272 vk::Sampler createVkSampler(
const TextureSampler &
sampler, uint32_t mipLevels)
const;
1273 void writeCombinedImageDescriptor(GpuTexture *gpu);
1280 void createInstanceAndDevice(
const std::vector<const char *> &instanceExtensions,
1281 void *nativeWindow, vk::SurfaceKHR *surfaceOut);
1283 bool rebuildSwapchainIfNeeded();
1285 bool beginPresentCommandBuffer();
1287 bool initialized =
false;
1288 bool headless_ =
false;
1289 bool hasPresentedFrame =
false;
1290 float maxSamplerAnisotropy = 1.f;
1291 std::vector<uint8_t> lastFrameRgba;
1296 struct ScreenReadbackSlot {
1297 vkb::GenericBuffer staging;
1298 void *mapped =
nullptr;
1300 std::vector<ScreenReadbackSlot> screenReadbackSlots;
1301 size_t screenReadbackBytes = 0;
1302 size_t readbackWriteSlot = 0;
1303 bool readbackReady =
false;
1304 bool readbackCpuSynced =
false;
1305 bool readbackBgra =
false;
1306 Canvas *activeCanvas =
nullptr;
1307 bool swapchainDirty =
false;
1308 void markSwapchainDirty()
override { swapchainDirty =
true; }
1311 std::atomic<bool> surfaceNeedsRecreate{
false};
1312 void recreateSurfaceForResume();
1315 bool isRenderSurfaceReady()
const;
1319 bool isRenderSurfaceStable();
1320 int pendingSurfaceW = 0;
1321 int pendingSurfaceH = 0;
1322 int surfaceStableFrames = 0;
1323 void *sdlWindow =
nullptr;
1324 vk::SurfaceKHR surface;
1327#if defined(VKB_ENABLE_VMA)
1330 VmaAllocatorOwner vmaAllocatorOwner_;
1333 vkb::Swapchain swapchain;
1334 vkb::BuiltRenderPass renderpass;
1336 vk::Pipeline pipeline;
1337 vk::PipelineLayout pipelineLayout;
1338 vk::Pipeline solidAlphaPipeline;
1339 vk::Pipeline additiveSolidPipeline;
1340 vk::Pipeline premultipliedSolidPipeline;
1341 vk::Pipeline multiplySolidPipeline;
1343 vk::DescriptorSetLayout texSetLayout;
1344 vk::UniqueDescriptorSetLayout texSetLayoutUnique;
1345 vk::DescriptorPool descriptorPool;
1346 vk::Pipeline texPipeline;
1347 vk::Pipeline additiveTexPipeline;
1348 vk::Pipeline premultipliedTexPipeline;
1349 vk::Pipeline multiplyTexPipeline;
1350 vk::Pipeline opaqueTexPipeline;
1351 vk::Pipeline particleDistortionPipeline;
1352 vk::Pipeline sceneTonemapPipeline;
1354 vk::Format presentAttachmentFormat_ = vk::Format::eUndefined;
1355 SceneToneMapping sceneToneMapping_ = SceneToneMapping::Aces;
1356 vk::SurfaceFormatKHR selectedSurfaceFormat_{vk::Format::eB8G8R8A8Unorm,
1357 vk::ColorSpaceKHR::eSrgbNonlinear};
1358 float sceneExposure = 1.f;
1359 glm::vec3 sceneColorFilter{1.f};
1360 glm::vec3 sceneLift{0.f};
1361 glm::vec3 sceneInverseGamma{1.f};
1362 glm::vec3 sceneGain{1.f};
1363 float scenePhotographicVignette_ = 0.0F;
1364 float sceneTransitionVignette = 0.0F;
1365 float sceneTransitionVignetteSmoothness = 0.2F;
1366 float sceneTransitionLensDistortion = 0.0F;
1367 float sceneTransitionLensScale = 1.0F;
1368 bool sceneAutoExposure =
false;
1369 float sceneAutoExposureMinEV = -8.f;
1370 float sceneAutoExposureMaxEV = 8.f;
1371 float sceneBloomIntensity = 0.f;
1372 float sceneBloomThreshold = 1.f;
1373 float sceneDofFocusDistance = 0.f;
1374 float sceneDofMaxBlurPx = 0.f;
1375 float sceneDofFocusRange = 8.f;
1376 float sceneDofNearZ = 0.1f;
1377 float sceneDofFarZ = 100.f;
1378 vk::PipelineLayout texPipelineLayout;
1379 vk::PipelineLayout shaderPipelineLayout;
1380 vk::CommandPool uploadPool;
1382 vkb::BuiltRenderPass offscreenRenderPass;
1383 vkb::BuiltRenderPass hdrOffscreenRenderPass;
1384 vk::Pipeline offscreenSolidPipeline;
1385 vk::Pipeline offscreenSolidAlphaPipeline;
1386 vk::Pipeline offscreenAdditiveSolidPipeline;
1387 vk::Pipeline offscreenPremultipliedSolidPipeline;
1388 vk::Pipeline offscreenMultiplySolidPipeline;
1389 vk::Pipeline offscreenTexPipeline;
1390 vk::Pipeline offscreenAdditiveTexPipeline;
1391 vk::Pipeline offscreenPremultipliedTexPipeline;
1392 vk::Pipeline offscreenMultiplyTexPipeline;
1393 vk::Pipeline offscreenOpaqueTexPipeline;
1394 vk::Pipeline hdrOffscreenTexPipeline;
1395 vk::Pipeline hdrOffscreenOpaqueTexPipeline;
1396 vk::Pipeline hdrOffscreenAdditiveTexPipeline;
1397 vk::Pipeline hdrOffscreenPremultipliedTexPipeline;
1398 vk::Pipeline hdrOffscreenMultiplyTexPipeline;
1399 vk::Pipeline hdrOffscreenSolidPipeline;
1400 vk::Pipeline hdrOffscreenSolidAlphaPipeline;
1401 vk::Pipeline hdrOffscreenAdditiveSolidPipeline;
1402 vk::Pipeline hdrOffscreenPremultipliedSolidPipeline;
1403 vk::Pipeline hdrOffscreenMultiplySolidPipeline;
1404 vk::Pipeline hdrOffscreenLitPipeline;
1405 vk::Pipeline hdrOffscreenLitAdditivePipeline;
1406 vk::Pipeline hdrOffscreenLitPremultipliedPipeline;
1407 vk::Pipeline hdrOffscreenLitMultiplyPipeline;
1408 vk::Pipeline hdrOffscreenLitOpaquePipeline;
1409 vk::Pipeline hdrOffscreenTonemapPipeline;
1410 vk::Pipeline hdrOffscreenParticleDistortionPipeline;
1411 vk::Pipeline hdrGpuParticleAlphaPipeline_{};
1412 vk::Pipeline hdrGpuParticleAdditivePipeline_{};
1413 vk::Pipeline hdrGpuParticlePremultipliedPipeline_{};
1414 vk::Pipeline hdrGpuParticleMultiplyPipeline_{};
1415 vk::Pipeline hdrGpuParticleOpaquePipeline_{};
1416 bool presentComposeActive_ =
false;
1418 vk::DescriptorSetLayout mesh3dSetLayout;
1419 vk::UniqueDescriptorSetLayout mesh3dSetLayoutUnique;
1420 vk::PipelineLayout mesh3dPipelineLayout;
1421 vk::PipelineLayout mesh3dShaderPipelineLayout;
1422 vk::Pipeline mesh3dPipeline;
1423 vk::Pipeline mesh3dTransparentPipeline;
1424 std::array<vk::Pipeline, kMesh3DPipelineVariants> mesh3dSurfacePipelines{};
1425 std::array<vk::Pipeline, kPrimitive3DPipelineVariants> primitive3DPipelines{};
1426 std::array<vk::Pipeline, kPrimitive3DPipelineVariants> offscreenPrimitive3DPipelines{};
1427 std::array<vk::Pipeline, kPrimitive3DPipelineVariants> hdrOffscreenPrimitive3DPipelines{};
1428 std::vector<vkb::HostVertexBuffer> offscreenPrimitive3DBufs;
1429 std::size_t offscreenPrimitive3DDrawIndex = 0;
1433 struct Mesh3dSetKey {
1434 GpuTexture *
albedo =
nullptr;
1435 GpuTexture *
normal =
nullptr;
1436 GpuTexture *env =
nullptr;
1437 GpuTexture *reflectionProbe0 =
nullptr;
1438 GpuTexture *reflectionProbe1 =
nullptr;
1439 GpuTexture *
height =
nullptr;
1440 GpuTexture *
depth =
nullptr;
1441 GpuTexture *sceneColor =
nullptr;
1442 GpuTexture *decalAlbedo =
nullptr;
1443 GpuTexture *decalNormal =
nullptr;
1444 GpuTexture *decalParams =
nullptr;
1445 size_t paletteSlot = 0;
1447 bool operator==(
const Mesh3dSetKey &o)
const {
1448 return albedo == o.albedo &&
normal == o.normal && env == o.env && reflectionProbe0 == o.reflectionProbe0 &&
1449 reflectionProbe1 == o.reflectionProbe1 &&
height == o.height &&
depth == o.depth &&
1450 sceneColor == o.sceneColor && decalAlbedo == o.decalAlbedo && decalNormal == o.decalNormal &&
1451 decalParams == o.decalParams && paletteSlot == o.paletteSlot;
1454 struct Mesh3dSetKeyHash {
1456 size_t operator()(
const Mesh3dSetKey &k)
const {
1457 return std::hash<GpuTexture*>()(k.albedo) ^ (std::hash<GpuTexture*>()(k.normal) << 1) ^
1458 (std::hash<GpuTexture*>()(k.env) << 2) ^ (std::hash<GpuTexture*>()(k.height) << 3) ^
1459 (std::hash<GpuTexture*>()(k.reflectionProbe0) << 8) ^
1460 (std::hash<GpuTexture*>()(k.reflectionProbe1) << 9) ^ (std::hash<GpuTexture*>()(k.depth) << 4) ^
1461 (std::hash<GpuTexture*>()(k.sceneColor) << 10) ^ (std::hash<GpuTexture*>()(k.decalAlbedo) << 5) ^
1462 (std::hash<GpuTexture*>()(k.decalNormal) << 6) ^ (std::hash<GpuTexture*>()(k.decalParams) << 7) ^
1472 struct Mesh3dFrameSlots {
1473 vkb::GenericBuffer uboRing;
1474 vkb::GenericBuffer shadowRing;
1476 size_t drawIndex = 0;
1477 size_t lastDrawCount = 0;
1478 std::unordered_map<Mesh3dSetKey, vkb::BoundSet, Mesh3dSetKeyHash> sets;
1479 std::map<std::pair<size_t, GpuTexture*>, vkb::BoundSet> skinSets;
1480 std::vector<vkb::GenericBuffer> palettes;
1481 size_t activePalette = 0;
1483 std::vector<Mesh3dFrameSlots> mesh3dFrameSlots;
1484 Texture *whiteTexture =
nullptr;
1485 Texture *defaultExtrasArray =
nullptr;
1486 Texture *defaultColorsArray =
nullptr;
1487 Texture *defaultVertexArray =
nullptr;
1488 Texture *defaultMotionArray =
nullptr;
1489 Texture *defaultVegetationFadeNoise =
nullptr;
1491 Texture *defaultBindlessCube =
nullptr;
1492 Texture *flatNormalTexture3D =
nullptr;
1493 Texture *flatHeightTexture3D =
nullptr;
1494 Texture *defaultEnvCubemap =
nullptr;
1495 Texture *mesh3dNormalTexture =
nullptr;
1496 Texture *mesh3dHeightTexture =
nullptr;
1497 Texture *mesh3dEnvTexture =
nullptr;
1498 Texture *mesh3dSceneDepthTexture =
nullptr;
1499 Texture *mesh3dSceneColorTexture =
nullptr;
1500 float mesh3dEnvIntensity = 0.f;
1501 glm::vec3 mesh3dEnvProbeCenter{0.f};
1502 glm::vec3 mesh3dEnvProbeExtent{0.f};
1503 ReflectionProbeUpload mesh3dReflectionProbes{};
1504 float mesh3dMetallic = 0.f;
1505 float mesh3dRoughness = 0.45f;
1506 SurfaceMode mesh3dSurfaceMode = SurfaceMode::Opaque;
1507 BlendMode mesh3dSurfaceBlend = BlendMode::Alpha;
1508 bool mesh3dSurfaceDepthWrite =
false;
1509 bool mesh3dSurfaceDoubleSided =
false;
1510 float mesh3dAlphaCutoff = 0.5f;
1511 std::string mesh3dAlphaTechnique =
"cutoff";
1512 glm::vec4 mesh3dLodFade{1.f, 0.f, 0.f, 0.f};
1513 float mesh3dTexBombScale = 4.f;
1514 float mesh3dTexBombStrength = 0.f;
1515 float mesh3dTexBombRot = 1.f;
1516 float mesh3dParallaxScale = 0.f;
1517 float mesh3dParallaxMinLayers = 8.f;
1518 float mesh3dParallaxMaxLayers = 32.f;
1519 glm::vec4 mesh3dVirtualTexture{0.f};
1520 glm::vec4 mesh3dVirtualAtlas{0.f};
1521 Lighting3DPack mesh3dLighting{};
1522 ShadowUpload mesh3dShadows{};
1523 bool mesh3dShadowReceive =
true;
1524 int mesh3dSkinInfluenceLimit = 4;
1527 bool mesh3dClusteredActive =
false;
1528 ClusteredLightingUpload mesh3dClustered{};
1529 vk::DescriptorSetLayout mesh3dClusteredSetLayout;
1530 vk::UniqueDescriptorSetLayout mesh3dClusteredSetLayoutUnique;
1531 vk::PipelineLayout mesh3dClusteredPipelineLayout;
1532 vk::Pipeline mesh3dClusteredPipeline;
1536 struct ClusteredStorage {
1537 vkb::GenericBuffer lightsBuf;
1538 vkb::GenericBuffer tableBuf;
1539 vkb::GenericBuffer indicesBuf;
1540 size_t lightsCap = 0;
1541 size_t tableCap = 0;
1542 size_t indicesCap = 0;
1544 std::vector<ClusteredStorage> clusteredStorages;
1545 struct Mesh3dClusteredFrameSlots {
1546 vkb::GenericBuffer uboRing;
1547 vkb::GenericBuffer shadowRing;
1549 size_t drawIndex = 0;
1550 size_t lastDrawCount = 0;
1551 std::unordered_map<Mesh3dSetKey, vkb::BoundSet, Mesh3dSetKeyHash> sets;
1553 std::vector<Mesh3dClusteredFrameSlots> mesh3dClusteredFrameSlots;
1556 uint32_t mesh3dUboStride = 0;
1557 uint32_t shadowUboStride = 0;
1558 uint32_t mesh3dClusteredUboStride = 0;
1560 vk::Pipeline lastMesh3dPipeline =
nullptr;
1561 vk::Pipeline lastMesh3dClusteredPipeline =
nullptr;
1564 static constexpr uint32_t kAsyncResourceCopies = 2;
1567 GpuDrivenCaps gpuDrivenCaps_{};
1568 RayTracingCaps rayTracingCaps_{};
1569 std::vector<FrameArena> frameArenas_;
1571 vk::UniqueDescriptorSetLayout bindlessSetLayoutUnique_{};
1572 vk::DescriptorSetLayout bindlessSetLayout_ =
nullptr;
1573 vk::DescriptorPool bindlessPool_ =
nullptr;
1580 std::vector<vk::DescriptorSet> bindlessSets_;
1581 std::vector<GpuTexture *> bindlessTextures2D_;
1582 std::vector<uint32_t> bindlessFree2D_;
1583 std::vector<GpuTexture *> bindlessCubemaps_;
1584 std::vector<uint32_t> bindlessFreeCube_;
1586 vkb::GenericBuffer meshTableBuffer_;
1587 std::vector<GpuMeshRecord> meshTableRecords_;
1589 std::vector<GpuMesh *> meshRecordOwners_;
1590 uint32_t meshTableCapacity_ = 0;
1592 vkb::GenericBuffer materialTableBuffer_;
1593 std::vector<GpuMaterialRecord> materialTableRecords_;
1594 std::vector<uint32_t> materialTableFree_;
1595 std::unordered_map<const Material *, uint32_t> materialTableIndex_;
1596 uint32_t materialTableCapacity_ = 0;
1598 uint32_t registerBindlessTexture2D(GpuTexture *tex);
1599 uint32_t registerBindlessTextureCube(GpuTexture *tex);
1600 void unregisterBindlessTexture(GpuTexture *tex);
1601 uint32_t registerMeshRecord(GpuMesh *gpu,
const std::vector<MeshVertex> *
vertices =
nullptr,
1602 const std::vector<uint32_t> *
indices =
nullptr);
1603 void syncMeshTable();
1605 void createBindlessSet();
1607 vk::DescriptorSet bindlessSetForFrame()
const;
1611 struct GpuVertexPool {
1614 vkb::GenericBuffer uvs;
1619 GpuVertexPool gpuVertexPool_;
1620 void ensureGpuVertexPool();
1621 void growGpuVertexPool(uint32_t needVertices, uint32_t needIndices);
1623 void bindGpuVertexPoolBindless();
1624 void appendGpuMeshToPool(GpuMesh &gpu,
const std::vector<MeshVertex> *
vertices =
nullptr,
1625 const std::vector<uint32_t> *
indices =
nullptr);
1628 static constexpr uint32_t kMaxVgAssets = 64;
1629 static constexpr uint32_t kMaxVgClusters = 65536;
1630 struct VgGpuBuffers {
1633 vkb::GenericBuffer clusters;
1634 vkb::GenericBuffer clusterAssets;
1636 vkb::GenericBuffer indirect;
1637 vkb::GenericBuffer assetMaterials;
1638 vkb::GenericBuffer assetModels;
1640 VgGpuBuffers vgGpu_;
1641 uint32_t vgClusterCount_ = 0;
1642 uint32_t vgAssetCount_ = 0;
1643 uint32_t vgVertexCount_ = 0;
1644 uint32_t vgTriangleCount_ = 0;
1645 uint32_t vgLastVisible_ = 0;
1646 bool vgAnyThisFrame_ =
false;
1647 ComputePass vgCullPass_;
1648 vk::Pipeline gbufferVgVisPipeline =
nullptr;
1649 void ensureVgBuffers();
1650 void growVgBuffers(uint32_t needClusters, uint32_t needVertices, uint32_t needTriangles);
1652 void bindVgPoolBindless();
1654 void bindVgFrameBindless(vk::DescriptorSet bindless,
size_t slot);
1656 void recordVgCull();
1658 void drawVgClusters(vk::CommandBuffer cb);
1661 bool gpuDrivenEnabled_ =
false;
1662 uint32_t lastGpuDrivenDrawCount_ = 0;
1663 vk::PipelineLayout mesh3dGpuDrivenPipelineLayout =
nullptr;
1664 vk::Pipeline mesh3dGpuDrivenPipeline =
nullptr;
1665 vk::Pipeline resolveVisPipeline =
nullptr;
1667 vk::DescriptorSetLayout deferredLightingSetLayout{};
1668 vk::UniqueDescriptorSetLayout deferredLightingSetLayoutUnique;
1669 vk::PipelineLayout deferredLightingPipelineLayout{};
1670 vk::Pipeline deferredLightingPipeline{};
1671 vkb::GenericBuffer deferredLightingUbo{};
1672 vk::DescriptorSet deferredLightingSet{};
1673 vk::Sampler deferredLightingSampler{};
1674 void createMesh3DGpuDrivenPipeline();
1676 struct GpuDrivenFrameSet0 {
1677 vk::DescriptorSet set;
1678 uint32_t uboOffset = 0;
1679 uint32_t shadowOffset = 0;
1681 GpuDrivenFrameSet0 gpuDrivenFrameSet0();
1682 void createResolveVisPipeline(
const vkb::BuiltRenderPass &rp,
1683 vk::SampleCountFlagBits samples);
1685 void initGpuDrivenResources();
1687 void createGpuDrivenVisResources(
int width,
int height);
1690 struct GpuDrivenCullSlot {
1691 vkb::GenericBuffer visibleFlags;
1692 vkb::GenericBuffer compacted;
1693 vkb::GenericBuffer indirect;
1694 vkb::GenericBuffer indirectNI;
1695 vkb::GenericBuffer bucketCounters;
1696 vkb::GenericBuffer hzb;
1697 vkb::GenericBuffer cullParams;
1699 std::vector<GpuDrivenCullSlot> gpuDrivenCullSlots_;
1700 vkb::GenericBuffer gpuDrivenCullParamsPlaceholder_;
1701 int gpuDrivenCullWidth = 0;
1702 int gpuDrivenCullHeight = 0;
1703 uint32_t gpuDrivenCullMaxMip = 0;
1704 vk::PipelineLayout gpuDrivenComputeLayout =
nullptr;
1705 vk::DescriptorSetLayout gpuDrivenComputeEmptyLayout_ =
nullptr;
1706 ComputePass hzbBuildPass_;
1707 ComputePass cullPass_;
1708 ComputePass emitPass_;
1709 bool gpuDrivenCullReady_ =
false;
1710 bool gpuDrivenScenePassPending_ =
false;
1712 std::vector<uint32_t> gpuDrivenBucketIds_;
1713 std::vector<uint32_t> gpuDrivenBucketOffsets_;
1714 std::vector<uint32_t> gpuDrivenBucketMeshIds_;
1715 uint32_t gpuDrivenBucketCount_ = 0;
1716 uint32_t gpuDrivenCullInstanceCount_ = 0;
1717 uint32_t gpuDrivenLastCullSlot_ = 0;
1718 FrameArena::Alloc gpuDrivenInstAlloc_{};
1719 FrameArena::Alloc gpuDrivenBucketIdAlloc_{};
1720 FrameArena::Alloc gpuDrivenBucketOffAlloc_{};
1721 void ensureGpuDrivenCullResources(
int width,
int height);
1722 void recordGpuDrivenHzbBuild();
1723 void gpuDrivenRecordComputeSection(
const glm::mat4 &
viewProj,
const glm::vec3 &
eye,
1724 float fovYDeg,
float nearZ,
float farZ);
1725 void destroyGpuDrivenCullResources();
1726 GpuDrivenCullSlot ¤tGpuDrivenCullSlot();
1727 GpuDrivenCullSlot &gpuDrivenCullSlot(uint32_t frameSlot);
1730 struct ShadowMapSlot {
1731 vkb::DepthArrayImage
image;
1732 vk::Framebuffer framebuffers[ShadowConfig::kTotalLayers]{};
1734 std::vector<ShadowMapSlot> shadowMaps;
1735 vkb::DepthSampler shadowSampler{};
1736 vk::Sampler shadowRawSampler{};
1737 vkb::BuiltRenderPass shadowRenderPass{};
1738 vk::PipelineLayout shadowPipelineLayout{};
1739 vk::Pipeline shadowPipeline{};
1740 vk::Pipeline shadowSingleSidedPipeline{};
1741 vk::PipelineLayout shadowAlphaPipelineLayout{};
1742 vk::Pipeline shadowAlphaPipeline{};
1743 vk::Pipeline shadowAlphaSingleSidedPipeline{};
1744 vk::PipelineLayout skinPassPipelineLayout{};
1745 vk::DescriptorSetLayout skinPassSetLayout{};
1746 vk::UniqueDescriptorSetLayout skinPassSetLayoutUnique;
1747 vk::Pipeline shadowSkinPipeline{};
1748 vk::Pipeline shadowSkinSingleSidedPipeline{};
1749 vk::Pipeline shadowSkinAlphaPipeline{};
1750 vk::Pipeline shadowSkinAlphaSingleSidedPipeline{};
1751 int shadowPassCascade = -1;
1756 bool alphaTest =
false;
1758 glm::vec4 lodFade{1.f, 0.f, 0.f, 0.f};
1759 vk::DescriptorSet skinSet{};
1760 uint32_t skinUboOffset = 0;
1762 struct ShadowAlphaPush {
1764 glm::vec4 lodFade{1.f, 0.f, 0.f, 0.f};
1766 std::vector<ShadowDraw> shadowPassDraws;
1767 std::vector<ShadowDraw> shadowCascadeDraws[ShadowConfig::kTotalLayers];
1768 uint32_t shadowPendingMask = 0;
1769 ShadowMapSlot ¤tShadowMap();
1770 vk::ImageView currentShadowArrayView();
1773 struct GBufferPush {
1775 glm::vec4 modelR0{1.f, 0.f, 0.f, 0.f};
1776 glm::vec4 modelR1{0.f, 1.f, 0.f, 0.f};
1777 glm::vec4 modelR2{0.f, 0.f, 1.f, 0.f};
1778 glm::vec4
clip{0.1f, 100.f, 0.f, 0.f};
1780 static_assert(
sizeof(GBufferPush) == 128,
"GBuffer push constants must be 128 bytes");
1781 struct GBufferDraw {
1785 bool alphaTest =
false;
1786 vk::DescriptorSet skinSet{};
1787 uint32_t skinUboOffset = 0;
1789 struct GBufferSlot {
1791 vkb::ColorTarget depthColor;
1793 vkb::ColorTarget pbrParams;
1794 vkb::ColorTarget emissive;
1795 vkb::ColorTarget visID;
1796 vkb::ColorTarget visBary;
1797 vkb::DepthTarget
depth;
1798 vk::Framebuffer framebuffer{};
1799 vk::Framebuffer visFramebuffer{};
1800 GpuTexture normalGpu{};
1801 GpuTexture depthColorGpu{};
1802 GpuTexture albedoGpu{};
1803 GpuTexture pbrParamsGpu{};
1804 GpuTexture emissiveGpu{};
1805 GpuTexture visIDGpu{};
1806 GpuTexture visBaryGpu{};
1807 GpuTexture depthGpu{};
1817 int gbufferWidth = 0;
1818 int gbufferHeight = 0;
1819 std::vector<GBufferSlot> gbufferSlots;
1820 vkb::BuiltRenderPass gbufferRenderPass{};
1821 vkb::BuiltRenderPass gbufferVisRenderPass{};
1822 vk::PipelineLayout gbufferPipelineLayout{};
1823 vk::Pipeline gbufferPipeline{};
1824 vk::Pipeline gbufferAlphaPipeline{};
1825 vk::Pipeline gbufferSkinPipeline{};
1826 vk::Pipeline gbufferSkinAlphaPipeline{};
1827 vk::Pipeline gbufferVisPipeline =
nullptr;
1828 bool gbufferPassActive =
false;
1829 bool gbufferPending =
false;
1830 std::vector<GBufferDraw> gbufferPassDraws;
1831 GBufferSlot *currentGBufferSlot();
1836 struct DecalInstanceData {
1837 glm::mat4
model{1.f};
1838 glm::vec4 uvRect{0.f, 0.f, 1.f, 1.f};
1839 glm::vec4 fadeParams{1.f, 0.f, 0.f, 0.f};
1840 glm::vec4 extraParams{0.f, 0.f, 0.f, 0.f};
1841 glm::vec4 surfaceParams{0.f, 8.f, 24.f, 0.06f};
1843 static_assert(
sizeof(DecalInstanceData) == 128,
"DecalInstanceData must be 128 bytes");
1844 struct DecalCameraUBO {
1847 glm::vec4 nearFarTexel{0.1f, 100.f, 0.f, 0.f};
1850 static constexpr size_t kMaxDecalInstances = 512;
1852 glm::mat4
model{1.f};
1856 float uvRect[4] = {0.f, 0.f, 1.f, 1.f};
1859 float roughnessStrength = 0.f;
1860 float metalStrength = 0.f;
1861 float emissiveStrength = 0.f;
1863 int projectionMode = 0;
1864 float blendSharpness = 4.f;
1865 float parallaxScale = 0.f;
1866 float parallaxMinLayers = 8.f;
1867 float parallaxMaxLayers = 24.f;
1868 float edgeFadeWidth = 0.06f;
1870 struct DecalSetKey {
1871 GpuTexture *
albedo =
nullptr;
1872 GpuTexture *
normal =
nullptr;
1873 GpuTexture *
params =
nullptr;
1874 GpuTexture *
depth =
nullptr;
1875 GpuTexture *gbNormal =
nullptr;
1877 bool operator==(
const DecalSetKey &o)
const {
1879 depth == o.depth && gbNormal == o.gbNormal;
1882 struct DecalSetKeyHash {
1884 size_t operator()(
const DecalSetKey &k)
const {
1885 return std::hash<GpuTexture *>()(k.albedo) ^
1886 (std::hash<GpuTexture *>()(k.normal) << 1) ^
1887 (std::hash<GpuTexture *>()(k.params) << 2) ^
1888 (std::hash<GpuTexture *>()(k.depth) << 3) ^
1889 (std::hash<GpuTexture *>()(k.gbNormal) << 4);
1896 vk::Framebuffer framebuffer{};
1897 GpuTexture albedoGpu{};
1898 GpuTexture normalGpu{};
1899 GpuTexture paramsGpu{};
1903 vkb::GenericBuffer cameraUbo;
1904 std::unordered_map<DecalSetKey, vkb::BoundSet, DecalSetKeyHash> sets;
1907 int decalHeight = 0;
1908 std::vector<DecalSlot> decalSlots;
1909 vkb::BuiltRenderPass decalRenderPass{};
1910 vk::DescriptorSetLayout decalSetLayout;
1911 vk::UniqueDescriptorSetLayout decalSetLayoutUnique;
1912 vk::PipelineLayout decalPipelineLayout{};
1913 vk::Pipeline decalPipeline{};
1914 bool decalPassActive =
false;
1915 bool decalPending =
false;
1918 bool decalLayerFresh =
false;
1919 std::vector<DecalDraw> decalPassDraws;
1920 vk::Pipeline lastDecalPipeline =
nullptr;
1921 Mesh *decalUnitBox =
nullptr;
1923 Texture *decalFlatAlbedo =
nullptr;
1924 Texture *decalFlatNormal =
nullptr;
1925 Texture *decalFlatParams =
nullptr;
1926 glm::mat4 decalViewProj{1.f};
1927 float decalNear = 0.1f;
1928 float decalFar = 100.f;
1938 std::array<std::unique_ptr<vkb::FrameGraph>, kAsyncResourceCopies> deferredFrameGraphs_;
1939 vkb::FrameGraph *currentDeferredFrameGraph();
1941 bool deferredGraphRecorded_ =
false;
1942 size_t deferredGraphRecordedSlot_ = 0;
1944 void buildDeferredFrameGraphs();
1949 void resetDeferredFrameGraphs();
1951 void recordShadowCascadePass(vkb::FrameGraphPassContext &ctx,
int cascade);
1953 void recordGBufferPassDraws(vkb::FrameGraphPassContext &ctx);
1955 struct SceneColorSlot {
1956 vkb::ColorTarget msaaColor;
1957 vkb::ColorTarget
color;
1958 vkb::DepthTarget
depth;
1959 vk::Framebuffer framebuffer{};
1960 GpuTexture colorGpu{};
1963 int sceneColorWidth = 0;
1964 int sceneColorHeight = 0;
1965 vk::Format sceneColorFormat = vk::Format::eUndefined;
1966 vk::SampleCountFlagBits sceneColorSamples = vk::SampleCountFlagBits::e1;
1967 std::vector<SceneColorSlot> sceneColorSlots;
1968 size_t completedSceneColorSlot = 0;
1969 bool sceneColorHistoryValid =
false;
1970 vkb::BuiltRenderPass sceneColorRenderPass{};
1971 vk::RenderPass sceneColorResumeRenderPass{};
1972 bool sceneColorPassOpen =
false;
1973 vk::RenderPass scenePassPipelineTarget = vk::RenderPass{};
1974 vk::SampleCountFlagBits scenePassPipelineSamples = vk::SampleCountFlagBits::e1;
1975 int appliedMsaa = -1;
1976 SceneColorSlot *currentSceneColorSlot();
1981 vkb::BuiltRenderPass offscreen3DRenderPass{};
1982 vkb::BuiltRenderPass hdrOffscreen3DRenderPass{};
1983 vk::Pipeline offscreen3DMeshPipeline =
nullptr;
1984 vk::Pipeline hdrOffscreen3DMeshPipeline =
nullptr;
1985 std::array<vk::Pipeline, kMesh3DPipelineVariants> offscreen3DSurfacePipelines{};
1986 std::array<vk::Pipeline, kMesh3DPipelineVariants> hdrOffscreen3DSurfacePipelines{};
1987 vk::UniqueDescriptorSetLayout reflectionProbeFilterSetLayout;
1988 vk::UniquePipelineLayout reflectionProbeFilterPipelineLayout;
1989 ComputePass reflectionProbeFilterPass;
1990 vk::CommandPool offscreen3DPool =
nullptr;
1991 vk::CommandBuffer offscreen3DCB =
nullptr;
1992 vk::Fence offscreen3DFence =
nullptr;
1993 vk::QueryPool offscreen3DTimestampQueryPool =
nullptr;
1994 float offscreen3DTimestampPeriodNs = 0.f;
1995 float lastOffscreen3DGpuDurationMs = 0.f;
1996 bool offscreen3DPassOpen =
false;
1997 bool offscreen3DHDRActive =
false;
1998 OffscreenCanvas *offscreen3DCanvas =
nullptr;
2002 struct UiColorSlot {
2003 vkb::ColorTarget msaaColor;
2004 vkb::ColorTarget
color;
2005 vk::Framebuffer framebuffer{};
2006 GpuTexture colorGpu{};
2009 int uiColorWidth = 0;
2010 int uiColorHeight = 0;
2011 vk::Format uiColorFormat = vk::Format::eUndefined;
2012 vk::SampleCountFlagBits uiColorSamples = vk::SampleCountFlagBits::e1;
2013 std::vector<UiColorSlot> uiColorSlots;
2014 vkb::BuiltRenderPass uiRenderPass{};
2015 vk::Pipeline uiTexturePipeline{};
2016 vk::Pipeline uiTextureOpaquePipeline{};
2017 UiColorSlot *currentUiColorSlot();
2022 struct PresentComposeSlot {
2023 vkb::ColorTarget
color;
2024 vk::Framebuffer framebuffer{};
2025 GpuTexture colorGpu{};
2028 int presentComposeWidth = 0;
2029 int presentComposeHeight = 0;
2030 std::vector<PresentComposeSlot> presentComposeSlots;
2032 vkb::Present presentModel;
2033 vkb::RecordingCmd presentRecording;
2034 vkb::InRenderPass swapchainPass;
2035 vkb::DepthStencilImage depthImage;
2036 vk::Format depthFormat = vk::Format::eD32Sfloat;
2039 vk::QueryPool gpuQueryPool_{};
2040 float timestampPeriod_ = 1.f;
2041 bool gpuTimingReady_ =
false;
2042 float gpuFrameMs_ = 0.f;
2048 std::vector<SolidBatch> solidBatches;
2049 struct TexturedBatch {
2051 enum class Effect {
Default, SceneColorDistortion, DisplayEncode };
2062 std::vector<TexturedBatch> texturedBatches;
2064 std::vector<LitBatch> litBatches;
2066 enum class OverlayKind : uint8_t {
Solid, Textured, Lit, GpuParticles };
2067 struct OverlaySpan {
2068 OverlayKind
kind = OverlayKind::Solid;
2070 uint32_t vertBegin = 0;
2071 uint32_t vertCount = 0;
2073 std::vector<OverlaySpan> overlaySpans;
2074 std::vector<OverlaySpan> engine3DSpans;
2075 std::optional<TexturedBatch> pendingSceneResolve;
2076 Texture *pendingSceneResolveSource =
nullptr;
2077 std::optional<TexturedBatch> pendingUiResolve;
2078 bool sceneColorComposited =
false;
2080 struct GpuParticleDrawRequest {
2082 GpuParticleDraw
draw;
2084 std::unordered_map<GpuParticleHandle, GpuParticleResource*> gpuParticles_;
2085 std::vector<GpuParticleDrawRequest> gpuParticleDraws_;
2087 vk::DescriptorSetLayout gpuParticleComputeSetLayout_{};
2088 vk::DescriptorSetLayout gpuParticleDrawSetLayout_{};
2089 vk::DescriptorSetLayout gpuParticleSortSetLayout_{};
2090 vk::PipelineLayout gpuParticleComputeLayout_{};
2091 vk::PipelineLayout gpuParticleDrawLayout_{};
2092 vk::PipelineLayout gpuParticleSortLayout_{};
2093 vk::Pipeline gpuParticleComputePipeline_{};
2094 vk::Pipeline gpuParticleSortPipeline_{};
2095 vk::Pipeline gpuParticleAlphaPipeline_{};
2096 vk::Pipeline gpuParticleAdditivePipeline_{};
2097 vk::Pipeline gpuParticlePremultipliedPipeline_{};
2098 vk::Pipeline gpuParticleMultiplyPipeline_{};
2099 vk::Pipeline gpuParticleOpaquePipeline_{};
2103 struct Frame2DBuffers {
2104 std::vector<vkb::HostVertexBuffer> solidBufs;
2105 std::vector<vkb::HostVertexBuffer> texBufs;
2106 std::vector<vkb::HostVertexBuffer> uiTexBufs;
2107 std::vector<vkb::HostVertexBuffer> primitive3DBufs;
2108 std::size_t primitive3DDrawIndex = 0;
2110 std::vector<Frame2DBuffers> frame2dBuffers;
2111 Frame2DBuffers offscreenBuffers;
2113 vk::DescriptorSetLayout lit2dSetLayout;
2114 vk::UniqueDescriptorSetLayout lit2dSetLayoutUnique;
2115 vk::PipelineLayout lit2dPipelineLayout;
2116 vk::Pipeline lit2dPipeline;
2117 vk::Pipeline lit2dAdditivePipeline;
2118 vk::Pipeline lit2dPremultipliedPipeline;
2119 vk::Pipeline lit2dMultiplyPipeline;
2120 vk::Pipeline lit2dOpaquePipeline;
2121 vk::Pipeline offscreenLitPipeline;
2122 vk::Pipeline offscreenLitAdditivePipeline;
2123 vk::Pipeline offscreenLitPremultipliedPipeline;
2124 vk::Pipeline offscreenLitMultiplyPipeline;
2125 vk::Pipeline offscreenLitOpaquePipeline;
2127 vk::Pipeline selectLit2DPipeline(BlendMode
blend,
bool offscreen,
bool hdr =
false)
const;
2128 std::vector<vkb::GenericBuffer> lighting2dUboSlots;
2129 vkb::GenericBuffer offscreenLighting2dUbo;
2130 Lighting2DUBO lighting2dFrame{};
2132 GpuTexture *
albedo =
nullptr;
2133 GpuTexture *
normal =
nullptr;
2135 bool operator==(
const LitSetKey &o)
const {
2139 struct LitSetKeyHash {
2141 size_t operator()(
const LitSetKey &k)
const {
2142 return std::hash<void *>()(k.albedo) ^ (std::hash<void *>()(k.normal) << 1);
2146 GpuTexture *
color =
nullptr;
2147 GpuTexture *
depth =
nullptr;
2148 GpuTexture *motion =
nullptr;
2149 GpuTexture *extra =
nullptr;
2150 GpuTexture *specular =
nullptr;
2152 bool operator==(
const PostSetKey &o)
const {
2153 return color == o.color &&
depth == o.depth && motion == o.motion && extra == o.extra &&
2154 specular == o.specular;
2157 struct PostSetKeyHash {
2159 size_t operator()(
const PostSetKey &k)
const {
2160 return std::hash<void *>()(k.color) ^ (std::hash<void *>()(k.depth) << 1) ^
2161 (std::hash<void *>()(k.motion) << 2) ^
2162 (std::hash<void *>()(k.extra) << 3) ^
2163 (std::hash<void *>()(k.specular) << 4);
2166 std::vector<std::unordered_map<LitSetKey, vkb::BoundSet, LitSetKeyHash>> lit2dSets;
2167 std::unordered_map<LitSetKey, vkb::BoundSet, LitSetKeyHash> offscreenLit2dSets;
2168 std::unordered_map<PostSetKey, vkb::BoundSet, PostSetKeyHash> post2Sets;
2169 Texture *flatNormalTexture =
nullptr;
2172 bool hasPendingClear =
true;
2174 std::vector<std::unique_ptr<Texture>> ownedTextures;
2175 std::vector<std::unique_ptr<GpuTexture>> ownedGpuTextures;
2177 std::unordered_map<std::string, Texture *> texturesByPath;
2178 std::unordered_map<std::string, Texture *> sharedTexturesByContent;
2179 std::vector<std::unique_ptr<Mesh>> ownedMeshes;
2180 std::vector<std::unique_ptr<GpuMesh>> ownedGpuMeshes;
2181 std::vector<std::unique_ptr<Shader>> ownedShaders;
2182 std::vector<std::unique_ptr<GpuShader>> ownedGpuShaders;
2183 std::vector<std::unique_ptr<eve::graphics::Canvas>> ownedCanvases;
2185 bool swapchainPassOpen =
false;
2186 bool flushingSwapchain_ =
false;
2187 Mesh3DUBO mesh3dFrameUbo{};
2190 struct VoxelRectPC {
2192 glm::vec4 chunkOrigin{0.f};
2193 glm::vec4 atlasInfo{16.f, 0.f, 0.f, 0.f};
2194 glm::vec4
tint{1.f};
2196 vk::DescriptorSetLayout voxelRectSetLayout{};
2197 vk::UniqueDescriptorSetLayout voxelRectSetLayoutUnique;
2198 vk::PipelineLayout voxelRectPipelineLayout{};
2199 vk::Pipeline voxelRectPipeline{};
2200 vkb::GenericBuffer voxelUnitQuadVerts;
2201 vkb::GenericBuffer voxelUnitQuadIndices;
2202 bool voxelUnitQuadReady =
false;
2203 std::unordered_map<GpuTexture *, vkb::BoundSet> voxelRectSets;
2206 struct VoxelInstanceSlot {
2207 vkb::GenericBuffer
buffer;
2208 size_t capacityBytes = 0;
2209 vkb::GenericBuffer aoBuffer;
2210 size_t aoCapacityBytes = 0;
2212 struct VoxelInstanceFrame {
2213 std::vector<VoxelInstanceSlot>
slots;
2214 size_t drawIndex = 0;
2216 std::vector<VoxelInstanceFrame> voxelInstanceFrames;
2218 Frame2DBuffers ¤tFrame2DBuffers();
2219 Mesh3dFrameSlots ¤tMesh3dFrameSlots();
2220 Mesh3dClusteredFrameSlots ¤tMesh3dClusteredFrameSlots();
2221 vkb::GenericBuffer ¤tLighting2dUbo();
2222 std::unordered_map<LitSetKey, vkb::BoundSet, LitSetKeyHash> ¤tLit2dSets();
2223 ClusteredStorage ¤tClusteredStorage();
2224 VoxelInstanceFrame ¤tVoxelInstanceFrame();
2225 uint32_t frameSlotCount()
const;
2226 size_t currentFrameSlot()
const;
2227 vk::CommandBuffer ¤tPresentCb();
2228 vkb::FrameSlot frameToken()
const;
2229 void invalidateTextureBindings();