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

Heap-less descriptor sets in Metal #2183

Merged
merged 5 commits into from
Jun 28, 2018
Merged

Conversation

kvark
Copy link
Member

@kvark kvark commented Jun 26, 2018

Fixes the heap allocations in descriptor sets, to help #2161.
Edit: the improvement is there, but it's not the one we were looking for.

Adds real value semantics for the DescriptorPool, which now owns the allocation and has the actual descriptor sets pointing to it.
PR checklist:

  • make succeeds (on *nix)
  • make reftests succeeds
  • tested examples with the following backends: metal

Note: it doesn't work correctly yet, but I'd be happy to get the review comments and notes. Perhaps, you can spot the mistake? ;)
Sadly, my CTS is non-operational atm, so it's not easy to figure out a test case.
Note2: the individual commits are not build-able. Will squash once finished.

@kvark kvark requested a review from grovesNL June 26, 2018 16:49
@kvark kvark force-pushed the mtl-descriptors branch from 15901ef to 5340e09 Compare June 26, 2018 21:42
@kvark kvark changed the title [WIP] heap-less descriptor sets Heap-less descriptor sets in Metal Jun 26, 2018
@kvark
Copy link
Member Author

kvark commented Jun 26, 2018

I'm thinking about these follow-ups:

  • make us not issuing any pre-render/compute commands if not inside a render pass at all
  • make us not re-set the resources to the same values - check against cache
  • change the API a little bit to avoid heaps and use iterators with move semantics

@kvark
Copy link
Member Author

kvark commented Jun 27, 2018

I've implemented the first two follow-ups here. The code looks much better, subjectively. Performance-wise we don't have hard numbers, just some rough estimation. FPS increased from 65 to 85, which is quite visible but still far from the target.

@kvark kvark mentioned this pull request Jun 27, 2018
22 tasks
@kvark
Copy link
Member Author

kvark commented Jun 27, 2018

That difference of 20fps is for peak fps (with everything still on screen), but the averages differ less.
Anyhow, I'm hitting a failed assertion occasionally when running Dota now:

ERROR! VK call failed! result = VK_ERROR_FRAGMENTED_POOL ( vkAllocateDescriptorSets( m_pDeviceVulkan, &allocInfo, &pCurrentDescriptorSetPool->m_ppDescriptorSets[ pCurrentDescriptorSetPool->m_nCurrentDescriptorSet - 1 ] ) )
ERROR! VK call failed! result = VK_ERROR_FRAGMENTED_POOL ( vkAllocateDescriptorSets( m_pDeviceVulkan, &allocInfo, &pCurrentDescriptorSetPool->m_ppDescriptorSets[ pCurrentDescriptorSetPool->m_nCurrentDescriptorSet - 1 ] ) )
ERROR! VK call failed! result = VK_ERROR_FRAGMENTED_POOL ( vkAllocateDescriptorSets( m_pDeviceVulkan, &allocInfo, &pCurrentDescriptorSetPool->m_ppDescriptorSets[ pCurrentDescriptorSetPool->m_nCurrentDescriptorSet - 1 ] ) )
ERROR! VK call failed! result = VK_ERROR_FRAGMENTED_POOL ( vkAllocateDescriptorSets( m_pDeviceVulkan, &allocInfo, &pCurrentDescriptorSetPool->m_ppDescriptorSets[ pCurrentDescriptorSetPool->m_nCurrentDescriptorSet - 1 ] ) )
thread '<unnamed>' panicked at 'assertion failed: range.start < range.end', /Users/dmalyshau/Code/gfx/src/backend/metal/src/../../auxil/range_alloc.rs:63:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.

First, we don't know how dota reacts on an allocation error (but we can ask). Second, the range allocator failure may signify a mistake in our logic. Need to double check that (cc @Xaeroxe ).

@kvark
Copy link
Member Author

kvark commented Jun 27, 2018

@Xaeroxe nvm, it was my code's fault all along. Fixed now :)

Copy link
Contributor

@grovesNL grovesNL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 👍 looking forward to the performance improvement!

Dota 2 should have covered/validated most of these changes as well, so it seems safe to proceed.

native::DescriptorPool::count_bindings(layout.ty, layout.count,
&mut sampler_base, &mut texture_base, &mut buffer_base);

if buffer_base != bf_range.start {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: seems we could collapse this with the other if buffer_base != bf_range.start below

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's just github view playing tricks on us - the other one has different indentation (so executes at a different frequency)

}
}

pub fn allocate_range(&mut self, length: T) -> Option<Range<T>> {
assert_ne!(length + length, length);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this assertion? Seems it's just checking for zero?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but T doesn't have a Zero bound :)

Copy link
Member Author

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look!
I still suspect something is wonky with the code, but having so much stuff piling in doesn't help, and we'll need to investigate post-merging.
bors r=grovesNL

native::DescriptorPool::count_bindings(layout.ty, layout.count,
&mut sampler_base, &mut texture_base, &mut buffer_base);

if buffer_base != bf_range.start {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's just github view playing tricks on us - the other one has different indentation (so executes at a different frequency)

bors bot added a commit that referenced this pull request Jun 28, 2018
2183: Heap-less descriptor sets in Metal r=grovesNL a=kvark

Fixes the heap allocations in descriptor sets, to help #2161.
Edit: the improvement is there, but it's not the one we were looking for.

Adds real value semantics for the `DescriptorPool`, which now owns the allocation and has the actual descriptor sets pointing to it.
PR checklist:
- [x] `make` succeeds (on *nix)
- [x] `make reftests` succeeds
- [x] tested examples with the following backends: metal

~~Note: it doesn't work correctly yet, but I'd be happy to get the review comments and notes. Perhaps, you can spot the mistake? ;)
Sadly, my CTS is non-operational atm, so it's not easy to figure out a test case.
Note2: the individual commits are not build-able. Will squash once finished.~~

Co-authored-by: Dzmitry Malyshau <[email protected]>
@bors
Copy link
Contributor

bors bot commented Jun 28, 2018

@bors bors bot merged commit 1f9b40e into gfx-rs:master Jun 28, 2018
@kvark kvark deleted the mtl-descriptors branch June 28, 2018 03:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants