# all needed deps and SPIRV-Tools package is needed
SET(DALI_LDFLAGS ${DALI_LDFLAGS} ${GLSLANG_LDFLAGS} -lSPIRV ${SPIRVTOOLS_LDFLAGS} -lglslang-default-resource-limits)
ENDIF()
-
+ LIST(APPEND DALI_CFLAGS ${GLSLANG_CFLAGS})
ENDIF()
IF(LIBUV_X11_PROFILE)
{
return false;
}
- if(backgroundBlurRadius != blurInfo.backgroundBlurRadius)
+ if(backgroundCornerRadius != blurInfo.backgroundCornerRadius)
{
return false;
}
void WindowBlurInfo::SetCornerRadiusForBackground(int cornerRadius)
{
- backgroundBlurRadius = cornerRadius;
+ backgroundCornerRadius = cornerRadius;
}
int WindowBlurInfo::GetCornerRadiusForBackground() const
{
- return backgroundBlurRadius;
+ return backgroundCornerRadius;
}
} // namespace Dali
WindowBlurInfo()
: windowBlurType(WindowBlurType::NONE),
windowBlurRadius(0),
- backgroundBlurRadius(0)
+ backgroundCornerRadius(0)
{
}
explicit constexpr WindowBlurInfo(WindowBlurType type, int blurRadius, int cornerRadius)
: windowBlurType(type),
windowBlurRadius(blurRadius),
- backgroundBlurRadius(cornerRadius)
+ backgroundCornerRadius(cornerRadius)
{
}
explicit constexpr WindowBlurInfo(WindowBlurType type, int blurRadius)
: windowBlurType(type),
windowBlurRadius(blurRadius),
- backgroundBlurRadius(0)
+ backgroundCornerRadius(0)
{
}
public:
WindowBlurType windowBlurType;
int windowBlurRadius;
- int backgroundBlurRadius;
+ int backgroundCornerRadius;
};
} // namespace Dali
/*
-* Copyright (c) 2024 Samsung Electronics Co., Ltd.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-*/
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
#include <dali/integration-api/debug.h>
#include <dali/internal/graphics/common/shader-parser.h>
}
}
-} // namespace Dali::Internal::ShaderParser
\ No newline at end of file
+} // namespace Dali::Internal::ShaderParser
{
BufferImpl* BufferImpl::New(Device& device, size_t size, vk::BufferUsageFlags usageFlags)
{
- return New(device, size, vk::SharingMode(vk::SharingMode::eExclusive), usageFlags, vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible));
+ return New(device, size, vk::SharingMode(vk::SharingMode::eExclusive), usageFlags, vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent));
}
BufferImpl* BufferImpl::New(Device& device, size_t size, vk::SharingMode sharingMode, vk::BufferUsageFlags usageFlags, vk::MemoryPropertyFlags memoryProperties)
requirements.memoryTypeBits,
memoryProperties);
- mMemory = std::make_unique<MemoryImpl>(mDevice, size_t(requirements.size), size_t(requirements.alignment), ((memoryProperties & vk::MemoryPropertyFlagBits::eHostVisible) == vk::MemoryPropertyFlagBits::eHostVisible));
+ mMemory = std::make_unique<MemoryImpl>(mDevice, size_t(requirements.size), size_t(requirements.alignment), memoryProperties);
auto allocateInfo = vk::MemoryAllocateInfo{}
.setMemoryTypeIndex(memoryTypeIndex)
#include <dali/internal/graphics/vulkan-impl/vulkan-command-pool-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-image-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-pipeline-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-sampler-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-sampler.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-texture.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
#include <dali/internal/graphics/vulkan/vulkan-device.h>
// Bind if pipeline is ready (if nullptr, pipeline isn't ready).
// If pipeline is valid, bind it early
+
if(pipelineImpl.GetVkPipeline())
{
mCommandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipelineImpl.GetVkPipeline());
+
+ mCurrentProgram = pipelineImpl.GetProgram()->GetImplementation();
+ }
+ else
+ {
+ mCurrentProgram = nullptr;
+ }
+}
+
+void CommandBufferImpl::BindVertexBuffers(
+ uint32_t firstBinding,
+ const std::vector<BufferImpl*>& buffers,
+ const std::vector<uint32_t>& offsets)
+{
+ // update list of used resources and create an array of VkBuffers
+ std::vector<vk::Buffer> vkBuffers;
+ vkBuffers.reserve(buffers.size());
+ for(auto&& buffer : buffers)
+ {
+ vkBuffers.emplace_back(buffer->GetVkHandle());
+ }
+ std::vector<vk::DeviceSize> vkOffsets;
+ vkOffsets.reserve(offsets.size());
+ for(auto&& offset : offsets)
+ {
+ vkOffsets.emplace_back(static_cast<vk::DeviceSize>(offset));
+ }
+ mCommandBuffer.bindVertexBuffers(firstBinding, vkBuffers.size(), vkBuffers.data(), vkOffsets.data());
+}
+
+void CommandBufferImpl::BindIndexBuffer(
+ BufferImpl& buffer,
+ uint32_t offset,
+ Format format)
+{
+ if(format == Graphics::Format::R16_UINT)
+ {
+ mCommandBuffer.bindIndexBuffer(buffer.GetVkHandle(), offset, vk::IndexType::eUint16);
+ }
+ else if(format == Graphics::Format::R32_UINT)
+ {
+ mCommandBuffer.bindIndexBuffer(buffer.GetVkHandle(), offset, vk::IndexType::eUint32);
+ }
+}
+
+void CommandBufferImpl::BindUniformBuffers(const std::vector<UniformBufferBinding>& bindings)
+{
+ // Needs descriptor set pools.
+}
+
+void CommandBufferImpl::BindTextures(const std::vector<TextureBinding>& textureBindings)
+{
+ for(const auto& textureBinding : textureBindings)
+ {
+ auto texture = static_cast<const Vulkan::Texture*>(textureBinding.texture);
+ auto sampler = const_cast<Vulkan::Sampler*>(static_cast<const Vulkan::Sampler*>(textureBinding.sampler));
+ auto vkSampler = sampler ? sampler->GetImpl()->GetVkHandle() : nullptr;
+
+ auto image = texture->GetImage();
+ auto imageView = texture->GetImageView();
+
+ // test if image is valid, skip invalid image
+ if(!image || !image->GetVkHandle())
+ {
+ continue;
+ }
+
+ // Store: imageView, sampler & texture.binding for later use
+ // We don't know at this point what pipeline is bound (As dali-core
+ // binds the pipeline after calling this API)
+ mDeferredTextureBindings.emplace_back();
+ mDeferredTextureBindings.back().imageView = imageView->GetVkHandle();
+ mDeferredTextureBindings.back().sampler = vkSampler;
+ mDeferredTextureBindings.back().binding = textureBinding.binding;
}
}
+void CommandBufferImpl::BindSamplers(const std::vector<SamplerBinding>& samplerBindings)
+{
+ // Unused in core
+}
+
vk::CommandBuffer CommandBufferImpl::GetVkHandle() const
{
return mCommandBuffer;
uint32_t firstVertex,
uint32_t firstInstance)
{
+ // Example of deferred binding descriptors
+ if(mCurrentProgram)
+ {
+ auto set = mCurrentProgram->AllocateDescriptorSet(-1); // allocate from recent pool
+ if(set)
+ {
+ // bind resources here
+ }
+ }
+ mCommandBuffer.draw(vertexCount, instanceCount, firstVertex, firstInstance);
}
void CommandBufferImpl::DrawIndexed(uint32_t indexCount,
int32_t vertexOffset,
uint32_t firstInstance)
{
+ // Example of deferred binding descriptors
+ if(mCurrentProgram)
+ {
+ auto set = mCurrentProgram->AllocateDescriptorSet(-1); // allocate from recent pool
+ if(set)
+ {
+ // bind resources here
+ }
+ }
+ // draw here
+ mCommandBuffer.drawIndexed(indexCount,
+ instanceCount,
+ firstIndex,
+ static_cast<int32_t>(vertexOffset),
+ firstInstance);
+}
+
+void CommandBufferImpl::DrawIndexedIndirect(BufferImpl& buffer,
+ uint32_t offset,
+ uint32_t drawCount,
+ uint32_t stride)
+{
+ mCommandBuffer.drawIndexedIndirect(buffer.GetVkHandle(), static_cast<vk::DeviceSize>(offset), drawCount, stride);
+}
+
+void CommandBufferImpl::ExecuteCommandBuffers(std::vector<vk::CommandBuffer>& commandBuffers)
+{
+ mCommandBuffer.executeCommands(commandBuffers);
}
-void CommandBufferImpl::DrawIndexedIndirect(Graphics::Buffer& buffer,
- uint32_t offset,
- uint32_t drawCount,
- uint32_t stride)
+void CommandBufferImpl::SetScissor(Rect2D value)
{
+ mCommandBuffer.setScissor(0, 1, reinterpret_cast<vk::Rect2D*>(&value));
}
-void CommandBufferImpl::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
+void CommandBufferImpl::SetViewport(Viewport value)
{
+ mCommandBuffer.setViewport(0, 1, reinterpret_cast<vk::Viewport*>(&value));
}
} // namespace Vulkan
#include <dali/graphics-api/graphics-types.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-buffer-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-image-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-program-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
namespace Dali::Graphics::Vulkan
/** Final validation of the pipeline */
void ValidatePipeline();
+ void BindVertexBuffers(
+ uint32_t firstBinding,
+ const std::vector<Vulkan::BufferImpl*>& buffers,
+ const std::vector<uint32_t>& offsets);
+ void BindIndexBuffer(Vulkan::BufferImpl& buffer, uint32_t offset, Format format);
+ void BindUniformBuffers(const std::vector<UniformBufferBinding>& bindings);
+ void BindTextures(const std::vector<TextureBinding>& textureBindings);
+ void BindSamplers(const std::vector<SamplerBinding>& samplerBindings);
+
/** Returns Vulkan object associated with the buffer */
[[nodiscard]] vk::CommandBuffer GetVkHandle() const;
* @return Returns true if the command buffer is primary
*/
[[nodiscard]] bool IsPrimary() const;
-
/**
* Allows to issue custom VkRenderPassBeginInfo structure
* @param renderPassBeginInfo
*/
bool OnDestroy() override;
+ void SetScissor(Rect2D value);
+ void SetViewport(Viewport value);
+
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstInstance);
void DrawIndexedIndirect(
- Graphics::Buffer& buffer,
- uint32_t offset,
- uint32_t drawCount,
- uint32_t stride);
+ BufferImpl& buffer,
+ uint32_t offset,
+ uint32_t drawCount,
+ uint32_t stride);
- void ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers);
+ void ExecuteCommandBuffers(std::vector<vk::CommandBuffer>& commandBuffers);
private:
/**
const vk::CommandBufferAllocateInfo& allocateInfo,
vk::CommandBuffer vulkanHandle);
+private: // Struct for deferring texture binding
+ struct DeferredTextureBinding
+ {
+ vk::ImageView imageView;
+ vk::Sampler sampler;
+ uint32_t binding;
+ };
+
private:
- CommandPool* mOwnerCommandPool;
- Device* mGraphicsDevice;
- uint32_t mPoolAllocationIndex;
- vk::CommandBufferAllocateInfo mAllocateInfo{};
+ CommandPool* mOwnerCommandPool;
+ Device* mGraphicsDevice;
+ uint32_t mPoolAllocationIndex;
+ vk::CommandBufferAllocateInfo mAllocateInfo{};
+ std::vector<DeferredTextureBinding> mDeferredTextureBindings;
vk::CommandBuffer mCommandBuffer{};
+ Vulkan::ProgramImpl* mCurrentProgram{nullptr}; /// To test descriptor sets, will collide with other work
+
bool mRecording{false};
};
* limitations under the License.
*/
+#include <dali/internal/graphics/vulkan-impl/vulkan-buffer-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-buffer.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-command-buffer.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-command-pool-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-program-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-render-pass.h>
#include <dali/internal/graphics/vulkan/vulkan-device.h>
namespace Dali::Graphics::Vulkan
{
+template<typename VT, typename GT>
+VT* ConstGraphicsCast(const GT* object)
+{
+ return const_cast<VT*>(static_cast<const VT*>(object));
+}
+
CommandBuffer::CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, VulkanGraphicsController& controller)
: CommandBufferResource(createInfo, controller),
mCommandBufferImpl(nullptr)
{
if(mCommandBufferImpl)
{
- mCommandBufferImpl->Begin(static_cast<vk::CommandBufferUsageFlags>(info.usage), nullptr);
+ // Check if there is some extra information about used resources
+ // if so then apply optimizations
+ if(info.resourceBindings)
+ {
+ // update programs with descriptor pools
+ for(auto& binding : *info.resourceBindings)
+ {
+ if(binding.type == ResourceType::PROGRAM)
+ {
+ auto programImpl = static_cast<Vulkan::Program*>(binding.programBinding->program)->GetImplementation();
+
+ // Pool index is returned and we may do something with it later (storing it per cmdbuf?)
+ [[maybe_unused]] auto poolIndex = programImpl->AddDescriptorPool(binding.programBinding->count, 3); // add new pool, limit pools to 3 per program
+ }
+ }
+ }
+
+ vk::CommandBufferInheritanceInfo inheritanceInfo{};
+ if(info.renderPass)
+ {
+ auto renderTarget = ConstGraphicsCast<Vulkan::RenderTarget, Graphics::RenderTarget>(info.renderTarget);
+ inheritanceInfo.renderPass = renderTarget->GetRenderPass(info.renderPass)->GetVkHandle();
+ inheritanceInfo.subpass = 0;
+ inheritanceInfo.queryFlags = static_cast<vk::QueryControlFlags>(0);
+ inheritanceInfo.pipelineStatistics = static_cast<vk::QueryPipelineStatisticFlags>(0);
+ }
+ mCommandBufferImpl->Begin(static_cast<vk::CommandBufferUsageFlags>(info.usage), &inheritanceInfo);
}
}
}
void CommandBuffer::BindVertexBuffers(uint32_t firstBinding,
- const std::vector<const Graphics::Buffer*>& buffers,
+ const std::vector<const Graphics::Buffer*>& gfxBuffers,
const std::vector<uint32_t>& offsets)
{
+ std::vector<BufferImpl*> buffers;
+ buffers.reserve(gfxBuffers.size());
+ for(auto& gfxBuffer : gfxBuffers)
+ {
+ buffers.push_back(ConstGraphicsCast<Buffer, Graphics::Buffer>(gfxBuffer)->GetImpl());
+ }
+ mCommandBufferImpl->BindVertexBuffers(firstBinding, buffers, offsets);
+}
+
+void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& gfxBuffer,
+ uint32_t offset,
+ Format format)
+{
+ auto indexBuffer = ConstGraphicsCast<Buffer, Graphics::Buffer>(&gfxBuffer);
+ DALI_ASSERT_DEBUG(indexBuffer && indexBuffer->GetImpl());
+ mCommandBufferImpl->BindIndexBuffer(*indexBuffer->GetImpl(), offset, format);
}
void CommandBuffer::BindUniformBuffers(const std::vector<UniformBufferBinding>& bindings)
{
+ mCommandBufferImpl->BindUniformBuffers(bindings);
}
void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
void CommandBuffer::BindTextures(const std::vector<TextureBinding>& textureBindings)
{
+ mCommandBufferImpl->BindTextures(textureBindings);
}
void CommandBuffer::BindSamplers(const std::vector<SamplerBinding>& samplerBindings)
{
+ mCommandBufferImpl->BindSamplers(samplerBindings);
}
void CommandBuffer::BindPushConstants(void* data,
{
}
-void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer,
- uint32_t offset,
- Format format)
-{
-}
-
void CommandBuffer::BeginRenderPass(Graphics::RenderPass* gfxRenderPass,
Graphics::RenderTarget* gfxRenderTarget,
Rect2D renderArea,
mCommandBufferImpl->EndRenderPass();
}
-void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
+void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& gfxCommandBuffers)
{
+ std::vector<vk::CommandBuffer> vkCommandBuffers;
+ vkCommandBuffers.reserve(gfxCommandBuffers.size());
+ for(auto& gfxCmdBuf : gfxCommandBuffers)
+ {
+ vkCommandBuffers.push_back(ConstGraphicsCast<CommandBuffer, Graphics::CommandBuffer>(gfxCmdBuf)->GetImpl()->GetVkHandle());
+ }
+ mCommandBufferImpl->ExecuteCommandBuffers(vkCommandBuffers);
}
void CommandBuffer::Draw(uint32_t vertexCount,
mCommandBufferImpl->DrawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
-void CommandBuffer::DrawIndexedIndirect(Graphics::Buffer& buffer,
+void CommandBuffer::DrawIndexedIndirect(Graphics::Buffer& gfxBuffer,
uint32_t offset,
uint32_t drawCount,
uint32_t stride)
{
- mCommandBufferImpl->DrawIndexedIndirect(buffer, offset, drawCount, stride);
+ auto buffer = ConstGraphicsCast<Buffer, Graphics::Buffer>(&gfxBuffer)->GetImpl();
+
+ mCommandBufferImpl->DrawIndexedIndirect(*buffer, offset, drawCount, stride);
}
void CommandBuffer::DrawNative(const DrawNativeInfo* drawInfo)
void CommandBuffer::SetScissor(Rect2D value)
{
+ // @todo Vulkan accepts array of scissors... add to API
+ mCommandBufferImpl->SetScissor(value);
}
void CommandBuffer::SetScissorTestEnable(bool value)
{
+ // Enabled by default. What does disabling test do?!
+ // Probably should force pipeline to not use dynamic scissor state
}
void CommandBuffer::SetViewport(Viewport value)
{
+ mCommandBufferImpl->SetViewport(value);
}
void CommandBuffer::SetViewportEnable(bool value)
{
+ // Enabled by default. What does disabling test do?!
+ // Probably should force pipeline to not use dynamic viewport state
}
void CommandBuffer::SetColorMask(bool enabled)
{
namespace Vulkan
{
-
Image* Image::New(Device& graphicsDevice, const vk::ImageCreateInfo& createInfo)
{
auto image = new Image(graphicsDevice, createInfo, nullptr);
mMemory = std::make_unique<MemoryImpl>(mDevice,
size_t(requirements.size),
size_t(requirements.alignment),
- (memoryProperties & vk::MemoryPropertyFlagBits::eHostVisible) == vk::MemoryPropertyFlagBits::eHostVisible);
+ memoryProperties);
auto allocateInfo = vk::MemoryAllocateInfo{}
.setMemoryTypeIndex(memoryTypeIndex)
auto allocator = &mDevice.GetAllocator();
auto memory = mMemory->ReleaseVkObject();
- mDevice.DiscardResource([device, image, memory, allocator]()
- { DestroyVulkanResources(device, image, memory, allocator); });
+ mDevice.DiscardResource([device, image, memory, allocator]() { DestroyVulkanResources(device, image, memory, allocator); });
}
}
namespace Dali::Graphics::Vulkan
{
-
-MemoryImpl::MemoryImpl(Device& device, size_t memSize, size_t memAlign, bool isHostVisible)
+MemoryImpl::MemoryImpl(Device& device, size_t memSize, size_t memAlign, vk::MemoryPropertyFlags memoryProperties)
: mDevice(device),
deviceMemory(nullptr),
size(memSize),
alignment(memAlign),
mappedPtr(nullptr),
mappedSize(0u),
- hostVisible(isHostVisible)
+ mMemoryProperties(memoryProperties)
{
}
void MemoryImpl::Flush()
{
- vk::Result result = mDevice.GetLogicalDevice().flushMappedMemoryRanges({vk::MappedMemoryRange{}
- .setSize(mappedSize)
- .setMemory(deviceMemory)
- .setOffset(0u)});
- DALI_ASSERT_ALWAYS(result == vk::Result::eSuccess); // If it's out of memory, may as well crash.
+ // Don't flush if we are using host coherent memory - it's un-necessary
+ if((mMemoryProperties & vk::MemoryPropertyFlagBits::eHostCoherent) != vk::MemoryPropertyFlagBits::eHostCoherent)
+ {
+ vk::Result result = mDevice.GetLogicalDevice().flushMappedMemoryRanges({vk::MappedMemoryRange{}
+ .setSize(mappedSize ? mappedSize : VK_WHOLE_SIZE)
+ .setMemory(deviceMemory)
+ .setOffset(0u)});
+
+ DALI_ASSERT_ALWAYS(result == vk::Result::eSuccess); // If it's out of memory, may as well crash.
+ }
}
vk::DeviceMemory MemoryImpl::GetVkHandle() const
namespace Dali::Graphics::Vulkan
{
-
class MemoryImpl
{
public:
- MemoryImpl(Device& device, size_t memSize, size_t memAlign, bool hostVisible);
+ MemoryImpl(Device& device, size_t memSize, size_t memAlign, vk::MemoryPropertyFlags memoryProperties);
~MemoryImpl();
}
// No copy constructor or assignment operator
- MemoryImpl(MemoryImpl&) = delete;
+ MemoryImpl(MemoryImpl&) = delete;
MemoryImpl& operator=(MemoryImpl&) = delete;
void* Map();
[[nodiscard]] vk::DeviceMemory GetVkHandle() const;
private:
- Device& mDevice;
- vk::DeviceMemory deviceMemory;
- size_t size;
- size_t alignment;
- void* mappedPtr;
- size_t mappedSize;
- bool hostVisible;
+ Device& mDevice;
+ vk::DeviceMemory deviceMemory;
+ size_t size;
+ size_t alignment;
+ void* mappedPtr;
+ size_t mappedSize;
+ vk::MemoryPropertyFlags mMemoryProperties;
};
} // namespace Dali::Graphics::Vulkan
dynInfo.setDynamicStates(mDynamicStates);
gfxPipelineInfo.setPDynamicState(&dynInfo);
- auto& allocator = mController.GetGraphicsDevice().GetAllocator();
- auto rtImpl = static_cast<Vulkan::RenderTarget*>(mCreateInfo.renderTarget);
- auto framebuffer = rtImpl->GetFramebuffer();
- auto surface = rtImpl->GetSurface();
+ auto& allocator = mController.GetGraphicsDevice().GetAllocator();
+
+ auto rtImpl = static_cast<Vulkan::RenderTarget*>(mCreateInfo.renderTarget);
+
+ auto framebuffer = rtImpl->GetFramebuffer();
+ auto surface = rtImpl->GetSurface();
FramebufferImpl* fbImpl = nullptr;
if(surface)
}
}
+const Vulkan::Program* PipelineImpl::GetProgram() const
+{
+ return static_cast<const Vulkan::Program*>(mCreateInfo.programState->program);
+}
+
void PipelineImpl::InitializeVertexInputState(vk::PipelineVertexInputStateCreateInfo& out)
{
std::vector<vk::VertexInputBindingDescription> bindings;
void InitializePipeline();
+ const Vulkan::Program* GetProgram() const;
+
private:
void InitializeVertexInputState(vk::PipelineVertexInputStateCreateInfo& out);
void InitializeInputAssemblyState(vk::PipelineInputAssemblyStateCreateInfo& out) const;
#include <dali/internal/graphics/vulkan-impl/vulkan-reflection.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-shader-impl.h>
#include <dali/internal/graphics/vulkan-impl/vulkan-shader.h>
+#include <dali/internal/graphics/vulkan/vulkan-device.h>
// EXTERNAL HEADERS
#include <iostream>
std::unique_ptr<Vulkan::Reflection> reflection{nullptr};
std::vector<vk::PipelineShaderStageCreateInfo> mPipelineShaderStageCreateInfoList;
+
+ struct DescriptorPool
+ {
+ vk::DescriptorPoolCreateInfo createInfo;
+ vk::DescriptorPool vkPool;
+ };
+
+ std::vector<DescriptorPool> poolList;
+ int32_t currentPoolIndex{-1};
};
ProgramImpl::ProgramImpl(const Graphics::ProgramCreateInfo& createInfo, VulkanGraphicsController& controller)
return mImpl->mPipelineShaderStageCreateInfoList;
}
+[[nodiscard]] int ProgramImpl::AddDescriptorPool(uint32_t poolCapacity, uint32_t maxPoolCounts)
+{
+ auto& poolList = mImpl->poolList;
+ auto& poolIndex = mImpl->currentPoolIndex;
+ poolIndex %= maxPoolCounts;
+
+ auto& gfxDevice = mImpl->controller.GetGraphicsDevice();
+ auto& allocator = gfxDevice.GetAllocator();
+ auto vkDevice = gfxDevice.GetLogicalDevice();
+
+ if(poolCapacity != poolList.size())
+ {
+ poolList.resize(poolCapacity);
+ // should error if pool index exceeds pool capacity
+ }
+
+ // round-robin the pool index
+ Impl::DescriptorPool& descriptorPool = mImpl->poolList[poolIndex];
+
+ // if pool exists at index...
+ if(descriptorPool.vkPool)
+ {
+ // ...try to reuse the pool
+ if(descriptorPool.createInfo.maxSets >= poolCapacity)
+ {
+ vkDevice.resetDescriptorPool(descriptorPool.vkPool, vk::DescriptorPoolResetFlags{});
+ return poolIndex;
+ }
+
+ // ... else, destroy vulkan object
+ vkDevice.destroyDescriptorPool(descriptorPool.vkPool, &allocator);
+ }
+
+ descriptorPool.createInfo.setMaxSets(poolCapacity);
+ std::vector<vk::DescriptorPoolSize> poolSizes;
+
+ auto uniformBlockCount = GetReflection().GetUniformBlockCount();
+ auto samplersCount = GetReflection().GetSamplers().size();
+
+ if(uniformBlockCount)
+ {
+ vk::DescriptorPoolSize item;
+ item.setType(vk::DescriptorType::eUniformBuffer);
+ item.setDescriptorCount(uniformBlockCount * poolCapacity);
+ poolSizes.emplace_back(item);
+ }
+ if(samplersCount) // For now, we use only combined image sampler type as 'sampler'
+ {
+ vk::DescriptorPoolSize item;
+ item.setType(vk::DescriptorType::eCombinedImageSampler);
+ item.setDescriptorCount(samplersCount * poolCapacity);
+ poolSizes.emplace_back(item);
+ }
+
+ // set sizes
+ descriptorPool.createInfo.setPoolSizes(poolSizes);
+
+ // create pool
+ VkAssert(vkDevice.createDescriptorPool(&descriptorPool.createInfo, &allocator, &descriptorPool.vkPool));
+
+ return poolIndex;
+}
+
+[[nodiscard]] vk::DescriptorSet ProgramImpl::AllocateDescriptorSet(int poolIndex)
+{
+ // if pool index isn't specified, last added pool will be used
+ if(poolIndex < 0)
+ {
+ poolIndex = mImpl->currentPoolIndex;
+ }
+
+ auto& poolList = mImpl->poolList;
+ auto& gfxDevice = mImpl->controller.GetGraphicsDevice();
+ auto vkDevice = gfxDevice.GetLogicalDevice();
+
+ vk::DescriptorSetAllocateInfo allocateInfo;
+ allocateInfo.setDescriptorPool(poolList[poolIndex].vkPool);
+
+ auto& layouts = GetReflection().GetVkDescriptorSetLayouts();
+ allocateInfo.setSetLayouts(layouts);
+ // TODO: making sure only first layout will be use.
+ // Reflection supports multiple sets but current architecture of Vulkan backend
+ // uses single set only per pipeline/program
+ allocateInfo.setDescriptorSetCount(1);
+
+ vk::DescriptorSet set;
+ VkAssert(vkDevice.allocateDescriptorSets(&allocateInfo, &set));
+ return set;
+}
+
}; // namespace Dali::Graphics::Vulkan
*/
bool GetParameter(uint32_t parameterId, void* out);
+ /**
+ *
+ * @param[in] poolCapacity the capacity of pool
+ * @param maxPoolCounts number of pools, last added pool will be removed
+ * @return index of descriptor pool or -1 if unable to create pool
+ */
+ [[nodiscard]] int AddDescriptorPool(uint32_t poolCapacity, uint32_t maxPoolCounts);
+
+ [[nodiscard]] vk::DescriptorSet AllocateDescriptorSet(int poolIndex);
+
private:
friend class Program;
return mVkPipelineLayout;
}
+const std::vector<vk::DescriptorSetLayout>& Reflection::GetVkDescriptorSetLayouts() const
+{
+ return mVkDescriptorSetLayoutList;
+}
+
void Reflection::BuildVertexAttributeReflection(SpvReflectShaderModule* spvModule)
{
std::vector<SpvReflectInterfaceVariable*> attrs;
vk::PipelineLayout GetVkPipelineLayout() const;
+ const std::vector<vk::DescriptorSetLayout>& GetVkDescriptorSetLayouts() const;
+
protected:
Reflection(Reflection&&) = default;
Reflection& operator=(Reflection&&) = default;
std::vector<vk::DescriptorSetLayoutCreateInfo> mVkDescriptorSetLayoutCreateInfoList; ///< List of DSlayout create structures
std::vector<std::vector<vk::DescriptorSetLayoutBinding>> mVkDescriptorSetLayoutBindingList;
std::vector<vk::DescriptorSetLayout> mVkDescriptorSetLayoutList;
- vk::PipelineLayout mVkPipelineLayout;
+
+ vk::PipelineLayout mVkPipelineLayout;
};
} // namespace Vulkan
*/
// CLASS HEADER
-#include "vulkan-render-target.h"
+#include <dali/internal/graphics/vulkan-impl/vulkan-render-target.h>
// INTERNAL INCLUDES
#include <dali/integration-api/adaptor-framework/render-surface-interface.h>
-#include "vulkan-framebuffer.h"
-#include "vulkan-graphics-controller.h"
+#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-render-pass.h>
+#include <dali/internal/graphics/vulkan/vulkan-device.h>
+#include <dali/internal/window-system/common/window-render-surface.h>
namespace Dali::Graphics::Vulkan
{
return mCreateInfo.surface;
}
+Vulkan::RenderPassImpl* RenderTarget::GetRenderPass(const Graphics::RenderPass* gfxRenderPass) const
+{
+ auto renderPass = const_cast<Vulkan::RenderPass*>(static_cast<const Vulkan::RenderPass*>(gfxRenderPass));
+
+ auto framebuffer = GetFramebuffer();
+ auto surface = GetSurface();
+
+ FramebufferImpl* fbImpl = nullptr;
+ if(surface)
+ {
+ auto& gfxDevice = mController.GetGraphicsDevice();
+ auto surfaceId = static_cast<Internal::Adaptor::WindowRenderSurface*>(surface)->GetSurfaceId();
+ auto swapchain = gfxDevice.GetSwapchainForSurfaceId(surfaceId);
+ fbImpl = swapchain->GetCurrentFramebuffer();
+ }
+ else if(framebuffer)
+ {
+ fbImpl = framebuffer->GetImpl();
+ }
+
+ return fbImpl->GetRenderPass(renderPass);
+}
+
} // namespace Dali::Graphics::Vulkan
{
class Framebuffer;
class Surface;
+class RenderPassImpl;
using RenderTargetResource = Resource<Graphics::RenderTarget, Graphics::RenderTargetCreateInfo>;
*/
[[nodiscard]] Integration::RenderSurfaceInterface* GetSurface() const;
+ /**
+ * Find a matching render pass for this render target
+ * @param[in] renderPass A render pass to search for
+ * @return a matching render pass implementation from the current framebuffer
+ */
+ [[nodiscard]] Vulkan::RenderPassImpl* GetRenderPass(const Graphics::RenderPass* renderPass) const;
// Get Swapchain?
private:
// INTERNAL INCLUDES
#include <dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-sampler-impl.h>
namespace Dali::Graphics::Vulkan
{
+
+namespace
+{
+constexpr vk::Filter ConvertFilter(Dali::Graphics::SamplerFilter filter)
+{
+ switch(filter)
+ {
+ case Dali::Graphics::SamplerFilter::LINEAR:
+ return vk::Filter::eLinear;
+ case Dali::Graphics::SamplerFilter::NEAREST:
+ return vk::Filter::eNearest;
+ }
+ return vk::Filter{};
+}
+
+constexpr vk::SamplerAddressMode ConvertAddressMode(Dali::Graphics::SamplerAddressMode mode)
+{
+ switch(mode)
+ {
+ case Dali::Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
+ return vk::SamplerAddressMode::eClampToEdge;
+ case Dali::Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
+ return vk::SamplerAddressMode::eClampToBorder;
+ case Dali::Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
+ return vk::SamplerAddressMode::eMirrorClampToEdge;
+ case Dali::Graphics::SamplerAddressMode::MIRRORED_REPEAT:
+ return vk::SamplerAddressMode::eMirroredRepeat;
+ case Dali::Graphics::SamplerAddressMode::REPEAT:
+ return vk::SamplerAddressMode::eRepeat;
+ }
+ return vk::SamplerAddressMode{};
+}
+
+constexpr vk::SamplerMipmapMode ConvertMipmapMode(Dali::Graphics::SamplerMipmapMode mode)
+{
+ switch(mode)
+ {
+ case Dali::Graphics::SamplerMipmapMode::NONE:
+ return vk::SamplerMipmapMode::eNearest;
+ case Dali::Graphics::SamplerMipmapMode::LINEAR:
+ return vk::SamplerMipmapMode::eLinear;
+ case Dali::Graphics::SamplerMipmapMode::NEAREST:
+ return vk::SamplerMipmapMode::eNearest;
+ }
+ return vk::SamplerMipmapMode{};
+}
+
+} // namespace
+
Sampler::Sampler(const Graphics::SamplerCreateInfo& createInfo, VulkanGraphicsController& controller)
: SamplerResource(createInfo, controller)
{
bool Sampler::InitializeResource()
{
+ vk::SamplerCreateInfo createInfo{};
+ createInfo.setMinFilter(ConvertFilter(mCreateInfo.minFilter))
+ .setMagFilter(ConvertFilter(mCreateInfo.magFilter))
+ .setAddressModeU(ConvertAddressMode(mCreateInfo.addressModeU))
+ .setAddressModeV(ConvertAddressMode(mCreateInfo.addressModeV))
+ .setAddressModeW(ConvertAddressMode(mCreateInfo.addressModeW))
+ .setMipmapMode(ConvertMipmapMode(mCreateInfo.mipMapMode))
+ .setCompareEnable(vk::Bool32(mCreateInfo.compareEnable))
+ .setUnnormalizedCoordinates(vk::Bool32(mCreateInfo.unnormalizeCoordinates))
+ .setBorderColor(vk::BorderColor::eFloatOpaqueBlack)
+ .setAnisotropyEnable(vk::Bool32(mCreateInfo.anisotropyEnable))
+ .setMaxAnisotropy(mCreateInfo.maxAnisotropy)
+ .setMinLod(mCreateInfo.minLod)
+ .setMaxLod(mCreateInfo.maxLod);
+
+ mSamplerImpl = SamplerImpl::New(mController.GetGraphicsDevice(), createInfo);
+
return true;
}
namespace Dali::Graphics::Vulkan
{
using SamplerResource = Resource<Graphics::Sampler, Graphics::SamplerCreateInfo>;
+class SamplerImpl;
class Sampler : public SamplerResource
{
* @brief Called when UniquePtr<> on client-side dies
*/
void DiscardResource() override;
+
+ SamplerImpl* GetImpl()
+ {
+ return mSamplerImpl;
+ }
+
+private:
+ SamplerImpl* mSamplerImpl;
};
} // namespace Dali::Graphics::Vulkan
return 0;
}
+void WindowBaseAndroid::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseAndroid::GetBehindBlur()
+{
+ return 0;
+}
+
} // namespace Adaptor
} // namespace Internal
*/
bool RelativeMotionUnGrab() override;
-/**
+ /**
* @copydoc Dali::Internal::Adaptor::WindowBase::SetBackgroundBlur()
*/
void SetBackgroundBlur(int blurRadius, int cornerRadius) override;
-
/**
* @copydoc Dali::Internal::Adaptor::WindowBase::GetBackgroundBlur()
*/
int GetBackgroundBlur() override;
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+ */
+ void SetBehindBlur(int blurRadius) override;
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+ */
+ int GetBehindBlur() override;
+
private:
/**
* Second stage initialization
* @brief Set the window's background blur.
* If this value is 0, the background blur is disabled.
*
- * @param[in] blurRadius the background blur.
- * @param[in] cornerRadius the background blur.
+ * @param[in] blurRadius The radius of the blur effect.
+ * @param[in] cornerRadius The radius of the corner radius.
*/
virtual void SetBackgroundBlur(int blurRadius, int cornerRadius) = 0;
*/
virtual int GetBackgroundBlur() = 0;
+ /**
+ * @brief Set the window's behind blur.
+ * If this value is 0, the behind blur is disabled.
+ *
+ * @param[in] blurRadius The radius of the blur effect.
+ */
+ virtual void SetBehindBlur(int blurRadius) = 0;
+
+ /**
+ * @brief Returns current behind blur.
+ * If this value is 0, behind blur is disabled.
+ *
+ * @return current behind blur.
+ */
+ virtual int GetBehindBlur() = 0;
+
// Signals
/**
return false;
}
- auto callback = [handle = Dali::Window(this)](Dali::KeyEvent keyEvent, bool consumed) {
+ auto callback = [handle = Dali::Window(this)](Dali::KeyEvent keyEvent, bool consumed)
+ {
if(!consumed)
{
Dali::DevelKeyEvent::SetNoInterceptModifier(keyEvent, true);
if(mBlurInfo.windowBlurType == WindowBlurType::BACKGROUND)
{
- mWindowBase->SetBackgroundBlur(mBlurInfo.windowBlurRadius, mBlurInfo.backgroundBlurRadius);
+ mWindowBase->SetBackgroundBlur(mBlurInfo.windowBlurRadius, mBlurInfo.backgroundCornerRadius);
+ }
+ else if(mBlurInfo.windowBlurType == WindowBlurType::BEHIND)
+ {
+ mWindowBase->SetBehindBlur(mBlurInfo.windowBlurRadius);
}
else
{
mWindowBase->SetBackgroundBlur(0, 0);
}
- // TODO : When new Blur type is append, it will be added
}
WindowBlurInfo Window::GetBlur() const
std::string GetNativeWindowResourceId() override;
/**
- * @copydoc Dali::Internal::Adaptor::WindowBase::CreateWindow()
+ * @copydoc Dali::Internal::Adaptor::WindowBase::CreateWindow()
*/
Dali::Any CreateWindow(int width, int height) override;
*/
int GetBackgroundBlur() override;
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+ */
+ void SetBehindBlur(int blurRadius) override;
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+ */
+ int GetBehindBlur() override;
+
private:
// Undefined
WindowBaseCocoa(const WindowBaseCocoa&) = delete;
return 0;
}
+void WindowBaseCocoa::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseCocoa::GetBehindBlur()
+{
+ return 0;
+}
+
} // namespace Dali::Internal::Adaptor
@implementation CocoaView
return radius;
}
+void WindowBaseEcoreWl2::SetBehindBlur(int blurRadius)
+{
+ DALI_LOG_RELEASE_INFO("ecore_wl2_window_behind_blur_set, window: [%p], blur radius [%d]\n", mEcoreWindow, blurRadius);
+ START_DURATION_CHECK();
+ ecore_wl2_window_behind_blur_set(mEcoreWindow, blurRadius);
+ FINISH_DURATION_CHECK("ecore_wl2_window_behind_blur_set");
+}
+
+int WindowBaseEcoreWl2::GetBehindBlur()
+{
+ int radius = ecore_wl2_window_behind_blur_get(mEcoreWindow);
+ DALI_LOG_RELEASE_INFO("ecore_wl2_window_behind_blur_get, window: [%p], radius [%d]\n", mEcoreWindow, radius);
+ return radius;
+}
+
} // namespace Adaptor
} // namespace Internal
*/
int GetBackgroundBlur() override;
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+ */
+ void SetBehindBlur(int blurRadius) override;
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+ */
+ int GetBehindBlur() override;
+
private:
/**
* Second stage initialization
return 0;
}
+void WindowBaseEcoreX::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseEcoreX::GetBehindBlur()
+{
+ return 0;
+}
+
} // namespace Adaptor
} // namespace Internal
*/
int GetBackgroundBlur() override;
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+ */
+ void SetBehindBlur(int blurRadius) override;
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+ */
+ int GetBehindBlur() override;
private:
/**
* Second stage initialization
return 0;
}
+void WindowBaseWin::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseWin::GetBehindBlur()
+{
+ return 0;
+}
+
} // namespace Adaptor
} // namespace Internal
*/
int GetBackgroundBlur() override;
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+ */
+ void SetBehindBlur(int blurRadius) override;
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+ */
+ int GetBehindBlur() override;
private:
/**
* Second stage initialization
return 0;
}
+void WindowBaseX::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseX::GetBehindBlur()
+{
+ return 0;
+}
+
} // namespace Adaptor
} // namespace Internal
*/
int GetBackgroundBlur() override;
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+ */
+ void SetBehindBlur(int blurRadius) override;
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+ */
+ int GetBehindBlur() override;
private:
/**
* Second stage initialization
{
NONE = 0, ///< default value for blur disable
BACKGROUND, ///< the window's background
- // BEHIND, ///< the window's behind except background
- // BOTH, ///< both window's background and behind
+ BEHIND, ///< the window's behind except background
};
} // namespace Dali
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 3;
-const unsigned int ADAPTOR_MICRO_VERSION = 41;
+const unsigned int ADAPTOR_MICRO_VERSION = 42;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.3.41
+Version: 2.3.42
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT