vulkan: suppress sampler field of VkDescriptorImageInfo (guest)
when in the immutable sampler case.
Test: vulkanhal_unittests (needs host side CL)
dEQP-VK.ycbcr* in 64 bit mode
dEQP-VK.binding_model*
bug: 145153816
Change-Id: I84fd8b4f2630b86e80da987b3e010824392599c3
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 99e7735..92f8965 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -335,6 +335,11 @@
struct VkDescriptorSet_Info {
VkDescriptorPool pool;
+ std::vector<bool> bindingIsImmutableSampler;
+ };
+
+ struct VkDescriptorSetLayout_Info {
+ std::vector<VkDescriptorSetLayoutBinding> bindings;
};
#define HANDLE_REGISTER_IMPL_IMPL(type) \
@@ -499,7 +504,12 @@
unregister_VkDescriptorSet_locked(set);
}
- void addAllocedDescriptorSetsToPoolLocked(const VkDescriptorSetAllocateInfo* ci, const VkDescriptorSet* sets) {
+ void unregister_VkDescriptorSetLayout(VkDescriptorSetLayout setLayout) {
+ AutoLock lock(mLock);
+ info_VkDescriptorSetLayout.erase(setLayout);
+ }
+
+ void initDescriptorSetStateLocked(const VkDescriptorSetAllocateInfo* ci, const VkDescriptorSet* sets) {
auto it = info_VkDescriptorPool.find(ci->descriptorPool);
if (it == info_VkDescriptorPool.end()) return;
@@ -512,9 +522,67 @@
auto& setInfo = setIt->second;
setInfo.pool = ci->descriptorPool;
+
+ VkDescriptorSetLayout setLayout = ci->pSetLayouts[i];
+ auto layoutIt = info_VkDescriptorSetLayout.find(setLayout);
+ if (layoutIt == info_VkDescriptorSetLayout.end()) continue;
+
+ const auto& layoutInfo = layoutIt->second;
+ for (size_t i = 0; i < layoutInfo.bindings.size(); ++i) {
+ // Bindings can be sparsely defined
+ const auto& binding = layoutInfo.bindings[i];
+ uint32_t bindingIndex = binding.binding;
+ if (setInfo.bindingIsImmutableSampler.size() <= bindingIndex) {
+ setInfo.bindingIsImmutableSampler.resize(bindingIndex + 1, false);
+ }
+ setInfo.bindingIsImmutableSampler[bindingIndex] =
+ binding.descriptorCount > 0 &&
+ (binding.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
+ binding.descriptorType ==
+ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
+ binding.pImmutableSamplers;
+ }
}
}
+ VkWriteDescriptorSet
+ createImmutableSamplersFilteredWriteDescriptorSetLocked(
+ const VkWriteDescriptorSet* descriptorWrite,
+ std::vector<VkDescriptorImageInfo>* imageInfoArray) {
+
+ VkWriteDescriptorSet res = *descriptorWrite;
+
+ if (descriptorWrite->descriptorCount == 0) return res;
+
+ if (descriptorWrite->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER &&
+ descriptorWrite->descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) return res;
+
+ VkDescriptorSet set = descriptorWrite->dstSet;
+ auto descSetIt = info_VkDescriptorSet.find(set);
+ if (descSetIt == info_VkDescriptorSet.end()) {
+ ALOGE("%s: error: descriptor set 0x%llx not found\n", __func__,
+ (unsigned long long)set);
+ return res;
+ }
+
+ const auto& descInfo = descSetIt->second;
+ uint32_t binding = descriptorWrite->dstBinding;
+
+ bool immutableSampler = descInfo.bindingIsImmutableSampler[binding];
+
+ if (!immutableSampler) return res;
+
+ for (uint32_t i = 0; i < descriptorWrite->descriptorCount; ++i) {
+ VkDescriptorImageInfo imageInfo = descriptorWrite->pImageInfo[i];
+ imageInfo.sampler = 0;
+ imageInfoArray->push_back(imageInfo);
+ }
+
+ res.pImageInfo = imageInfoArray->data();
+
+ return res;
+ }
+
// Also unregisters underlying descriptor sets
// and deletes their guest-side wrapped handles.
void clearDescriptorPoolLocked(VkDescriptorPool pool) {
@@ -3149,7 +3217,7 @@
if (res != VK_SUCCESS) return res;
AutoLock lock(mLock);
- addAllocedDescriptorSetsToPoolLocked(pAllocateInfo, pDescriptorSets);
+ initDescriptorSetStateLocked(pAllocateInfo, pDescriptorSets);
return res;
}
@@ -3190,6 +3258,64 @@
toActuallyFree.data());
}
+ VkResult on_vkCreateDescriptorSetLayout(
+ void* context,
+ VkResult,
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorSetLayout* pSetLayout) {
+
+ VkEncoder* enc = (VkEncoder*)context;
+
+ VkResult res = enc->vkCreateDescriptorSetLayout(
+ device, pCreateInfo, pAllocator, pSetLayout);
+
+ if (res != VK_SUCCESS) return res;
+
+ AutoLock lock(mLock);
+
+ auto it = info_VkDescriptorSetLayout.find(*pSetLayout);
+ if (it == info_VkDescriptorSetLayout.end()) return res;
+
+ auto& info = it->second;
+ for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
+ info.bindings.push_back(pCreateInfo->pBindings[i]);
+ }
+
+ return res;
+ }
+
+ void on_vkUpdateDescriptorSets(
+ void* context,
+ VkDevice device,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites,
+ uint32_t descriptorCopyCount,
+ const VkCopyDescriptorSet* pDescriptorCopies) {
+
+ VkEncoder* enc = (VkEncoder*)context;
+
+ std::vector<std::vector<VkDescriptorImageInfo>> imageInfosPerWrite(
+ descriptorWriteCount);
+
+ std::vector<VkWriteDescriptorSet> writesWithSuppressedSamplers;
+
+ {
+ AutoLock lock(mLock);
+ for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
+ writesWithSuppressedSamplers.push_back(
+ createImmutableSamplersFilteredWriteDescriptorSetLocked(
+ pDescriptorWrites + i,
+ imageInfosPerWrite.data() + i));
+ }
+ }
+
+ enc->vkUpdateDescriptorSets(
+ device, descriptorWriteCount, writesWithSuppressedSamplers.data(),
+ descriptorCopyCount, pDescriptorCopies);
+ }
+
void on_vkDestroyImage(
void* context,
VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
@@ -4976,6 +5102,28 @@
context, input_result, device, descriptorPool, descriptorSetCount, pDescriptorSets);
}
+VkResult ResourceTracker::on_vkCreateDescriptorSetLayout(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorSetLayout* pSetLayout) {
+ return mImpl->on_vkCreateDescriptorSetLayout(
+ context, input_result, device, pCreateInfo, pAllocator, pSetLayout);
+}
+
+void ResourceTracker::on_vkUpdateDescriptorSets(
+ void* context,
+ VkDevice device,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites,
+ uint32_t descriptorCopyCount,
+ const VkCopyDescriptorSet* pDescriptorCopies) {
+ return mImpl->on_vkUpdateDescriptorSets(
+ context, device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
+}
+
VkResult ResourceTracker::on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
void* context,
VkResult input_result,