Skip to content

Commit 4f25fcb

Browse files
committed
GPU Vulkan Display: Add optional support for smooth lines
1 parent 70ce4e5 commit 4f25fcb

2 files changed

Lines changed: 24 additions & 10 deletions

File tree

‎GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx‎

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,8 @@ void GPUDisplayBackendVulkan::createDevice()
537537
if (checkDevice(mPhysicalDevice, reqDeviceExtensions, reqDeviceFeatures, true) <= 0) {
538538
throw std::runtime_error("Selected vulkan device is incompatible");
539539
}
540+
mSmoothLinesSupported = getFeatures(mPhysicalDevice, reqDeviceFeatures).get<vk::PhysicalDeviceVulkan14Features>().smoothLines;
541+
reqDeviceFeatures.get<vk::PhysicalDeviceVulkan14Features>().smoothLines = mSmoothLinesSupported;
540542

541543
updateSwapChainDetails(mPhysicalDevice);
542544
vk::PhysicalDeviceProperties deviceProperties = mPhysicalDevice.getProperties();
@@ -548,7 +550,7 @@ void GPUDisplayBackendVulkan::createDevice()
548550
mStencilSupported = (bool)(depth64FormatProperties.optimalTilingFeatures & vk::FormatFeatureFlagBits::eDepthStencilAttachment);
549551
bool mailboxSupported = std::find(mSwapChainDetails.presentModes.begin(), mSwapChainDetails.presentModes.end(), vk::PresentModeKHR::eMailbox) != mSwapChainDetails.presentModes.end();
550552
if (mDisplay->GetProcessingSettings().debugLevel >= 2) {
551-
GPUInfo("Max MSAA: %d, 32 bit Z buffer %d, 32 bit Z buffer + stencil buffer %d, Mailbox present mode %d\n", (int32_t)mMaxMSAAsupported, (int32_t)mZSupported, (int32_t)mStencilSupported, (int32_t)mailboxSupported);
553+
GPUInfo("Max MSAA: %d, 32 bit Z buffer %d, 32 bit Z buffer + stencil buffer %d, Mailbox present mode %d, smooth lines %d\n", (int32_t)mMaxMSAAsupported, (int32_t)mZSupported, (int32_t)mStencilSupported, (int32_t)mailboxSupported, (int32_t)mSmoothLinesSupported);
552554
}
553555

554556
vk::DeviceQueueCreateInfo queueCreateInfo{};
@@ -796,24 +798,27 @@ void GPUDisplayBackendVulkan::recreateRendering(bool forScreenshot, bool forMixi
796798
needRecordCommandBuffers();
797799
const bool needUpdateSwapChain = mMustUpdateSwapChain;
798800
const bool needUpdateOffscreenBuffers = needUpdateSwapChain || mDownsampleFactor != getDownsampleFactor(forScreenshot) || mMSAASampleCount != getMSAASamplesFlag(std::min<uint32_t>(mMaxMSAAsupported, mDisplay->cfgR().drawQualityMSAA)) || mZActive != (mZSupported && mDisplay->cfgL().depthBuffer) || mMixingSupported != forMixing;
799-
if (!needUpdateOffscreenBuffers) {
801+
const bool smoothLinesChanged = mSmoothLines != (mSmoothLinesSupported && mDisplay->cfgL().smoothLines);
802+
if (!needUpdateOffscreenBuffers && !smoothLinesChanged) {
800803
return;
801804
}
802805
mDevice.waitIdle();
803806
const vk::Format oldFormat = mSurfaceFormat.format;
804807
const vk::SampleCountFlagBits oldMSAASampleCount = mMSAASampleCount;
805808
const bool oldZActive = mZActive;
806-
clearOffscreenBuffers();
807-
if (needUpdateSwapChain) {
808-
clearSwapChain(true);
809-
createSwapChain(mSwapChain);
809+
if (needUpdateOffscreenBuffers) {
810+
clearOffscreenBuffers();
811+
if (needUpdateSwapChain) {
812+
clearSwapChain(true);
813+
createSwapChain(mSwapChain);
814+
}
815+
createOffscreenBuffers(forScreenshot, forMixing);
816+
mUpdateUBOtextMatrix = mUpdateUBOmixMatrix = -1; // Screen / render size may have changed
810817
}
811-
createOffscreenBuffers(forScreenshot, forMixing);
812-
if (mSurfaceFormat.format != oldFormat || mMSAASampleCount != oldMSAASampleCount || mZActive != oldZActive) { // Viewport / scissor are dynamic
818+
if (mSurfaceFormat.format != oldFormat || mMSAASampleCount != oldMSAASampleCount || mZActive != oldZActive || smoothLinesChanged) { // Viewport / scissor are dynamic
813819
clearPipeline();
814820
createPipeline();
815821
}
816-
mUpdateUBOtextMatrix = mUpdateUBOmixMatrix = -1; // Screen / render size may have changed
817822
}
818823

819824
// ---------------------------- VULKAN OFFSCREEN BUFFERS ----------------------------
@@ -1022,10 +1027,15 @@ void GPUDisplayBackendVulkan::createPipeline()
10221027
pipelineInfo.basePipelineHandle = VkPipeline(VK_NULL_HANDLE); // Optional
10231028
pipelineInfo.basePipelineIndex = -1; // Optional
10241029

1030+
mSmoothLines = mSmoothLinesSupported && mDisplay->cfgL().smoothLines;
1031+
vk::PipelineRasterizationLineStateCreateInfo smoothLineState{};
1032+
smoothLineState.lineRasterizationMode = vk::LineRasterizationMode::eRectangularSmooth; // Coverage goes to alpha, blending is enabled
1033+
10251034
mPipelines.resize(5);
10261035
static constexpr vk::PrimitiveTopology types[3] = {vk::PrimitiveTopology::ePointList, vk::PrimitiveTopology::eLineList, vk::PrimitiveTopology::eLineStrip};
10271036
for (uint32_t i = 0; i < mPipelines.size(); i++) {
10281037
if (i == 4) { // Texture rendering
1038+
rasterizer.pNext = nullptr;
10291039
bindingDescription.stride = 4 * sizeof(float);
10301040
attributeDescriptions.format = vk::Format::eR32G32B32A32Sfloat;
10311041
inputAssembly.topology = vk::PrimitiveTopology::eTriangleList;
@@ -1038,6 +1048,7 @@ void GPUDisplayBackendVulkan::createPipeline()
10381048
colorBlendAttachment.blendEnable = true;
10391049
multisampling.rasterizationSamples = vk::SampleCountFlagBits::e1;
10401050
} else if (i == 3) { // Text rendering
1051+
rasterizer.pNext = nullptr;
10411052
bindingDescription.stride = 4 * sizeof(float);
10421053
attributeDescriptions.format = vk::Format::eR32G32B32A32Sfloat;
10431054
inputAssembly.topology = vk::PrimitiveTopology::eTriangleList;
@@ -1053,6 +1064,7 @@ void GPUDisplayBackendVulkan::createPipeline()
10531064
bindingDescription.stride = 3 * sizeof(float);
10541065
attributeDescriptions.format = vk::Format::eR32G32B32Sfloat;
10551066
inputAssembly.topology = types[i];
1067+
rasterizer.pNext = mSmoothLines && types[i] != vk::PrimitiveTopology::ePointList ? &smoothLineState : nullptr;
10561068
vertShaderStageInfo.module = mShaders[types[i] == vk::PrimitiveTopology::ePointList ? "vertexPoint" : "vertex"];
10571069
fragShaderStageInfo.module = mShaders["fragment"];
10581070
pipelineInfo.layout = mPipelineLayout;
@@ -1374,7 +1386,7 @@ void GPUDisplayBackendVulkan::prepareDraw(const hmm_mat4& proj, const hmm_mat4&
13741386
};
13751387

13761388
vk::Result retVal = vk::Result::eSuccess;
1377-
bool mustUpdateSwapChain = mMustUpdateSwapChain || mDisplay->updateRenderPipeline() || (toMixBuffer && !mMixingSupported) || mDownsampleFactor != getDownsampleFactor(requestScreenshot);
1389+
bool mustUpdateSwapChain = mMustUpdateSwapChain || mDisplay->updateRenderPipeline() || (toMixBuffer && !mMixingSupported) || mDownsampleFactor != getDownsampleFactor(requestScreenshot) || mSmoothLines != (mSmoothLinesSupported && mDisplay->cfgL().smoothLines);
13781390
if (!mustUpdateSwapChain) {
13791391
retVal = getImage();
13801392
if (retVal == vk::Result::eErrorOutOfDateKHR) {

‎GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend
207207
vk::SampleCountFlagBits mMSAASampleCount = vk::SampleCountFlagBits::e16;
208208
uint32_t mMaxMSAAsupported = 0;
209209
bool mZActive = false;
210+
bool mSmoothLinesSupported = false; // Optional Vulkan 1.4 feature smoothLines, enabled if available
211+
bool mSmoothLines = false;
210212
bool mZSupported = false;
211213
bool mStencilSupported = false;
212214
bool mDownsampleFSAA = false;

0 commit comments

Comments
 (0)