346 VkCommandBuffer cmd = data.commandBuffer;
348 auto now = std::chrono::high_resolution_clock::now();
349 currentTime = std::chrono::duration<float>(now - startTime).count();
351 if (m_r_context.supportsBindlessTextures) {
352 VkDescriptorSet globalSet = m_p_resources->getBindlessDescriptorSet();
353 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_pipeline->layout(),
354 1, 1, &globalSet, 0,
nullptr);
357 if (m_lastUsedView != m_r_context.lowResColorView) {
359 if (m_cachedImGuiDescriptor != VK_NULL_HANDLE) {
360 m_garbageDescriptors[m_r_context.currentFrame].push_back(m_cachedImGuiDescriptor);
362 m_cachedImGuiDescriptor = VK_NULL_HANDLE;
363 m_lastUsedView = m_r_context.lowResColorView;
366 glm::vec3 finalClearColor = m_r_context.m_environment.clearColor;
367 bool fogHandled =
false;
371 if (fogHandled)
return;
373 m_sceneUBO.fogColor = glm::vec4(fc.color, fc.density);
374 m_sceneUBO.fogDistances = glm::vec2(fc.start, fc.end);
376 float skyMixFactor = glm::clamp(fc.density, 0.0f, 1.0f);
377 finalClearColor = glm::mix(finalClearColor, fc.color, skyMixFactor);
382 std::vector<MeshComponent*> pendingMeshes;
386 const std::string& path = mesh.meshData.meshPath;
387 if (!path.empty() && !m_p_meshManager->isMeshLoaded(path)) {
389 for (
auto* m : pendingMeshes) {
390 if (m->meshData.meshPath == path) {
396 pendingMeshes.push_back(&mesh);
401 if (!pendingMeshes.empty()) {
402 m_p_meshManager->loadMeshesAsync(pendingMeshes);
406 m_r_context.lowResColorImage,
407 VK_IMAGE_LAYOUT_UNDEFINED,
408 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
410 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
411 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
412 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
415 m_r_context.depthImage,
416 VK_IMAGE_LAYOUT_UNDEFINED,
417 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
419 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
420 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
421 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
423 VkRenderingAttachmentInfo colorAttachment{};
424 colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
425 colorAttachment.imageView = m_r_context.lowResColorView;
426 colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
427 colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
428 colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
429 colorAttachment.clearValue.color = {{finalClearColor.x, finalClearColor.y, finalClearColor.z, 1.0f}};
431 VkRenderingAttachmentInfo depthAttachment{};
432 depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
433 depthAttachment.imageView = m_r_context.depthImageView;
434 depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
435 depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
436 depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
437 depthAttachment.clearValue.depthStencil = {1.0f, 0};
439 VkRenderingInfo renderingInfo{};
440 renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
441 renderingInfo.renderArea.offset = {0, 0};
442 renderingInfo.renderArea.extent = {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y};
443 renderingInfo.layerCount = 1;
444 renderingInfo.colorAttachmentCount = 1;
445 renderingInfo.pColorAttachments = &colorAttachment;
446 renderingInfo.pDepthAttachment = &depthAttachment;
449 vkCmdBeginRendering(cmd, &renderingInfo);
450 }
catch (
const std::exception& e) {
455 VkViewport viewport{};
456 viewport.width = (float)m_r_context.currentRenderResolution.x;
457 viewport.height = (float)m_r_context.currentRenderResolution.y;
458 viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f;
459 vkCmdSetViewport(cmd, 0, 1, &viewport);
462 scissor.extent = {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y};
463 vkCmdSetScissor(cmd, 0, 1, &scissor);
465 glm::mat4 view = glm::mat4(1.0f);
466 glm::mat4 proj = glm::mat4(1.0f);
470 if(!transform.isReady()){
471 transform.setRegistry(registry);
474 transform.recalculateMatrix();
476 view = glm::lookAt(transform.getWorldPosition(), transform.getWorldPosition() + transform.getForwardVector(), transform.getUpVector());
477 proj = glm::perspective(glm::radians(camera.fov), (
float)m_r_context.currentRenderResolution.x / (
float)m_r_context.currentRenderResolution.y, camera.nearPlane, camera.farPlane);
480 m_sceneUBO.view = view;
481 m_sceneUBO.proj = proj;
483 m_sceneUBO.snapResolution = 1.f;
484 m_sceneUBO.jitterIntensity = 0.5f;
486 m_sceneUBO.enablePS1Effects = 0;
488 if(m_r_context.m_environment.vertexSnapping){
489 m_sceneUBO.enablePS1Effects |= PS1Effects::VERTEX_SNAPPING;
492 if(m_r_context.m_environment.passiveVertexJitter){
493 m_sceneUBO.enablePS1Effects |= PS1Effects::VERTEX_JITTER;
496 if(m_r_context.m_environment.affineWarping){
497 m_sceneUBO.enablePS1Effects |= PS1Effects::AFFINE_WARPING;
500 if(m_r_context.m_environment.screenQuantization){
501 m_sceneUBO.enablePS1Effects |= PS1Effects::SCREEN_QUANTIZATION;
504 if(m_r_context.m_environment.ntfsArtifacts){
505 m_sceneUBO.enablePS1Effects |= PS1Effects::NTSC_ARTIFACTS;
508 if(m_r_context.m_environment.gourardShading){
509 m_sceneUBO.enablePS1Effects |= PS1Effects::GOURAUD_SHADING;
512 if(m_r_context.m_environment.textureQuantization){
513 m_sceneUBO.enablePS1Effects |= PS1Effects::TEXTURE_QUANTIZATION;
516 if(m_r_context.m_environment.screenDither){
517 m_sceneUBO.enablePS1Effects |= PS1Effects::SCREEN_DITHER;
520 m_sceneUBO.renderResolution = m_r_context.currentRenderResolution;
521 m_sceneUBO.windowResolution = {m_r_context.swapchainExtent.width, m_r_context.swapchainExtent.height};
522 m_sceneUBO.time = currentTime;
523 m_sceneUBO.frame = frame;
524 m_sceneUBO.upscaleRatio = m_r_context.swapchainExtent.height /
static_cast<float>(m_r_context.currentRenderResolution.y);
526 m_sceneUBO.ambientLight = glm::vec4(m_r_context.m_environment.ambientLight,1.0f);
527 m_sceneUBO.ambientLightStrength = m_r_context.m_environment.ambientLightStrength;
528 m_sceneUBO.sunLight = glm::vec4(m_r_context.m_environment.sunLight,1.0f);
529 m_sceneUBO.sunDirection = glm::vec4(m_r_context.m_environment.sunDirection,1.0f);
531 m_p_resources->updateSceneUBO(m_sceneUBO);
533 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_pipeline->get());
535 glm::vec3 cameraPos = extractCameraPosition(view);
537 camFrustum.
update(proj * view);
539 m_transparentTriangles.clear();
540 trnasMatrixes.clear();
541 uint32_t modelIndex = 0;
555 frustumSimd.init(camFrustum);
560 bool boundsNeedUpdate = transform.isDirty() || mesh.
getIsFresh() || isEditorMode || mesh.worldRadius <= 0.0f;
561 glm::mat4 modelMatrix = transform.
matrix();
563 if(!transform.isReady()){
564 transform.setRegistry(registry);
567 if(boundsNeedUpdate){
568 float scaleX = glm::length(glm::vec3(modelMatrix[0]));
569 float scaleY = glm::length(glm::vec3(modelMatrix[1]));
570 float scaleZ = glm::length(glm::vec3(modelMatrix[2]));
572 float maxScale = std::max({ scaleX, scaleY, scaleZ });
574 mesh.worldRadius = mesh.localRadius * maxScale;
575 mesh.worldCenter = (modelMatrix * glm::vec4(mesh.localCenter, 1.0f));
578 if(isEditorMode && frame > 0){
579 transform.convertRot();
580 }
else if(isEditorMode){
583 transform.rotation = glm::mod(transform.rotation, glm::vec3(360.0f));
589 if (useAVX) [[likely]] {
590 visible = frustumSimd.testSphereAVX(mesh.worldCenter, mesh.worldRadius);
592 visible = camFrustum.
testSphere(mesh.worldCenter, mesh.worldRadius);
595 if (!visible)
return;
600 lightUBO.lightCount = 0;
603 if (lightUBO.lightCount >= MAX_DYNAMIC_LIGHTS) {
607 if(!lightTransform.isReady()){
608 lightTransform.setRegistry(registry);
611 float dist = glm::distance(lightTransform.
getWorldPosition(), mesh.worldCenter);
612 if (dist < (light.radius + mesh.worldRadius)) {
613 auto& targetLight = lightUBO.lights[lightUBO.lightCount];
614 targetLight.position = glm::vec4(lightTransform.
getWorldPosition(), light.radius);
615 targetLight.color = glm::vec4(light.color, light.intensity);
616 lightUBO.lightCount++;
618 if (lightUBO.lightCount == MAX_DYNAMIC_LIGHTS) {
619 log(LogLevel::WARNING,
"Limit reached of per object dynamic lights, rest of the light wont affect this mesh.");
624 m_p_resources->updateLightUBO(m_r_context.currentFrame, modelIndex, lightUBO);
626 if (mesh.renderType == RenderType::OPAQUE) {
633 }
else if (mesh.renderType == RenderType::MASKED) {
635 }
else if (mesh.renderType == RenderType::TRANSPARENT) {
646 if (tIndex == 0) tIndex = m_p_resources->getTextureIndex(
"default");
664 float offsetStep = 1.2f;
665 float currentOffset = -((bill.
texturePaths.size() - 1) * offsetStep) / 2.0f;
669 uint32_t tIndex = m_p_resources->getTextureIndex(correctPath);
671 if (m_p_resources->loadTexture(correctPath, correctPath)) {
672 tIndex = m_p_resources->getTextureIndex(correctPath);
675 if (tIndex == 0) tIndex = m_p_resources->getTextureIndex(
"default");
677 bEditorQueue.push_back({entity, tIndex, currentOffset});
678 currentOffset += offsetStep;
687 auto& vulkanMesh = m_p_meshManager->getVulkanMeshByMesh(mesh);
690 vulkanMesh->draw(cmd, m_p_pipeline->layout(), *m_p_resources, data.frameIndex, item.modelIndex, transform.matrix(), mesh);
698 if(cameraEntity == entity) {
705 if(m_editorCameraVulkanMesh->getNumOfInstances() <= 0){
706 m_editorCameraMesh.loadFromRawFile(
"../Assets/meshes/editorCamera.obj");
707 m_editorCameraVulkanMesh->upload(m_editorCameraMesh);
708 m_editorCameraVulkanMesh->addInstance();
711 mc.color = glm::vec4(0.3f, 1.0f, 0.5f, 1.0f);
712 m_editorCameraVulkanMesh->draw(cmd, m_p_pipeline->layout(), *m_p_resources, data.frameIndex, 0, transform.
matrix(), mc);
720 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_maskPipeline->get());
725 auto& vulkanMesh = m_p_meshManager->getVulkanMeshByMesh(mesh);
728 vulkanMesh->draw(cmd,
m_p_maskPipeline->layout(), *m_p_resources, data.frameIndex, item.modelIndex, transform.matrix(), mesh);
733 uint32_t currentParticleOffset = 0;
735 VkDescriptorSet particleSSBODescriptorSet = m_p_resources->getParticleDescriptorSet(data.frameIndex);
739 VkViewport viewport{0.0f, 0.0f, (float)m_r_context.currentRenderResolution.x, (
float)m_r_context.currentRenderResolution.y, 0.0f, 1.0f};
740 VkRect2D scissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
741 vkCmdSetViewport(cmd, 0, 1, &viewport);
742 vkCmdSetScissor(cmd, 0, 1, &scissor);
743 VkDescriptorSet globalSet_bMaskedQueue = m_p_resources->getUBODescriptorSet(data.frameIndex);
744 uint32_t dynamicOffset_bMaskedQueue = 0;
745 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 0, 1, &globalSet_bMaskedQueue, 1, &dynamicOffset_bMaskedQueue);
746 if (m_r_context.supportsBindlessTextures) {
747 VkDescriptorSet bindlessSet = m_p_resources->getBindlessDescriptorSet();
748 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 1, 1, &bindlessSet, 0,
nullptr);
755 push.
pos = trans.getWorldPosition();
756 push.sx = bill.size.x;
757 push.sy = bill.size.y;
758 push.tID = item.texID;
759 push.unlit = bill.isUnlit ? 1 : 0;
760 push.col = glm::vec4(bill.color.r, bill.color.g, bill.color.b, bill.color.a);
764 VkDescriptorSet globalSet = m_p_resources->getUBODescriptorSet(data.frameIndex);
765 uint32_t dynamicOffset = 0;
766 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 0, 1, &globalSet, 1, &dynamicOffset);
768 if (m_r_context.supportsBindlessTextures) {
769 VkDescriptorSet bindlessSet = m_p_resources->getBindlessDescriptorSet();
770 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 1, 1, &bindlessSet, 0,
nullptr);
772 VkDescriptorSet texSet = m_p_resources->getTextureDescriptorSet(data.frameIndex, item.texID);
776 vkCmdDraw(cmd, 6, 1, 0, 0);
783 VkViewport viewport{0.0f, 0.0f, (float)m_r_context.currentRenderResolution.x, (
float)m_r_context.currentRenderResolution.y, 0.0f, 1.0f};
784 VkRect2D scissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
785 vkCmdSetViewport(cmd, 0, 1, &viewport);
786 vkCmdSetScissor(cmd, 0, 1, &scissor);
787 VkDescriptorSet globalSet_bMaskedQueue = m_p_resources->getUBODescriptorSet(data.frameIndex);
788 uint32_t dynamicOffset_bMaskedQueue = 0;
789 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 0, 1, &globalSet_bMaskedQueue, 1, &dynamicOffset_bMaskedQueue);
790 if (m_r_context.supportsBindlessTextures) {
791 VkDescriptorSet bindlessSet = m_p_resources->getBindlessDescriptorSet();
792 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 1, 1, &bindlessSet, 0,
nullptr);
798 glm::vec3 cameraRight = glm::vec3(view[0][0], view[1][0], view[2][0]);
799 glm::vec3 basePos = trans ? trans->getWorldPosition() : glm::vec3(0.0f);
800 push.pos = basePos + (cameraRight * item.offsetX);
803 push.tID = item.texID;
805 push.col = glm::vec4(1,1,1,1);
809 VkDescriptorSet globalSet = m_p_resources->getUBODescriptorSet(data.frameIndex);
810 uint32_t dynamicOffset = 0;
811 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 0, 1, &globalSet, 1, &dynamicOffset);
813 if (m_r_context.supportsBindlessTextures) {
814 VkDescriptorSet bindlessSet = m_p_resources->getBindlessDescriptorSet();
815 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardMaskedPipeline->layout(), 1, 1, &bindlessSet, 0,
nullptr);
817 VkDescriptorSet texSet = m_p_resources->getTextureDescriptorSet(data.frameIndex, item.texID);
821 vkCmdDraw(cmd, 6, 1, 0, 0);
828 VkViewport viewport{0.0f, 0.0f, (float)m_r_context.currentRenderResolution.x, (
float)m_r_context.currentRenderResolution.y, 0.0f, 1.0f};
829 VkRect2D scissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
830 vkCmdSetViewport(cmd, 0, 1, &viewport);
831 vkCmdSetScissor(cmd, 0, 1, &scissor);
833 VkDescriptorSet globalSet = m_p_resources->getUBODescriptorSet(data.frameIndex);
834 uint32_t dynamicOffset = 0;
835 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleMaskedPipeline->layout(), 0, 1, &globalSet, 1, &dynamicOffset);
837 if (m_r_context.supportsBindlessTextures) {
838 VkDescriptorSet bindlessSet = m_p_resources->getBindlessDescriptorSet();
839 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleMaskedPipeline->layout(), 1, 1, &bindlessSet, 0,
nullptr);
846 if (currentParticleOffset + pCount > 100000) {
847 vex::log(LogLevel::WARNING,
"Max particle limit reached! Skipping further particles.");
855 if (tIndex == 0) tIndex = m_p_resources->getTextureIndex(
"default");
860 if (!m_r_context.supportsBindlessTextures) {
861 VkDescriptorSet texSet = m_p_resources->getTextureDescriptorSet(data.frameIndex, tIndex);
862 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleMaskedPipeline->layout(), 1, 1, &texSet, 0,
nullptr);
865 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleMaskedPipeline->layout(), 2, 1, &particleSSBODescriptorSet, 0,
nullptr);
867 vkCmdDraw(cmd, 6, pCount, 0, currentParticleOffset);
868 currentParticleOffset += pCount;
872 vkCmdEndRendering(cmd);
874 transitionImageLayout(cmd, m_r_context.accumImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
875 transitionImageLayout(cmd, m_r_context.revealImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
877 VkRenderingAttachmentInfo transAttachments[2]{};
879 transAttachments[0].sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
880 transAttachments[0].imageView = m_r_context.accumView;
881 transAttachments[0].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
882 transAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
883 transAttachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
884 transAttachments[0].clearValue.color = {{0.0f, 0.0f, 0.0f, 0.0f}};
886 transAttachments[1].sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
887 transAttachments[1].imageView = m_r_context.revealView;
888 transAttachments[1].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
889 transAttachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
890 transAttachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
891 transAttachments[1].clearValue.color = {{1.0f, 0.0f, 0.0f, 0.0f}};
893 VkRenderingAttachmentInfo transDepthAttachment{};
894 transDepthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
895 transDepthAttachment.imageView = m_r_context.depthImageView;
896 transDepthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
897 transDepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
898 transDepthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_NONE;
900 VkRenderingInfo transRenderingInfo{};
901 transRenderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
902 transRenderingInfo.renderArea.offset = {0, 0};
903 transRenderingInfo.renderArea.extent = {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y};
904 transRenderingInfo.layerCount = 1;
905 transRenderingInfo.colorAttachmentCount = 2;
906 transRenderingInfo.pColorAttachments = transAttachments;
907 transRenderingInfo.pDepthAttachment = &transDepthAttachment;
909 vkCmdBeginRendering(cmd, &transRenderingInfo);
912 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_transPipeline->get());
917 auto& vulkanMesh = m_p_meshManager->getVulkanMeshByMesh(mesh);
920 vulkanMesh->draw(cmd,
m_p_transPipeline->layout(), *m_p_resources, data.frameIndex, item.modelIndex, transform.matrix(), mesh);
927 VkViewport viewport{0.0f, 0.0f, (float)m_r_context.currentRenderResolution.x, (
float)m_r_context.currentRenderResolution.y, 0.0f, 1.0f};
928 VkRect2D scissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
929 vkCmdSetViewport(cmd, 0, 1, &viewport);
930 vkCmdSetScissor(cmd, 0, 1, &scissor);
931 VkDescriptorSet globalSet_bTransQueue = m_p_resources->getUBODescriptorSet(data.frameIndex);
932 uint32_t dynamicOffset_bTransQueue = 0;
933 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardTransPipeline->layout(), 0, 1, &globalSet_bTransQueue, 1, &dynamicOffset_bTransQueue);
934 if (m_r_context.supportsBindlessTextures) {
935 VkDescriptorSet bindlessSet = m_p_resources->getBindlessDescriptorSet();
936 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardTransPipeline->layout(), 1, 1, &bindlessSet, 0,
nullptr);
943 push.
pos = trans.getWorldPosition();
944 push.sx = bill.size.x;
945 push.sy = bill.size.y;
946 push.tID = item.texID;
947 push.unlit = bill.isUnlit ? 1 : 0;
948 push.col = glm::vec4(bill.color.r, bill.color.g, bill.color.b, bill.color.a);
954 if (!m_r_context.supportsBindlessTextures) {
955 VkDescriptorSet texSet = m_p_resources->getTextureDescriptorSet(data.frameIndex, item.texID);
956 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_billboardTransPipeline->layout(), 1, 1, &texSet, 0,
nullptr);
959 vkCmdDraw(cmd, 6, 1, 0, 0);
965 VkViewport viewport{0.0f, 0.0f, (float)m_r_context.currentRenderResolution.x, (
float)m_r_context.currentRenderResolution.y, 0.0f, 1.0f};
966 VkRect2D scissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
967 vkCmdSetViewport(cmd, 0, 1, &viewport);
968 vkCmdSetScissor(cmd, 0, 1, &scissor);
970 VkDescriptorSet globalSet = m_p_resources->getUBODescriptorSet(data.frameIndex);
971 uint32_t dynamicOffset = 0;
972 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleTransPipeline->layout(), 0, 1, &globalSet, 1, &dynamicOffset);
974 if (m_r_context.supportsBindlessTextures) {
975 VkDescriptorSet bindlessSet = m_p_resources->getBindlessDescriptorSet();
976 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleTransPipeline->layout(), 1, 1, &bindlessSet, 0,
nullptr);
983 if (currentParticleOffset + pCount > 100000) {
984 vex::log(LogLevel::WARNING,
"Max particle limit reached! Skipping further particles.");
992 if (tIndex == 0) tIndex = m_p_resources->getTextureIndex(
"default");
997 if (!m_r_context.supportsBindlessTextures) {
998 VkDescriptorSet texSet = m_p_resources->getTextureDescriptorSet(data.frameIndex, tIndex);
999 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleTransPipeline->layout(), 1, 1, &texSet, 0,
nullptr);
1002 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_p_particleTransPipeline->layout(), 2, 1, &particleSSBODescriptorSet, 0,
nullptr);
1004 vkCmdDraw(cmd, 6, pCount, 0, currentParticleOffset);
1005 currentParticleOffset += pCount;
1009 vkCmdEndRendering(cmd);
1011 transitionImageLayout(cmd, m_r_context.accumImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1012 transitionImageLayout(cmd, m_r_context.revealImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1014 transitionImageLayout(cmd, m_r_context.uiImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1016 VkRenderingAttachmentInfo uiColorAttachment = colorAttachment;
1017 uiColorAttachment.imageView = m_r_context.uiView;
1018 uiColorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1019 uiColorAttachment.clearValue.color = {{0.0f, 0.0f, 0.0f, 0.0f}};
1021 VkRenderingAttachmentInfo uiDepthAttachment = depthAttachment;
1022 uiDepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1023 uiDepthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_NONE;
1025 VkRenderingInfo uiRenderingInfo = renderingInfo;
1026 uiRenderingInfo.pColorAttachments = &uiColorAttachment;
1027 uiRenderingInfo.pDepthAttachment = &uiDepthAttachment;
1029 vkCmdBeginRendering(cmd, &uiRenderingInfo);
1032 m_uiObjects.clear();
1035 if(uiComp.m_vexUI->isInitialized()) {
1036 m_uiObjects.emplace_back(uiComp);
1039 std::sort(m_uiObjects.begin(), m_uiObjects.end(), [](
const UiComponent &f,
const UiComponent &s) { return f.m_vexUI->getZIndex() < s.m_vexUI->getZIndex(); });
1041 for(
const auto& uiObject : m_uiObjects) {
1042 if(uiObject.visible){
1043 uiObject.m_vexUI->render(cmd, m_p_uiPipeline->get(), m_p_uiPipeline->layout(), data.frameIndex);
1049 if(debugLines && !debugLines->empty()) {
1050 renderDebug(cmd, data.frameIndex, *debugLines);
1054 vkCmdEndRendering(cmd);
1057 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1058 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1059 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1060 VK_ACCESS_SHADER_READ_BIT,
1061 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1062 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1065 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1066 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1067 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1068 VK_ACCESS_SHADER_READ_BIT,
1069 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1070 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1099 VkCommandBuffer cmd = data.commandBuffer;
1101 transitionImageLayout(cmd, m_r_context.compositeImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1103 VkRenderingAttachmentInfo preCompAtt{};
1104 preCompAtt.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
1105 preCompAtt.imageView = m_r_context.compositeView;
1106 preCompAtt.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1107 preCompAtt.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1108 preCompAtt.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1109 preCompAtt.clearValue.color = {{0.0f, 0.0f, 0.0f, 1.0f}};
1111 VkRenderingInfo preCompInfo{};
1112 preCompInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
1113 preCompInfo.renderArea.offset = {0, 0};
1114 preCompInfo.renderArea.extent = {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y};
1115 preCompInfo.layerCount = 1;
1116 preCompInfo.colorAttachmentCount = 1;
1117 preCompInfo.pColorAttachments = &preCompAtt;
1119 vkCmdBeginRendering(cmd, &preCompInfo);
1120 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_compositePipeline->get());
1121 VkViewport compViewport{};
1122 compViewport.x = 0.0f;
1123 compViewport.y = 0.0f;
1124 compViewport.width =
static_cast<float>(m_r_context.currentRenderResolution.x);
1125 compViewport.height =
static_cast<float>(m_r_context.currentRenderResolution.y);
1126 compViewport.minDepth = 0.0f;
1127 compViewport.maxDepth = 1.0f;
1128 vkCmdSetViewport(cmd, 0, 1, &compViewport);
1129 VkRect2D compScissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
1130 vkCmdSetScissor(cmd, 0, 1, &compScissor);
1131 VkDescriptorSet compSceneSet = m_p_resources->getUBODescriptorSet(data.frameIndex);
1132 uint32_t compDynamicOffset = 0;
1133 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_compositePipeline->layout(), 0, 1, &compSceneSet, 1, &compDynamicOffset);
1134 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_compositePipeline->layout(), 1, 1, &m_screenDescriptorSet, 0,
nullptr);
1135 vkCmdDraw(cmd, 3, 1, 0, 0);
1136 vkCmdEndRendering(cmd);
1139 VkImageMemoryBarrier barrier{};
1140 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1141 barrier.image = m_r_context.compositeImage;
1142 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1143 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1144 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1145 barrier.subresourceRange.baseArrayLayer = 0;
1146 barrier.subresourceRange.layerCount = 1;
1147 barrier.subresourceRange.levelCount = 1;
1149 int32_t mipWidth = m_r_context.currentRenderResolution.x;
1150 int32_t mipHeight = m_r_context.currentRenderResolution.y;
1152 for (uint32_t i = 1; i < 3; i++) {
1153 barrier.subresourceRange.baseMipLevel = i - 1;
1154 barrier.oldLayout = (i == 1) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1155 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1156 barrier.srcAccessMask = (i == 1) ? VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT : VK_ACCESS_TRANSFER_WRITE_BIT;
1157 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1159 vkCmdPipelineBarrier(cmd,
1160 (i == 1) ? VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT : VK_PIPELINE_STAGE_TRANSFER_BIT,
1161 VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
1162 0,
nullptr, 0,
nullptr, 1, &barrier);
1164 barrier.subresourceRange.baseMipLevel = i;
1165 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1166 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1167 barrier.srcAccessMask = 0;
1168 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1170 vkCmdPipelineBarrier(cmd,
1171 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
1172 0,
nullptr, 0,
nullptr, 1, &barrier);
1175 blit.srcOffsets[0] = {0, 0, 0};
1176 blit.srcOffsets[1] = {mipWidth, mipHeight, 1};
1177 blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1178 blit.srcSubresource.mipLevel = i - 1;
1179 blit.srcSubresource.baseArrayLayer = 0;
1180 blit.srcSubresource.layerCount = 1;
1182 blit.dstOffsets[0] = {0, 0, 0};
1183 blit.dstOffsets[1] = { mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1 };
1184 blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1185 blit.dstSubresource.mipLevel = i;
1186 blit.dstSubresource.baseArrayLayer = 0;
1187 blit.dstSubresource.layerCount = 1;
1190 m_r_context.compositeImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1191 m_r_context.compositeImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1192 1, &blit, VK_FILTER_LINEAR);
1194 barrier.subresourceRange.baseMipLevel = i - 1;
1195 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1196 barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1197 barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1198 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
1200 vkCmdPipelineBarrier(cmd,
1201 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
1202 0,
nullptr, 0,
nullptr, 1, &barrier);
1204 if (mipWidth > 1) mipWidth /= 2;
1205 if (mipHeight > 1) mipHeight /= 2;
1208 barrier.subresourceRange.baseMipLevel = 2;
1209 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1210 barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1211 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1212 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
1214 vkCmdPipelineBarrier(cmd,
1215 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
1216 0,
nullptr, 0,
nullptr, 1, &barrier);
1220 if (isEditorMode) [[unlikely]] {
1221 transitionImageLayout(cmd, m_r_context.gameViewImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1223 VkRenderingAttachmentInfo compAtt{};
1224 compAtt.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
1225 compAtt.imageView = m_r_context.gameViewView;
1226 compAtt.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1227 compAtt.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1228 compAtt.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1229 compAtt.clearValue.color = {{0.0f, 0.0f, 0.0f, 1.0f}};
1231 VkRenderingInfo compInfo{};
1232 compInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
1233 compInfo.renderArea.offset = {0, 0};
1234 compInfo.renderArea.extent = {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y};
1235 compInfo.layerCount = 1;
1236 compInfo.colorAttachmentCount = 1;
1237 compInfo.pColorAttachments = &compAtt;
1239 vkCmdBeginRendering(cmd, &compInfo);
1240 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_fullscreenPipeline->get());
1241 VkViewport viewport{};
1244 viewport.width =
static_cast<float>(m_r_context.currentRenderResolution.x);
1245 viewport.height =
static_cast<float>(m_r_context.currentRenderResolution.y);
1246 viewport.minDepth = 0.0f;
1247 viewport.maxDepth = 1.0f;
1248 vkCmdSetViewport(cmd, 0, 1, &viewport);
1249 VkRect2D scissor{{0, 0}, {m_r_context.currentRenderResolution.x, m_r_context.currentRenderResolution.y}};
1250 vkCmdSetScissor(cmd, 0, 1, &scissor);
1251 VkDescriptorSet sceneSet = m_p_resources->getUBODescriptorSet(data.frameIndex);
1252 uint32_t dynamicOffset = 0;
1253 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_fullscreenPipeline->layout(), 0, 1, &sceneSet, 1, &dynamicOffset);
1254 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_fullscreenPipeline->layout(), 1, 1, &m_crtDescriptorSet, 0,
nullptr);
1255 vkCmdDraw(cmd, 3, 1, 0, 0);
1256 vkCmdEndRendering(cmd);
1258 transitionImageLayout(cmd, m_r_context.gameViewImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1261 transitionImageLayout(cmd, m_r_context.swapchainImages[data.imageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1263 VkRenderingAttachmentInfo colorAttachment{};
1264 colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
1265 colorAttachment.imageView = m_r_context.swapchainImageViews[data.imageIndex];
1266 colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1267 colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1268 colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1269 colorAttachment.clearValue.color = {{0.0f, 0.0f, 0.0f, 1.0f}};
1271 VkRenderingInfo renderingInfo{};
1272 renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
1273 renderingInfo.renderArea.offset = {0, 0};
1274 renderingInfo.renderArea.extent = m_r_context.swapchainExtent;
1275 renderingInfo.layerCount = 1;
1276 renderingInfo.colorAttachmentCount = 1;
1277 renderingInfo.pColorAttachments = &colorAttachment;
1279 vkCmdBeginRendering(cmd, &renderingInfo);
1281 if (isEditorMode) [[unlikely]] {
1284 data.imguiTextureID = m_cachedImGuiDescriptor;
1287 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_fullscreenPipeline->get());
1289 VkViewport viewport{};
1292 viewport.width =
static_cast<float>(m_r_context.swapchainExtent.width);
1293 viewport.height =
static_cast<float>(m_r_context.swapchainExtent.height);
1294 viewport.minDepth = 0.0f;
1295 viewport.maxDepth = 1.0f;
1296 vkCmdSetViewport(cmd, 0, 1, &viewport);
1299 scissor.offset = {0, 0};
1300 scissor.extent = m_r_context.swapchainExtent;
1301 vkCmdSetScissor(cmd, 0, 1, &scissor);
1303 VkDescriptorSet sceneSet = m_p_resources->getUBODescriptorSet(data.frameIndex);
1304 uint32_t dynamicOffset = 0;
1305 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_fullscreenPipeline->layout(), 0, 1, &sceneSet, 1, &dynamicOffset);
1306 vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_p_fullscreenPipeline->layout(), 1, 1, &m_crtDescriptorSet, 0,
nullptr);
1307 vkCmdDraw(cmd, 3, 1, 0, 0);
1310 vkCmdEndRendering(cmd);
1311 transitionImageLayout(cmd, m_r_context.swapchainImages[data.imageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);