diff options
author | 2017-05-02 14:01:43 -0400 | |
---|---|---|
committer | 2017-05-02 19:17:23 +0000 | |
commit | a754378ef659dcc0bca9179719123e32891fb605 (patch) | |
tree | a0b819d62ed0625e015baf2dcd42715a6ca8d9a9 | |
parent | 0dd30d99282c48cb3b5d50939a4b200ace6b8c71 (diff) |
Setup support for UNIFORM_TEXEL_BUFFER descriptor sets in Vulkan
This is the first CL to get support for using texel buffers in vulkan.
Bug: skia:
Change-Id: Iaac5ba4a356b487bc2b63111cca34ed968881f6b
Reviewed-on: https://skia-review.googlesource.com/15100
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | src/gpu/vk/GrVkCopyManager.cpp | 3 | ||||
-rw-r--r-- | src/gpu/vk/GrVkDescriptorSetManager.cpp | 117 | ||||
-rw-r--r-- | src/gpu/vk/GrVkDescriptorSetManager.h | 6 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineStateBuilder.cpp | 3 | ||||
-rw-r--r-- | src/gpu/vk/GrVkResourceProvider.cpp | 22 | ||||
-rw-r--r-- | src/gpu/vk/GrVkResourceProvider.h | 6 | ||||
-rw-r--r-- | src/gpu/vk/GrVkUniformHandler.h | 8 |
7 files changed, 110 insertions, 55 deletions
diff --git a/src/gpu/vk/GrVkCopyManager.cpp b/src/gpu/vk/GrVkCopyManager.cpp index 91c9b1a737..a33ada624a 100644 --- a/src/gpu/vk/GrVkCopyManager.cpp +++ b/src/gpu/vk/GrVkCopyManager.cpp @@ -97,7 +97,8 @@ bool GrVkCopyManager::createCopyProgram(GrVkGpu* gpu) { uint32_t samplerVisibility = kFragment_GrShaderFlag; SkTArray<uint32_t> visibilityArray(&samplerVisibility, 1); - resourceProvider.getSamplerDescriptorSetHandle(visibilityArray, &fSamplerDSHandle); + resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + visibilityArray, &fSamplerDSHandle); dsLayout[GrVkUniformHandler::kSamplerDescSet] = resourceProvider.getSamplerDSLayout(fSamplerDSHandle); diff --git a/src/gpu/vk/GrVkDescriptorSetManager.cpp b/src/gpu/vk/GrVkDescriptorSetManager.cpp index f523cee960..161e50b36f 100644 --- a/src/gpu/vk/GrVkDescriptorSetManager.cpp +++ b/src/gpu/vk/GrVkDescriptorSetManager.cpp @@ -16,13 +16,18 @@ GrVkDescriptorSetManager::GrVkDescriptorSetManager(GrVkGpu* gpu, VkDescriptorType type, const GrVkUniformHandler* uniformHandler) : fPoolManager(type, gpu, uniformHandler) { - if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { + if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type) { SkASSERT(uniformHandler); for (int i = 0; i < uniformHandler->numSamplers(); ++i) { fBindingVisibilities.push_back(uniformHandler->samplerVisibility(i)); } + } else if (VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type) { + SkASSERT(uniformHandler); + for (int i = 0; i < uniformHandler->numTexelBuffers(); ++i) { + fBindingVisibilities.push_back(uniformHandler->texelBufferVisibility(i)); + } } else { - SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + SkASSERT(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type); // We set the visibility of the first binding to the vertex shader and the second to the // fragment shader. fBindingVisibilities.push_back(kVertex_GrShaderFlag); @@ -34,12 +39,13 @@ GrVkDescriptorSetManager::GrVkDescriptorSetManager(GrVkGpu* gpu, VkDescriptorType type, const SkTArray<uint32_t>& visibilities) : fPoolManager(type, gpu, visibilities) { - if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { + if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type || + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type) { for (int i = 0; i < visibilities.count(); ++i) { fBindingVisibilities.push_back(visibilities[i]); } } else { - SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + SkASSERT(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type); SkASSERT(2 == visibilities.count() && kVertex_GrShaderFlag == visibilities[0] && kFragment_GrShaderFlag == visibilities[1]); @@ -106,6 +112,15 @@ bool GrVkDescriptorSetManager::isCompatible(VkDescriptorType type, return false; } } + } else if (VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type) { + if (fBindingVisibilities.count() != uniHandler->numTexelBuffers()) { + return false; + } + for (int i = 0; i < uniHandler->numSamplers(); ++i) { + if (uniHandler->texelBufferVisibility(i) != fBindingVisibilities[i]) { + return false; + } + } } return true; } @@ -116,7 +131,8 @@ bool GrVkDescriptorSetManager::isCompatible(VkDescriptorType type, return false; } - if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { + if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type || + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type) { if (fBindingVisibilities.count() != visibilities.count()) { return false; } @@ -166,54 +182,73 @@ GrVkDescriptorSetManager::DescriptorPoolManager::DescriptorPoolManager( this->init(gpu, type, nullptr, &visibilities); } +void GrVkDescriptorSetManager::DescriptorPoolManager::setupDescriptorLayout( + GrVkGpu* gpu, + VkDescriptorType type, + const GrVkUniformHandler* uniformHandler, + const SkTArray<uint32_t>* visibilities, + uint32_t numSamplers) { + SkASSERT(SkToBool(uniformHandler) != SkToBool(visibilities)); + std::unique_ptr<VkDescriptorSetLayoutBinding[]> dsSamplerBindings( + new VkDescriptorSetLayoutBinding[numSamplers]); + for (uint32_t i = 0; i < numSamplers; ++i) { + uint32_t visibility; + if (uniformHandler) { + if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { + visibility = uniformHandler->samplerVisibility(i); + } else { + SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER); + visibility = uniformHandler->texelBufferVisibility(i); + } + } else { + visibility = (*visibilities)[i]; + } + dsSamplerBindings[i].binding = i; + dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + dsSamplerBindings[i].descriptorCount = 1; + dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(visibility); + dsSamplerBindings[i].pImmutableSamplers = nullptr; + } + + VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo; + memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); + dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + dsSamplerLayoutCreateInfo.pNext = nullptr; + dsSamplerLayoutCreateInfo.flags = 0; + dsSamplerLayoutCreateInfo.bindingCount = numSamplers; + // Setting to nullptr fixes an error in the param checker validation layer. Even though + // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is + // null. + dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr; + + GR_VK_CALL_ERRCHECK(gpu->vkInterface(), + CreateDescriptorSetLayout(gpu->device(), + &dsSamplerLayoutCreateInfo, + nullptr, + &fDescLayout)); +} + void GrVkDescriptorSetManager::DescriptorPoolManager::init(GrVkGpu* gpu, VkDescriptorType type, const GrVkUniformHandler* uniformHandler, const SkTArray<uint32_t>* visibilities) { - if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { - SkASSERT(SkToBool(uniformHandler) != SkToBool(visibilities)); + if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type || + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type) { uint32_t numSamplers; if (uniformHandler) { - numSamplers = (uint32_t)uniformHandler->numSamplers(); - } else { - numSamplers = (uint32_t)visibilities->count(); - } - - std::unique_ptr<VkDescriptorSetLayoutBinding[]> dsSamplerBindings( - new VkDescriptorSetLayoutBinding[numSamplers]); - for (uint32_t i = 0; i < numSamplers; ++i) { - uint32_t visibility; - if (uniformHandler) { - visibility = uniformHandler->samplerVisibility(i); + if (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type) { + numSamplers = (uint32_t)uniformHandler->numSamplers(); } else { - visibility = (*visibilities)[i]; + numSamplers = (uint32_t)uniformHandler->numTexelBuffers(); } - dsSamplerBindings[i].binding = i; - dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - dsSamplerBindings[i].descriptorCount = 1; - dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(visibility); - dsSamplerBindings[i].pImmutableSamplers = nullptr; + } else { + numSamplers = (uint32_t)visibilities->count(); } + this->setupDescriptorLayout(gpu, type, uniformHandler, visibilities, numSamplers); - VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo; - memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo)); - dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - dsSamplerLayoutCreateInfo.pNext = nullptr; - dsSamplerLayoutCreateInfo.flags = 0; - dsSamplerLayoutCreateInfo.bindingCount = numSamplers; - // Setting to nullptr fixes an error in the param checker validation layer. Even though - // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is - // null. - dsSamplerLayoutCreateInfo.pBindings = numSamplers ? dsSamplerBindings.get() : nullptr; - - GR_VK_CALL_ERRCHECK(gpu->vkInterface(), - CreateDescriptorSetLayout(gpu->device(), - &dsSamplerLayoutCreateInfo, - nullptr, - &fDescLayout)); fDescCountPerSet = numSamplers; } else { - SkASSERT(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + SkASSERT(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type); // Create Uniform Buffer Descriptor // The vertex uniform buffer will have binding 0 and the fragment binding 1. VkDescriptorSetLayoutBinding dsUniBindings[kUniformDescPerSet]; diff --git a/src/gpu/vk/GrVkDescriptorSetManager.h b/src/gpu/vk/GrVkDescriptorSetManager.h index 84dd29ece0..bffee8c13c 100644 --- a/src/gpu/vk/GrVkDescriptorSetManager.h +++ b/src/gpu/vk/GrVkDescriptorSetManager.h @@ -85,6 +85,12 @@ private: const SkTArray<uint32_t>* visibilities); void getNewPool(GrVkGpu* gpu); + + void setupDescriptorLayout(GrVkGpu* gpu, + VkDescriptorType type, + const GrVkUniformHandler* uniformHandler, + const SkTArray<uint32_t>* visibilities, + uint32_t numSamplers); }; DescriptorPoolManager fPoolManager; diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp index 1363045bd6..ea0aa75300 100644 --- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp +++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp @@ -103,7 +103,8 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout(); GrVkDescriptorSetManager::Handle samplerDSHandle; - resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle); + resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + fUniformHandler, &samplerDSHandle); dsLayout[GrVkUniformHandler::kSamplerDescSet] = resourceProvider.getSamplerDSLayout(samplerDSHandle); diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp index 487633d3dc..4c4a2268f9 100644 --- a/src/gpu/vk/GrVkResourceProvider.cpp +++ b/src/gpu/vk/GrVkResourceProvider.cpp @@ -183,35 +183,37 @@ sk_sp<GrVkPipelineState> GrVkResourceProvider::findOrCreateCompatiblePipelineSta return fPipelineStateCache->refPipelineState(pipeline, proc, primitiveType, renderPass); } -void GrVkResourceProvider::getSamplerDescriptorSetHandle(const GrVkUniformHandler& uniformHandler, +void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type, + const GrVkUniformHandler& uniformHandler, GrVkDescriptorSetManager::Handle* handle) { SkASSERT(handle); + SkASSERT(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type || + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type); for (int i = 0; i < fDescriptorSetManagers.count(); ++i) { - if (fDescriptorSetManagers[i].isCompatible(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - &uniformHandler)) { + if (fDescriptorSetManagers[i].isCompatible(type, &uniformHandler)) { *handle = GrVkDescriptorSetManager::Handle(i); return; } } - fDescriptorSetManagers.emplace_back(fGpu, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - &uniformHandler); + fDescriptorSetManagers.emplace_back(fGpu, type, &uniformHandler); *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.count() - 1); } -void GrVkResourceProvider::getSamplerDescriptorSetHandle(const SkTArray<uint32_t>& visibilities, +void GrVkResourceProvider::getSamplerDescriptorSetHandle(VkDescriptorType type, + const SkTArray<uint32_t>& visibilities, GrVkDescriptorSetManager::Handle* handle) { SkASSERT(handle); + SkASSERT(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == type || + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == type); for (int i = 0; i < fDescriptorSetManagers.count(); ++i) { - if (fDescriptorSetManagers[i].isCompatible(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - visibilities)) { + if (fDescriptorSetManagers[i].isCompatible(type, visibilities)) { *handle = GrVkDescriptorSetManager::Handle(i); return; } } - fDescriptorSetManagers.emplace_back(fGpu, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - visibilities); + fDescriptorSetManagers.emplace_back(fGpu, type, visibilities); *handle = GrVkDescriptorSetManager::Handle(fDescriptorSetManagers.count() - 1); } diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h index 903223af8c..d0bbc3d5c2 100644 --- a/src/gpu/vk/GrVkResourceProvider.h +++ b/src/gpu/vk/GrVkResourceProvider.h @@ -106,9 +106,11 @@ public: GrPrimitiveType, const GrVkRenderPass& renderPass); - void getSamplerDescriptorSetHandle(const GrVkUniformHandler&, + void getSamplerDescriptorSetHandle(VkDescriptorType type, + const GrVkUniformHandler&, GrVkDescriptorSetManager::Handle* handle); - void getSamplerDescriptorSetHandle(const SkTArray<uint32_t>& visibilities, + void getSamplerDescriptorSetHandle(VkDescriptorType type, + const SkTArray<uint32_t>& visibilities, GrVkDescriptorSetManager::Handle* handle); // Returns the compatible VkDescriptorSetLayout to use for uniform buffers. The caller does not diff --git a/src/gpu/vk/GrVkUniformHandler.h b/src/gpu/vk/GrVkUniformHandler.h index 808eed7fb3..8cfd1a9da1 100644 --- a/src/gpu/vk/GrVkUniformHandler.h +++ b/src/gpu/vk/GrVkUniformHandler.h @@ -19,6 +19,7 @@ public: enum { kUniformBufferDescSet = 0, kSamplerDescSet = 1, + kTexelBufferDescSet = 2, }; enum { kVertexBinding = 0, @@ -46,6 +47,7 @@ private: : INHERITED(program) , fUniforms(kUniformsPerBlock) , fSamplers(kUniformsPerBlock) + , fTexelBuffers(kUniformsPerBlock) , fCurrentVertexUBOOffset(0) , fCurrentFragmentUBOOffset(0) , fCurrentSamplerBinding(0) { @@ -76,6 +78,11 @@ private: return fSamplers[handle.toIndex()].fVisibility; } + int numTexelBuffers() const { return fTexelBuffers.count(); } + uint32_t texelBufferVisibility(SamplerHandle handle) const { + return fTexelBuffers[handle.toIndex()].fVisibility; + } + ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType, GrImageStorageFormat, GrSLMemoryModel, GrSLRestrict, GrIOType, const char* name) override { @@ -103,6 +110,7 @@ private: UniformInfoArray fUniforms; UniformInfoArray fSamplers; SkTArray<GrSwizzle> fSamplerSwizzles; + UniformInfoArray fTexelBuffers; uint32_t fCurrentVertexUBOOffset; uint32_t fCurrentFragmentUBOOffset; |