libcg / grvk

Vulkan-based Mantle API implementation
https://en.wikipedia.org/wiki/Mantle_(API)
zlib License
224 stars 14 forks source link

Add DMA queue support and minor Civilization BE fixes #25

Closed dougvj closed 3 years ago

dougvj commented 3 years ago

Fixes as discussed in #16

libcg commented 3 years ago

Maybe exposing both DMA and timer queue families with a count of 0 should be enough to get the game to boot.

dougvj commented 3 years ago

I did some investigating. The game boots with 4 families and count of 0 for DMA and TIMER queues, however even if the DMA queue count is 0 the game still requests it in the device creation and the game doesn't seem to check for success, so if we return an error for the DMA queue request the game crashes.

Should I drop the TIMER quirk and return 0 for a count there instead?

dougvj commented 3 years ago

Another question, how bad would it be to expose another queue as the DMA queue as a fallback in case a transfer only queue isn't exposed by vk?

libcg commented 3 years ago

Should I drop the TIMER quirk and return 0 for a count there instead?

Yes please. EDIT: done in master

Another question, how bad would it be to expose another queue as the DMA queue as a fallback in case a transfer only queue isn't exposed by vk?

I think that's what we'll have to do. Luckily, the official driver only exposes one queue of each family so we should be able to use any extra graphics or compute queue exposed by the Vulkan drivers to act as a DMA queue.

Cherser-s commented 3 years ago

we should be able to use any extra graphics or compute queue exposed by the Vulkan drivers to act as a DMA queue.

Yep, after I added DMA queue selection from compute queue family (I'm using RADV), BF4 started to launch without crashing. Though I have problems with image presentation as application crashes after window resize.

I've used this code:

        if ((queueFamilyProperty->queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)) ==
            (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT)) {
            universalQueueFamilyIndex = i;
            universalQueueCount = queueFamilyProperty->queueCount;
        } else if ((queueFamilyProperty->queueFlags & VK_QUEUE_COMPUTE_BIT) ==
                   VK_QUEUE_COMPUTE_BIT) {
            computeQueueFamilyIndex = i;
            computeQueueCount = queueFamilyProperty->queueCount;
            if (queueFamilyProperty->queueCount > 1 && (queueFamilyProperty->queueFlags & VK_QUEUE_TRANSFER_BIT)) {
                dmaQueueFamilyIndex = i;
                dmaQueueCount = 1;
                computeQueueCount = queueFamilyProperty->queueCount - 1;
            }
        } else if ((queueFamilyProperty->queueFlags & VK_QUEUE_TRANSFER_BIT)) {
            if (dmaQueueFamilyIndex != INVALID_QUEUE_INDEX && dmaQueueFamilyIndex == computeQueueCount) {
                computeQueueCount += 1;
            }
            dmaQueueFamilyIndex = i;
            dmaQueueCount = queueFamilyProperty->queueCount;
        }
dougvj commented 3 years ago

OK I think I have a robust fallback. I will clean it up and push shortly.

I have BF4 on my origin account I will try to get it installed on my Linux box with RADV

Cherser-s commented 3 years ago

Well, at least you can try launching bf4 after these fixes. It still will either crash or you'll get graphical artifacts instead of proper menu UI (the latter is due to shader instructions being unimplemented).

libcg commented 3 years ago

@Cherser-s the BF4 crash is caused by 8f8b6dc that advertises the DMA extension as supported. The game works without it. Also I have a (super terrible) workaround for an invalid SRV read in the shader, looks like a game bug, the menus are rendering correctly now.

Cherser-s commented 3 years ago

the BF4 crash is caused by 8f8b6dc that advertises the DMA extension as supported. The game works without it.

Oh, didn't know that. Anyway that is fixed in the code snippet, that I've posted above. Though this functionality (which is selecting DMA queue from compute family) must be used as a quirk, as it's probably required only by BF4 (it shouldn't really demand DMA queue if it isn't present). The game itself still doesn't work for me though (as I wrote here: https://github.com/libcg/grvk/issues/10)

dougvj commented 3 years ago

Ok I ran this with BF4 and get very fantasticly glitched UI with both amdvlk and radv. I also have a linux box with a priorietary nvidia driver I am super curious to try that out too.

@libcg I went for a fallback implementation that doesn't assume single queues which is a bit more complex, I'm happy to change this at your direction.

libcg commented 3 years ago

@dougvj I didn't take a look at your code, but I know that the official Mantle driver only exposes one queue of each type. Most Vulkan drivers seem to expose more than 3 queues so should be fine.

libcg commented 3 years ago

I pushed a more general (but slightly less performant) alternative to 5b3c70a: 2522ee1. Closing, now that everything has been merged.