Skip to content

Commit d1cca40

Browse files
committed
mantle: added quirk to allocate memory specifically for descriptor buffers
1 parent fc0ca96 commit d1cca40

File tree

5 files changed

+79
-6
lines changed

5 files changed

+79
-6
lines changed

src/mantle/mantle_descriptor_set.c

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ GR_RESULT GR_STDCALL grCreateDescriptorSet(
2828
}
2929

3030
VkBuffer vkBuffer = VK_NULL_HANDLE;
31+
VkDeviceMemory bufferMemory = VK_NULL_HANDLE;
3132
VkDeviceSize bufferSize = 0;
33+
VkDeviceAddress bufferAddress = 0ull;
34+
void* descriptorBufferPtr = NULL;
3235
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
3336
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
3437

@@ -59,7 +62,69 @@ GR_RESULT GR_STDCALL grCreateDescriptorSet(
5962
vkRes = VKD.vkCreateBuffer(grDevice->device, &bufferCreateInfo, NULL, &vkBuffer);
6063
if (vkRes != VK_SUCCESS) {
6164
LOGE("vkCreateBuffer failed (%d)\n", vkRes);
62-
return getGrResult(vkRes);
65+
goto bail;
66+
}
67+
if (quirkHas(QUIRK_DESCRIPTOR_SET_USE_DEDICATED_ALLOCATION)) {
68+
VkMemoryRequirements memReqs;
69+
VKD.vkGetBufferMemoryRequirements(grDevice->device, vkBuffer, &memReqs);
70+
71+
const VkMemoryAllocateFlagsInfo flagsInfo = {
72+
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
73+
.pNext = NULL,
74+
.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT,
75+
.deviceMask = 0,
76+
};
77+
VkMemoryAllocateInfo allocateInfo = {
78+
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
79+
.pNext = &flagsInfo,
80+
.allocationSize = memReqs.size,
81+
.memoryTypeIndex = 0xFFFF,
82+
};
83+
// exclude host non-visible memory types
84+
for (unsigned i = 0; i < grDevice->memoryProperties.memoryTypeCount; ++i) {
85+
if (!(memReqs.memoryTypeBits & (1 << i))) {
86+
continue;
87+
}
88+
if (!(grDevice->memoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
89+
continue;
90+
}
91+
92+
allocateInfo.memoryTypeIndex = i;
93+
vkRes = VKD.vkAllocateMemory(grDevice->device, &allocateInfo, NULL, &bufferMemory);
94+
if (vkRes == VK_SUCCESS) {
95+
break;
96+
}
97+
}
98+
99+
if (vkRes != VK_SUCCESS) {
100+
LOGE("failed to allocate memory for descriptor buffer (%d)\n", vkRes);
101+
goto bail;
102+
} else if (bufferMemory == VK_NULL_HANDLE) {
103+
LOGE("failed to select memory memory for descriptor buffer\n");
104+
goto bail;
105+
}
106+
107+
vkRes = VKD.vkBindBufferMemory(grDevice->device, vkBuffer, bufferMemory, 0);
108+
if (vkRes != VK_SUCCESS) {
109+
LOGE("Buffer binding failed (%d)\n", vkRes);
110+
goto bail;
111+
}
112+
VkBufferDeviceAddressInfo vkBufferAddressInfo = {
113+
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
114+
.pNext = NULL,
115+
.buffer = vkBuffer,
116+
};
117+
118+
bufferAddress = VKD.vkGetBufferDeviceAddress(grDevice->device, &vkBufferAddressInfo);
119+
120+
vkRes = VKD.vkMapMemory(grDevice->device, bufferMemory,
121+
0, VK_WHOLE_SIZE, 0, &descriptorBufferPtr);
122+
if (vkRes != VK_SUCCESS) {
123+
LOGE("vkMapMemory failed (%d)\n", vkRes);
124+
goto bail;
125+
}
126+
127+
memset(descriptorBufferPtr, 0, bufferSize);
63128
}
64129
} else {
65130
const VkDescriptorType descriptorTypes[] = {
@@ -132,11 +197,12 @@ GR_RESULT GR_STDCALL grCreateDescriptorSet(
132197
.slots = calloc(pCreateInfo->slots, sizeof(DescriptorSetSlot)),
133198
.descriptorPool = descriptorPool,
134199
.descriptorSet = descriptorSet,
135-
.descriptorBufferPtr = NULL,
200+
.descriptorBufferPtr = descriptorBufferPtr,
136201
.descriptorBuffer = vkBuffer,
202+
.descriptorBufferMemory = bufferMemory,
137203
.descriptorBufferSize = bufferSize,
138204
.descriptorBufferMemoryOffset = 0ull,
139-
.descriptorBufferAddress = 0ull,
205+
.descriptorBufferAddress = bufferAddress,
140206
};
141207

142208
*pDescriptorSet = (GR_DESCRIPTOR_SET)grDescriptorSet;
@@ -145,6 +211,7 @@ GR_RESULT GR_STDCALL grCreateDescriptorSet(
145211
bail:
146212
VKD.vkDestroyDescriptorPool(grDevice->device, descriptorPool, NULL);
147213
VKD.vkDestroyBuffer(grDevice->device, vkBuffer, NULL);
214+
VKD.vkFreeMemory(grDevice->device, bufferMemory, NULL);
148215
return getGrResult(vkRes);
149216
}
150217

src/mantle/mantle_object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ typedef struct _GrDescriptorSet {
241241
VkDescriptorSet descriptorSet;
242242
void* descriptorBufferPtr;
243243
VkBuffer descriptorBuffer;
244+
VkDeviceMemory descriptorBufferMemory;
244245
VkDeviceSize descriptorBufferSize;
245246
VkDeviceSize descriptorBufferMemoryOffset;
246247
VkDeviceAddress descriptorBufferAddress;

src/mantle/mantle_object_man.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ GR_RESULT GR_STDCALL grDestroyObject(
4343
grClearDescriptorSetSlots(grDescriptorSet, 0, grDescriptorSet->slotCount);
4444
free(grDescriptorSet->slots);
4545
VKD.vkDestroyBuffer(grDevice->device, grDescriptorSet->descriptorBuffer, NULL);
46+
VKD.vkFreeMemory(grDevice->device, grDescriptorSet->descriptorBufferMemory, NULL);
4647
VKD.vkDestroyDescriptorPool(grDevice->device, grDescriptorSet->descriptorPool, NULL);
4748
} break;
4849
case GR_OBJ_TYPE_EVENT: {
@@ -182,7 +183,7 @@ GR_RESULT GR_STDCALL grGetObjectInfo(
182183
case GR_OBJ_TYPE_DESCRIPTOR_SET: {
183184
GrDescriptorSet* grDescriptorSet = (GrDescriptorSet*)grBaseObject;
184185
GrDevice* grDevice = GET_OBJ_DEVICE(grBaseObject);
185-
if (grDevice->descriptorBufferSupported) {
186+
if (grDevice->descriptorBufferSupported && !quirkHas(QUIRK_DESCRIPTOR_SET_USE_DEDICATED_ALLOCATION)) {
186187
VKD.vkGetBufferMemoryRequirements(grDevice->device, grDescriptorSet->descriptorBuffer, &memReqs);
187188

188189
// exclude host non-visible memory types
@@ -327,7 +328,7 @@ GR_RESULT GR_STDCALL grBindObjectMemory(
327328
GrDescriptorSet* grDescriptorSet = (GrDescriptorSet*)grObject;
328329
GrDevice* grDevice = GET_OBJ_DEVICE(grObject);
329330

330-
if (grDevice->descriptorBufferSupported) {
331+
if (grDevice->descriptorBufferSupported && !quirkHas(QUIRK_DESCRIPTOR_SET_USE_DEDICATED_ALLOCATION)) {
331332
vkRes = VKD.vkBindBufferMemory(grDevice->device, grDescriptorSet->descriptorBuffer, grGpuMemory->deviceMemory, offset);
332333
if (vkRes == VK_SUCCESS) {
333334
VkBufferDeviceAddressInfo vkBufferAddressInfo = {

src/mantle/quirk.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ void quirkInit(
1212
QUIRK_COMPRESSED_IMAGE_COPY_IN_TEXELS |
1313
QUIRK_INVALID_CMD_BUFFER_RESET |
1414
QUIRK_CUBEMAP_LAYER_DIV_6 |
15-
QUIRK_SILENCE_TRANSFER_ONLY_LINEAR_IMAGE_WARNINGS;
15+
QUIRK_SILENCE_TRANSFER_ONLY_LINEAR_IMAGE_WARNINGS |
16+
QUIRK_DESCRIPTOR_SET_USE_DEDICATED_ALLOCATION;
1617
} else if (!strcmp(appInfo->pEngineName, "CivTech")) {
1718
mQuirks = QUIRK_NON_ZERO_MEM_REQ |
1819
QUIRK_READ_ONLY_IMAGE_STATE_MISMATCH |

src/mantle/quirk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ typedef enum {
2828
// RADV doesn't support linear transfer-only images used by Star Swarm, but it has no effect
2929
// on rendering. Silence it.
3030
QUIRK_SILENCE_TRANSFER_ONLY_LINEAR_IMAGE_WARNINGS = 1 << 7,
31+
32+
// Star Swarm uses completely incompatible memory types for descriptor buffers
33+
QUIRK_DESCRIPTOR_SET_USE_DEDICATED_ALLOCATION = 1 << 8,
3134
} QUIRK_FLAGS;
3235

3336
void quirkInit(

0 commit comments

Comments
 (0)