Fake only supporting a single queue family type (the most capable one)

This commit is contained in:
baldurk
2016-07-18 18:17:16 +02:00
parent 7ab314d1a6
commit 0e43b3916e
5 changed files with 138 additions and 5 deletions
+8
View File
@@ -2594,6 +2594,14 @@ string ToStrHelper<false, VkClearAttachment>::Get(const VkClearAttachment &el)
el.colorAttachment, ToStr::Get(el.clearValue).c_str());
}
template <>
string ToStrHelper<false, VkQueueFamilyProperties>::Get(const VkQueueFamilyProperties &el)
{
return StringFormat::Fmt(
"%s x %u, %u bits, %s", ToStr::Get((VkQueueFlagBits)el.queueFlags).c_str(), el.queueCount,
el.timestampValidBits, ToStr::Get(el.minImageTransferGranularity).c_str());
}
template <>
string ToStrHelper<false, VkExtent2D>::Get(const VkExtent2D &el)
{
+10 -1
View File
@@ -44,7 +44,7 @@ struct VkInitParams : public RDCInitParams
void Set(const VkInstanceCreateInfo *pCreateInfo, ResourceId inst);
static const uint32_t VK_SERIALISE_VERSION = 0x0000004;
static const uint32_t VK_SERIALISE_VERSION = 0x0000005;
// version number internal to vulkan stream
uint32_t SerialiseVersion;
@@ -273,7 +273,16 @@ private:
m_QueueFamilyIdx; // the family index that we've selected in CreateDevice for our queue
VkQueue m_Queue; // the queue used for our own command buffer work
// the physical devices
vector<VkPhysicalDevice> m_PhysicalDevices;
// the single queue family supported for each physical device
vector<pair<uint32_t, VkQueueFamilyProperties> > m_SupportedQueueFamilies;
// the supported queue family for the created device
uint32_t m_SupportedQueueFamily;
// the queue families (an array of count for each) for the created device
vector<VkQueue *> m_QueueFamilies;
vector<uint32_t *> m_MemIdxMaps;
@@ -470,17 +470,32 @@ bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(Serialiser *localSerial
VkPhysicalDeviceProperties physProps;
VkPhysicalDeviceMemoryProperties memProps;
VkPhysicalDeviceFeatures physFeatures;
VkQueueFamilyProperties queueProps[16];
if(m_State >= WRITING)
{
ObjDisp(instance)->GetPhysicalDeviceProperties(Unwrap(*pPhysicalDevices), &physProps);
ObjDisp(instance)->GetPhysicalDeviceMemoryProperties(Unwrap(*pPhysicalDevices), &memProps);
ObjDisp(instance)->GetPhysicalDeviceFeatures(Unwrap(*pPhysicalDevices), &physFeatures);
uint32_t queueCount = 0;
ObjDisp(instance)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(*pPhysicalDevices),
&queueCount, NULL);
if(queueCount < 16)
{
RDCWARN("More than 16 queues");
queueCount = 16;
}
ObjDisp(instance)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(*pPhysicalDevices),
&queueCount, queueProps);
}
localSerialiser->Serialise("physProps", physProps);
localSerialiser->Serialise("memProps", memProps);
localSerialiser->Serialise("physFeatures", physFeatures);
localSerialiser->SerialisePODArray<16>("queueProps", queueProps);
VkPhysicalDevice pd = VK_NULL_HANDLE;
@@ -580,6 +595,7 @@ VkResult WrappedVulkan::vkEnumeratePhysicalDevices(VkInstance instance,
RDCASSERTEQUAL(vkr, VK_SUCCESS);
m_PhysicalDevices.resize(count);
m_SupportedQueueFamilies.resize(count);
for(uint32_t i = 0; i < count; i++)
{
@@ -632,6 +648,89 @@ VkResult WrappedVulkan::vkEnumeratePhysicalDevices(VkInstance instance,
}
}
}
// find the queue with the most bits set and only report that one
{
uint32_t count = 0;
ObjDisp(m_PhysicalDevices[i])
->GetPhysicalDeviceQueueFamilyProperties(Unwrap(m_PhysicalDevices[i]), &count, NULL);
VkQueueFamilyProperties *props = new VkQueueFamilyProperties[count];
ObjDisp(m_PhysicalDevices[i])
->GetPhysicalDeviceQueueFamilyProperties(Unwrap(m_PhysicalDevices[i]), &count, props);
uint32_t best = 0;
// don't need to explicitly check for transfer, because graphics bit
// implies it. We do have to check for compute bit, because there might
// be a graphics only queue - it just means we have to keep looking
// to find the grpahics & compute queue family which is guaranteed.
for(uint32_t q = 1; q < count; q++)
{
// compare current against the known best
VkQueueFamilyProperties &currentProps = props[q];
VkQueueFamilyProperties &bestProps = props[best];
const bool currentGraphics = (currentProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0;
const bool currentCompute = (currentProps.queueFlags & VK_QUEUE_COMPUTE_BIT) != 0;
const bool currentSparse = (currentProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) != 0;
const bool bestGraphics = (bestProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0;
const bool bestCompute = (bestProps.queueFlags & VK_QUEUE_COMPUTE_BIT) != 0;
const bool bestSparse = (bestProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) != 0;
// if one has graphics bit set, but the other doesn't
if(currentGraphics != bestGraphics)
{
// if current has graphics but best doesn't, we have a new best
if(currentGraphics)
best = q;
continue;
}
if(currentCompute != bestCompute)
{
// if current has compute but best doesn't, we have a new best
if(currentCompute)
best = q;
continue;
}
// if we've gotten here, both best and current have graphics and compute. Check
// to see if the current is somehow better than best (in the case of a tie, we
// keep the lower index of queue).
if(currentSparse != bestSparse)
{
if(currentSparse)
best = q;
continue;
}
if(currentProps.timestampValidBits != bestProps.timestampValidBits)
{
if(currentProps.timestampValidBits > bestProps.timestampValidBits)
best = q;
continue;
}
if(currentProps.minImageTransferGranularity.width <
bestProps.minImageTransferGranularity.width ||
currentProps.minImageTransferGranularity.height <
bestProps.minImageTransferGranularity.height ||
currentProps.minImageTransferGranularity.depth <
bestProps.minImageTransferGranularity.depth)
{
best = q;
continue;
}
}
m_SupportedQueueFamilies[i] = std::make_pair(best, props[best]);
SAFE_DELETE_ARRAY(props);
}
}
if(pPhysicalDeviceCount)
@@ -653,6 +752,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(Serialiser *localSerialiser,
SERIALISE_ELEMENT(ResourceId, physId, GetResID(physicalDevice));
SERIALISE_ELEMENT(VkDeviceCreateInfo, serCreateInfo, *pCreateInfo);
SERIALISE_ELEMENT(ResourceId, devId, GetResID(*pDevice));
SERIALISE_ELEMENT(uint32_t, queueFamily, m_SupportedQueueFamily);
if(m_State == READING)
{
@@ -660,6 +760,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(Serialiser *localSerialiser,
// in the serialised VkDeviceCreateInfo don't double-free
VkDeviceCreateInfo createInfo = serCreateInfo;
m_SupportedQueueFamily = queueFamily;
std::vector<string> Extensions;
for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++)
{
@@ -1002,6 +1104,11 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice,
m_QueueFamilies[family][q] = VK_NULL_HANDLE;
}
// find the matching physical device
for(size_t i = 0; i < m_PhysicalDevices.size(); i++)
if(m_PhysicalDevices[i] == physicalDevice)
m_SupportedQueueFamily = m_SupportedQueueFamilies[i].first;
VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
// step through the chain of pNext until we get to the link info
@@ -87,9 +87,18 @@ void WrappedVulkan::vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevic
void WrappedVulkan::vkGetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice, uint32_t *pCount, VkQueueFamilyProperties *pQueueFamilyProperties)
{
ObjDisp(physicalDevice)
->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), pCount,
pQueueFamilyProperties);
// pretend to only have one queue, the one with graphics capability
if(pCount)
*pCount = 1;
if(pQueueFamilyProperties)
{
// find the matching physical device
for(size_t i = 0; i < m_PhysicalDevices.size(); i++)
if(m_PhysicalDevices[i] == physicalDevice)
*pQueueFamilyProperties = m_SupportedQueueFamilies[i].second;
return;
}
}
void WrappedVulkan::vkGetPhysicalDeviceMemoryProperties(
@@ -29,7 +29,7 @@ bool WrappedVulkan::Serialise_vkGetDeviceQueue(Serialiser *localSerialiser, VkDe
VkQueue *pQueue)
{
SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
SERIALISE_ELEMENT(uint32_t, familyIdx, queueFamilyIndex);
SERIALISE_ELEMENT(uint32_t, familyIdx, m_SupportedQueueFamily);
SERIALISE_ELEMENT(uint32_t, idx, queueIndex);
SERIALISE_ELEMENT(ResourceId, queueId, GetResID(*pQueue));