diff --git a/src/rendering/vulkan/system/vk_builders.h b/src/rendering/vulkan/system/vk_builders.h index d50caaf2cf..b42a929469 100644 --- a/src/rendering/vulkan/system/vk_builders.h +++ b/src/rendering/vulkan/system/vk_builders.h @@ -41,6 +41,7 @@ public: void setSize(int width, int height, int miplevels = 1); void setFormat(VkFormat format); void setUsage(VkImageUsageFlags imageUsage, VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_GPU_ONLY); + void setLinearTiling(); std::unique_ptr create(VulkanDevice *device); @@ -331,6 +332,11 @@ inline void ImageBuilder::setFormat(VkFormat format) imageInfo.format = format; } +inline void ImageBuilder::setLinearTiling() +{ + imageInfo.tiling = VK_IMAGE_TILING_LINEAR; +} + inline void ImageBuilder::setUsage(VkImageUsageFlags usage, VmaMemoryUsage memoryUsage) { imageInfo.usage = usage; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index c75b4592c7..03ea17eb9f 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -37,6 +37,8 @@ #include "hwrenderer/data/shaderuniforms.h" #include "hwrenderer/dynlights/hw_lightbuffer.h" +#include "swrenderer/r_swscene.h" + #include "vk_framebuffer.h" #include "vk_buffers.h" #include "vulkan/renderer/vk_renderstate.h" @@ -119,9 +121,6 @@ void VulkanFrameBuffer::Update() device->beginFrame(); - mPresentCommands = mGraphicsCommandPool->createBuffer(); - mPresentCommands->begin(); - Draw2D(); Clear2D(); @@ -133,7 +132,7 @@ void VulkanFrameBuffer::Update() PipelineBarrier barrier0; barrier0.addImage(sceneColor, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); - barrier0.execute(mPresentCommands.get(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + barrier0.execute(GetDrawCommands(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); VkImageBlit blit = {}; blit.srcOffsets[0] = { 0, 0, 0 }; @@ -148,13 +147,13 @@ void VulkanFrameBuffer::Update() blit.dstSubresource.mipLevel = 0; blit.dstSubresource.baseArrayLayer = 0; blit.dstSubresource.layerCount = 1; - mPresentCommands->blitImage( + GetDrawCommands()->blitImage( sceneColor->image, VK_IMAGE_LAYOUT_GENERAL, device->swapChain->swapChainImages[device->presentImageIndex], VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, 1, &blit, VK_FILTER_NEAREST); } - mPresentCommands->end(); + mDrawCommands->end(); if (mUploadCommands) { @@ -178,7 +177,7 @@ void VulkanFrameBuffer::Update() submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &mPresentCommands->buffer; + submitInfo.pCommandBuffers = &mDrawCommands->buffer; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &device->renderFinishedSemaphore->semaphore; result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, device->renderFinishedFence->fence); @@ -196,7 +195,7 @@ void VulkanFrameBuffer::Update() submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &mPresentCommands->buffer; + submitInfo.pCommandBuffers = &mDrawCommands->buffer; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &device->renderFinishedSemaphore->semaphore; VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, device->renderFinishedFence->fence); @@ -211,7 +210,7 @@ void VulkanFrameBuffer::Update() device->presentFrame(); device->waitPresent(); - mPresentCommands.reset(); + mDrawCommands.reset(); mUploadCommands.reset(); mFrameDeleteList.clear(); @@ -228,7 +227,18 @@ void VulkanFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int wid sector_t *VulkanFrameBuffer::RenderView(player_t *player) { - return nullptr; + mRenderState->SetVertexBuffer(screen->mVertexData); + screen->mVertexData->Reset(); + + if (!V_IsHardwareRenderer()) + { + if (!swdrawer) swdrawer.reset(new SWSceneDrawer); + return swdrawer->RenderView(player); + } + else + { + return nullptr; + } } uint32_t VulkanFrameBuffer::GetCaps() @@ -337,5 +347,10 @@ VulkanCommandBuffer *VulkanFrameBuffer::GetUploadCommands() VulkanCommandBuffer *VulkanFrameBuffer::GetDrawCommands() { - return mPresentCommands.get(); + if (!mDrawCommands) + { + mDrawCommands = mGraphicsCommandPool->createBuffer(); + mDrawCommands->begin(); + } + return mDrawCommands.get(); } diff --git a/src/rendering/vulkan/system/vk_framebuffer.h b/src/rendering/vulkan/system/vk_framebuffer.h index 8e9bf18d25..b2d83235ad 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.h +++ b/src/rendering/vulkan/system/vk_framebuffer.h @@ -10,6 +10,7 @@ class VkRenderPassManager; class VkRenderState; class VKDataBuffer; class VkHardwareTexture; +class SWSceneDrawer; class VulkanFrameBuffer : public SystemBaseFrameBuffer { @@ -34,6 +35,8 @@ public: std::vector> mFrameDeleteList; + std::unique_ptr swdrawer; + VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev); ~VulkanFrameBuffer(); @@ -75,7 +78,7 @@ private: std::unique_ptr mRenderPassManager; std::unique_ptr mGraphicsCommandPool; std::unique_ptr mUploadCommands; - std::unique_ptr mPresentCommands; + std::unique_ptr mDrawCommands; std::unique_ptr mUploadSemaphore; std::unique_ptr mRenderState; diff --git a/src/rendering/vulkan/system/vk_objects.h b/src/rendering/vulkan/system/vk_objects.h index 959a356905..2fdbf14d44 100644 --- a/src/rendering/vulkan/system/vk_objects.h +++ b/src/rendering/vulkan/system/vk_objects.h @@ -78,6 +78,9 @@ public: int height = 0; int mipLevels = 1; + void *Map(size_t offset, size_t size); + void Unmap(); + private: VulkanDevice *device = nullptr; VmaAllocation allocation; @@ -881,6 +884,18 @@ inline VulkanImage::~VulkanImage() vmaDestroyImage(device->allocator, image, allocation); } +inline void *VulkanImage::Map(size_t offset, size_t size) +{ + void *data; + VkResult result = vmaMapMemory(device->allocator, allocation, &data); + return (result == VK_SUCCESS) ? data : nullptr; +} + +inline void VulkanImage::Unmap() +{ + vmaUnmapMemory(device->allocator, allocation); +} + ///////////////////////////////////////////////////////////////////////////// inline VulkanImageView::VulkanImageView(VulkanDevice *device, VkImageView view) : device(device), view(view) diff --git a/src/rendering/vulkan/textures/vk_hwtexture.cpp b/src/rendering/vulkan/textures/vk_hwtexture.cpp index e282fded28..9ee3b6edd7 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/rendering/vulkan/textures/vk_hwtexture.cpp @@ -104,7 +104,7 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s mDescriptorSet = fb->GetRenderPassManager()->DescriptorPool->allocate(fb->GetRenderPassManager()->TextureSetLayout.get()); WriteDescriptors update; - update.addCombinedImageSampler(mDescriptorSet.get(), 0, mImageView.get(), fb->GetSamplerManager()->Get(0), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + update.addCombinedImageSampler(mDescriptorSet.get(), 0, mImageView.get(), fb->GetSamplerManager()->Get(0), mImageLayout); update.updateSets(fb->device); } @@ -207,6 +207,44 @@ int VkHardwareTexture::GetMipLevels(int w, int h) return levels; } +void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize) +{ + if (!mImage) + { + auto fb = GetVulkanFrameBuffer(); + + ImageBuilder imgbuilder; + imgbuilder.setFormat(VK_FORMAT_B8G8R8A8_UNORM); + imgbuilder.setSize(w, h); + imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU); + imgbuilder.setLinearTiling(); + mImage = imgbuilder.create(fb->device); + mImageLayout = VK_IMAGE_LAYOUT_GENERAL; + mTexelsize = texelsize; + + ImageViewBuilder viewbuilder; + viewbuilder.setImage(mImage.get(), texelsize == 4 ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_R8_UNORM); + mImageView = viewbuilder.create(fb->device); + + auto cmdbuffer = fb->GetUploadCommands(); + + PipelineBarrier imageTransition; + imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, mImageLayout, 0, VK_ACCESS_SHADER_READ_BIT); + imageTransition.execute(cmdbuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + } +} + +uint8_t *VkHardwareTexture::MapBuffer() +{ + return (uint8_t*)mImage->Map(0, mImage->width * mImage->height * mTexelsize); +} + +unsigned int VkHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) +{ + mImage->Unmap(); + return 0; +} + #if 0 //=========================================================================== diff --git a/src/rendering/vulkan/textures/vk_hwtexture.h b/src/rendering/vulkan/textures/vk_hwtexture.h index 3a7b8a977f..3cecd427e3 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.h +++ b/src/rendering/vulkan/textures/vk_hwtexture.h @@ -28,9 +28,9 @@ public: VulkanDescriptorSet *GetDescriptorSet(const FMaterialState &state); // Software renderer stuff - void AllocateBuffer(int w, int h, int texelsize) override { } - uint8_t *MapBuffer() override { return nullptr; } - unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) override { return 0; } + void AllocateBuffer(int w, int h, int texelsize) override; + uint8_t *MapBuffer() override; + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) override; private: void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels); @@ -41,6 +41,8 @@ private: std::unique_ptr mImage; std::unique_ptr mImageView; std::unique_ptr mStagingBuffer; + VkImageLayout mImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + int mTexelsize = 4; }; #if 0