Merge pull request #699 from billhollings/master

Fix crash when VkDeviceCreateInfo specifies queue families out of numerical order.
This commit is contained in:
Bill Hollings 2019-08-05 16:47:09 -04:00 committed by GitHub
commit e38b7e7d90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 21 deletions

View File

@ -20,6 +20,7 @@ Released TBD
- Revert to supporting host-coherent memory for linear images on macOS. - Revert to supporting host-coherent memory for linear images on macOS.
- Ensure Vulkan loader magic number is set every time before returning any dispatchable Vulkan handle. - Ensure Vulkan loader magic number is set every time before returning any dispatchable Vulkan handle.
- Fix crash when `VkDeviceCreateInfo` specifies queue families out of numerical order.
- Consolidate the various linkable objects into a `MVKLinkableMixin` template base class. - Consolidate the various linkable objects into a `MVKLinkableMixin` template base class.
- Use `MVKVector` whenever possible in MoltenVK, especially within render loop. - Use `MVKVector` whenever possible in MoltenVK, especially within render loop.

View File

@ -2499,7 +2499,11 @@ void MVKDevice::initQueues(const VkDeviceCreateInfo* pCreateInfo) {
VkQueueFamilyProperties qfProps; VkQueueFamilyProperties qfProps;
qFam->getProperties(&qfProps); qFam->getProperties(&qfProps);
_queuesByQueueFamilyIndex.resize(qfIdx + 1); // Ensure an entry for this queue family exists // Ensure an entry for this queue family exists
uint32_t qfCntMin = qfIdx + 1;
if (_queuesByQueueFamilyIndex.size() < qfCntMin) {
_queuesByQueueFamilyIndex.resize(qfCntMin);
}
auto& queues = _queuesByQueueFamilyIndex[qfIdx]; auto& queues = _queuesByQueueFamilyIndex[qfIdx];
uint32_t qCnt = min(pQFInfo->queueCount, qfProps.queueCount); uint32_t qCnt = min(pQFInfo->queueCount, qfProps.queueCount);
for (uint32_t qIdx = 0; qIdx < qCnt; qIdx++) { for (uint32_t qIdx = 0; qIdx < qCnt; qIdx++) {

View File

@ -412,14 +412,14 @@ public:
iterator begin() const { return iterator( 0, *this ); } iterator begin() const { return iterator( 0, *this ); }
iterator end() const { return iterator( alc.num_elements_used, *this ); } iterator end() const { return iterator( alc.num_elements_used, *this ); }
const Type &operator[]( const size_t i ) const override { return alc.ptr[i]; } const Type &operator[]( const size_t i ) const override { return alc[i]; }
Type &operator[]( const size_t i ) override { return alc.ptr[i]; } Type &operator[]( const size_t i ) override { return alc[i]; }
const Type &at( const size_t i ) const override { return alc.ptr[i]; } const Type &at( const size_t i ) const override { return alc[i]; }
Type &at( const size_t i ) override { return alc.ptr[i]; } Type &at( const size_t i ) override { return alc[i]; }
const Type &front() const override { return alc.ptr[0]; } const Type &front() const override { return alc[0]; }
Type &front() override { return alc.ptr[0]; } Type &front() override { return alc[0]; }
const Type &back() const override { return alc.ptr[alc.num_elements_used - 1]; } const Type &back() const override { return alc[alc.num_elements_used - 1]; }
Type &back() override { return alc.ptr[alc.num_elements_used - 1]; } Type &back() override { return alc[alc.num_elements_used - 1]; }
const Type *data() const override { return alc.ptr; } const Type *data() const override { return alc.ptr; }
Type *data() override { return alc.ptr; } Type *data() override { return alc.ptr; }
@ -820,16 +820,16 @@ public:
iterator begin() { return iterator( 0, *this ); } iterator begin() { return iterator( 0, *this ); }
iterator end() { return iterator( alc.num_elements_used, *this ); } iterator end() { return iterator( alc.num_elements_used, *this ); }
const Type * const at( const size_t i ) const override { return alc.ptr[i]; } const Type * const at( const size_t i ) const override { return alc[i]; }
Type * &at( const size_t i ) override { return alc.ptr[i]; } Type * &at( const size_t i ) override { return alc[i]; }
const Type * const operator[]( const size_t i ) const override { return alc.ptr[i]; } const Type * const operator[]( const size_t i ) const override { return alc[i]; }
Type * &operator[]( const size_t i ) override { return alc.ptr[i]; } Type * &operator[]( const size_t i ) override { return alc[i]; }
const Type * const front() const override { return alc.ptr[0]; } const Type * const front() const override { return alc[0]; }
Type * &front() override { return alc.ptr[0]; } Type * &front() override { return alc[0]; }
const Type * const back() const override { return alc.ptr[alc.num_elements_used - 1]; } const Type * const back() const override { return alc[alc.num_elements_used - 1]; }
Type * &back() override { return alc.ptr[alc.num_elements_used - 1]; } Type * &back() override { return alc[alc.num_elements_used - 1]; }
const Type * const *data() const override { return &alc.ptr[0]; } const Type * const *data() const override { return alc.ptr; }
Type * *data() override { return &alc.ptr[0]; } Type * *data() override { return alc.ptr; }
size_t size() const override { return alc.num_elements_used; } size_t size() const override { return alc.num_elements_used; }
bool empty() const override { return alc.num_elements_used == 0; } bool empty() const override { return alc.num_elements_used == 0; }

View File

@ -21,6 +21,10 @@
#include <new> #include <new>
#include <type_traits> #include <type_traits>
#define MVK_VECTOR_CHECK_BOUNDS if (i >= num_elements_used) { throw std::out_of_range("Index out of range"); }
namespace mvk_memory_allocator namespace mvk_memory_allocator
{ {
inline char *alloc( const size_t num_bytes ) inline char *alloc( const size_t num_bytes )
@ -53,8 +57,8 @@ public:
mvk_vector_allocator_base( T *_ptr, const size_t _num_elements_used ) : ptr{ _ptr }, num_elements_used{ _num_elements_used } { } mvk_vector_allocator_base( T *_ptr, const size_t _num_elements_used ) : ptr{ _ptr }, num_elements_used{ _num_elements_used } { }
virtual ~mvk_vector_allocator_base() { } virtual ~mvk_vector_allocator_base() { }
const T &operator[]( const size_t i ) const { return ptr[i]; } const T &operator[]( const size_t i ) const { MVK_VECTOR_CHECK_BOUNDS return ptr[i]; }
T &operator[]( const size_t i ) { return ptr[i]; } T &operator[]( const size_t i ) { MVK_VECTOR_CHECK_BOUNDS return ptr[i]; }
size_t size() const { return num_elements_used; } size_t size() const { return num_elements_used; }