vulkan: filter nonexistent samplers
Bug: 186021150
Test: dEQP-VK.binding_model.descriptor_update.samplerless*
Change-Id: Ie80e5465460efaad3144ec2be63f42e8bfbc94bc
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 814a8dc..1b8563c 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -419,6 +419,10 @@
uint32_t unused;
};
+ struct VkSampler_Info {
+ uint32_t unused;
+ };
+
struct VkBufferCollectionFUCHSIA_Info {
#ifdef VK_USE_PLATFORM_FUCHSIA
android::base::Optional<
@@ -478,6 +482,13 @@
info_VkCommandPool.erase(pool);
}
+ void unregister_VkSampler(VkSampler sampler) {
+ if (!sampler) return;
+
+ AutoLock lock(mLock);
+ info_VkSampler.erase(sampler);
+ }
+
void unregister_VkCommandBuffer(VkCommandBuffer commandBuffer) {
resetCommandBufferStagingInfo(commandBuffer, true /* also reset primaries */, true /* also clear pending descriptor sets */);
@@ -709,34 +720,32 @@
return res;
}
- VkWriteDescriptorSet
- createImmutableSamplersFilteredWriteDescriptorSetLocked(
- const VkWriteDescriptorSet* descriptorWrite,
- std::vector<VkDescriptorImageInfo>* imageInfoArray) {
+ bool descriptorBindingIsImmutableSampler(
+ VkDescriptorSet dstSet,
+ uint32_t dstBinding) {
- VkWriteDescriptorSet res = *descriptorWrite;
+ return as_goldfish_VkDescriptorSet(dstSet)->reified->bindingIsImmutableSampler[dstBinding];
+ }
- if (descriptorWrite->descriptorCount == 0) return res;
+ VkDescriptorImageInfo
+ filterNonexistentSampler(
+ const VkDescriptorImageInfo& inputInfo) {
- if (descriptorWrite->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER &&
- descriptorWrite->descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) return res;
+ VkSampler sampler =
+ inputInfo.sampler;
- bool immutableSampler =
- as_goldfish_VkDescriptorSet(descriptorWrite->dstSet)->reified->bindingIsImmutableSampler[descriptorWrite->dstBinding];
+ VkDescriptorImageInfo res = inputInfo;
- 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);
+ if (sampler) {
+ auto it = info_VkSampler.find(sampler);
+ bool samplerExists = it != info_VkSampler.end();
+ if (!samplerExists) res.sampler = 0;
}
- res.pImageInfo = imageInfoArray->data();
-
return res;
}
+
void freeDescriptorSetsIfHostAllocated(VkEncoder* enc, VkDevice device, uint32_t descriptorSetCount, const VkDescriptorSet* sets) {
for (uint32_t i = 0; i < descriptorSetCount; ++i) {
struct goldfish_VkDescriptorSet* ds = as_goldfish_VkDescriptorSet(sets[i]);
@@ -4782,25 +4791,62 @@
VkEncoder* enc = (VkEncoder*)context;
- std::vector<std::vector<VkDescriptorImageInfo>> imageInfosPerWrite(
- descriptorWriteCount);
+ std::vector<VkDescriptorImageInfo> transformedImageInfos;
+ std::vector<VkWriteDescriptorSet> transformedWrites(descriptorWriteCount);
- std::vector<VkWriteDescriptorSet> writesWithSuppressedSamplers;
+ memcpy(transformedWrites.data(), pDescriptorWrites, sizeof(VkWriteDescriptorSet) * descriptorWriteCount);
+
+ size_t imageInfosNeeded = 0;
+ for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
+ if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
+ if (!transformedWrites[i].pImageInfo) continue;
+
+ imageInfosNeeded += transformedWrites[i].descriptorCount;
+ }
+
+ transformedImageInfos.resize(imageInfosNeeded);
+
+ size_t imageInfoIndex = 0;
+ for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
+ if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
+ if (!transformedWrites[i].pImageInfo) continue;
+
+ for (uint32_t j = 0; j < transformedWrites[i].descriptorCount; ++j) {
+ transformedImageInfos[imageInfoIndex] = transformedWrites[i].pImageInfo[j];
+ ++imageInfoIndex;
+ }
+ transformedWrites[i].pImageInfo = &transformedImageInfos[imageInfoIndex - transformedWrites[i].descriptorCount];
+ }
{
+ // Validate and filter samplers
AutoLock lock(mLock);
+ size_t imageInfoIndex = 0;
for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
- writesWithSuppressedSamplers.push_back(
- createImmutableSamplersFilteredWriteDescriptorSetLocked(
- pDescriptorWrites + i,
- imageInfosPerWrite.data() + i));
+
+ if (!isDescriptorTypeImageInfo(transformedWrites[i].descriptorType)) continue;
+ if (!transformedWrites[i].pImageInfo) continue;
+
+ bool isImmutableSampler =
+ descriptorBindingIsImmutableSampler(
+ transformedWrites[i].dstSet,
+ transformedWrites[i].dstBinding);
+
+ for (uint32_t j = 0; j < transformedWrites[i].descriptorCount; ++j) {
+ if (isImmutableSampler) {
+ transformedImageInfos[imageInfoIndex].sampler = 0;
+ }
+ transformedImageInfos[imageInfoIndex] =
+ filterNonexistentSampler(transformedImageInfos[imageInfoIndex]);
+ ++imageInfoIndex;
+ }
}
}
if (mFeatureInfo->hasVulkanBatchedDescriptorSetUpdate) {
for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
- VkDescriptorSet set = writesWithSuppressedSamplers[i].dstSet;
- doEmulatedDescriptorWrite(&writesWithSuppressedSamplers[i],
+ VkDescriptorSet set = transformedWrites[i].dstSet;
+ doEmulatedDescriptorWrite(&transformedWrites[i],
as_goldfish_VkDescriptorSet(set)->reified);
}
@@ -4811,7 +4857,7 @@
}
} else {
enc->vkUpdateDescriptorSets(
- device, descriptorWriteCount, writesWithSuppressedSamplers.data(),
+ device, descriptorWriteCount, transformedWrites.data(),
descriptorCopyCount, pDescriptorCopies, true /* do lock */);
}
}