Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory allocation on Intel Atom chips #947

Closed
SilverBird775 opened this Issue Mar 2, 2019 · 5 comments

Comments

Projects
None yet
3 participants
@SilverBird775
Copy link

SilverBird775 commented Mar 2, 2019

Intel Celeron N2840
Mesa DRI Intel(R) Bay Trail (0xf31)

For quite a time the DXVK wrapper have been completely unusable for me because of alot DxvkMemoryAllocator: Memory allocation failed errors. Most games renderings are pitch black, with rare exceptions. I put some efforts to investigate into this showstopper and now i think has found the clue.

According to Mesa sources (intel/vulkan/anv_device.c):

  if (device->info.has_llc) {
     /* Big core GPUs share LLC with the CPU and thus one memory type can be
      * both cached and coherent at the same time.
      */
     device->memory.types[type_count++] = (struct anv_memory_type) {
        .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                         VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
                         VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
        .heapIndex = heap,
        .valid_buffer_usage = valid_buffer_usage,
     };
  } else {
     /* The spec requires that we expose a host-visible, coherent memory
      * type, but Atom GPUs don't share LLC. Thus we offer two memory types
      * to give the application a choice between cached, but not coherent and
      * coherent but uncached (WC though).
      */
     device->memory.types[type_count++] = (struct anv_memory_type) {
        .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                         VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
        .heapIndex = heap,
        .valid_buffer_usage = valid_buffer_usage,
     };
     device->memory.types[type_count++] = (struct anv_memory_type) {
        .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                         VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
        .heapIndex = heap,
        .valid_buffer_usage = valid_buffer_usage,
     };
  }

So, when got unlucky GPU you cannot have HOST_COHERENT_BIT and HOST_CACHED_BIT flags both set! Having this in mind i made a proof of the concept code insertion in DxvkMemoryAllocator::tryAlloc

	if ((flags &  (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT))
               == (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT))
		flags &= ~VK_MEMORY_PROPERTY_HOST_CACHED_BIT;

Perhaps, i did it ugly way but it indeed fixed the problem, or at least, sweep it under the carpet. No more errors of THAT kind, backgrounds and models are fine, textures in place. There are still some known BayTrail-vulkan related visual glitches and issues in games because of unfinished drivers but that's irrelevant to DXVK.

The essential from DXVK logs seem to proof the findings:

info: DXVK: v1.0
warn: OpenVR: Failed to locate module
info: Enabled instance extensions:
info: VK_KHR_get_physical_device_properties2
info: VK_KHR_surface
info: VK_KHR_win32_surface
info: Intel(R) Bay Trail:
info: Driver: 18.3.3
info: Vulkan: 1.1.90
info: Memory Heap[0]:
info: Size: 1536 MiB
info: Flags: 0x1
info: Memory Type[0]: Property Flags = 0x7
info: Memory Type[1]: Property Flags = 0xb

Yes, those property flags in logs again. I hope the above will help to get Intel Atoms in line.

@doitsujin

This comment has been minimized.

Copy link
Owner

doitsujin commented Mar 2, 2019

Not using VK_MEMORY_PROPERTY_HOST_CACHED_BIT for read-back has a severe performance penalty (we're talking about hundreds of CPU cycles per read, with one read typically being 4/8/16 bytes), so this is not a great solution.

Unfortunately, supporting non-coherent memory is also very hard, especially when we don't want it to tank performance for the vast majority of hardware where readback memory is coherent. For D3D11, mapping and unmapping buffers (which is where we'd have to implement this) is performance-critical.

I don't have an Atom setup to test with anyway, although I could potentially simulate similar behaviour through a Vulkan layer.

@SilverBird775

This comment has been minimized.

Copy link
Author

SilverBird775 commented Mar 2, 2019

For BayTrail, as for any build-in graphics with shared memory APU there is no great solutions really. And it seems there is no much choice but to hurt its performance for now. If it will just work, then it would be good enough already. Later on it could be fixed with a more strict flag management (if it is possible so) or some clever finding.

Just as i see it.

@Cvostr

This comment has been minimized.

Copy link

Cvostr commented Mar 2, 2019

Baytrail is so weird, i am own one ,so i know

@doitsujin doitsujin closed this in f272071 Mar 14, 2019

doitsujin added a commit that referenced this issue Mar 14, 2019

[dxvk] Don't enforce HOST_CACHED flag when allocating memory
The better fix would be to support non-coherent memory properly,
but this will have to do for now. Fixes #947.
@doitsujin

This comment has been minimized.

Copy link
Owner

doitsujin commented Mar 14, 2019

I ultimately decided to go with the non-CACHED memory type for now, not sure if implementing a proper fix is worth it. It would certainly be a ton of work.

@SilverBird775

This comment has been minimized.

Copy link
Author

SilverBird775 commented Mar 15, 2019

I confirm the version 1.0.1 fixed the memory allocation problem and is working on real hardware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.