implementing renderpass and vieport
This commit is contained in:
Vendored
+10
-2
@@ -13,7 +13,15 @@
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/bin/Debug",
|
||||
"environment": [],
|
||||
"externalConsole": false
|
||||
"externalConsole": false,
|
||||
"symbolSearchPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.25.28610\\lib\\x64",
|
||||
"requireExactSource": false,
|
||||
"logging": {
|
||||
"moduleLoad": false,
|
||||
"exceptions": true,
|
||||
"trace": true,
|
||||
"traceResponse": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Test",
|
||||
@@ -25,6 +33,6 @@
|
||||
"cwd": "${workspaceRoot}/bin/Debug/test",
|
||||
"environment": [],
|
||||
"externalConsole": false
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
Vendored
+5
-2
@@ -11,6 +11,9 @@
|
||||
"xiosbase": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xtree": "cpp",
|
||||
"type_traits": "cpp"
|
||||
}
|
||||
"type_traits": "cpp",
|
||||
"vector": "cpp",
|
||||
"*.rh": "cpp",
|
||||
"memory": "cpp"
|
||||
},
|
||||
}
|
||||
@@ -58,6 +58,12 @@ target_link_libraries(SeeleEngine ${Vulkan_LIBRARY})
|
||||
target_link_libraries(SeeleEngine glfw ${GLFW_LIBRARIES})
|
||||
target_link_libraries(SeeleEngine ${SLANG_LIBRARY})
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(SeeleEngine PRIVATE /DEBUG:FASTLINK /Zi /W4)
|
||||
else()
|
||||
target_compile_options(SeeleEngine PRIVATE -Wall -Wextra -pedantic)
|
||||
endif()
|
||||
|
||||
add_subdirectory(test/)
|
||||
|
||||
add_custom_command(TARGET SeeleEngine POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DEPENDENT_BINARIES} $<TARGET_FILE_DIR:SeeleEngine>)
|
||||
|
||||
+404
-358
@@ -8,389 +8,435 @@
|
||||
#define DEFAULT_ALLOC_SIZE 16
|
||||
#endif
|
||||
|
||||
namespace Seele
|
||||
namespace Seele
|
||||
{
|
||||
template<typename T>
|
||||
struct Array
|
||||
template <typename T>
|
||||
struct Array
|
||||
{
|
||||
public:
|
||||
Array()
|
||||
: allocated(DEFAULT_ALLOC_SIZE), arraySize(0)
|
||||
{
|
||||
public:
|
||||
Array()
|
||||
: allocated(DEFAULT_ALLOC_SIZE)
|
||||
, arraySize(0)
|
||||
_data = new T[DEFAULT_ALLOC_SIZE];
|
||||
assert(_data != nullptr);
|
||||
memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE);
|
||||
refreshIterators();
|
||||
}
|
||||
Array(uint32 size, T value = T())
|
||||
: allocated(size), arraySize(size)
|
||||
{
|
||||
_data = new T[size];
|
||||
assert(_data != nullptr);
|
||||
for (uint32 i = 0; i < size; ++i)
|
||||
{
|
||||
_data = (T*)malloc(DEFAULT_ALLOC_SIZE * sizeof(T));
|
||||
assert(_data != nullptr);
|
||||
memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE);
|
||||
refreshIterators();
|
||||
assert(i < size);
|
||||
_data[i] = value;
|
||||
}
|
||||
Array(size_t size, T value = T())
|
||||
: allocated(size)
|
||||
, arraySize(size)
|
||||
refreshIterators();
|
||||
}
|
||||
Array(std::initializer_list<T> init)
|
||||
: allocated((uint32)init.size()), arraySize((uint32)init.size())
|
||||
{
|
||||
_data = new T[init.size()];
|
||||
auto it = init.begin();
|
||||
for (size_t i = 0; it != init.end(); i++, it++)
|
||||
{
|
||||
_data = (T*)malloc(size * sizeof(T));
|
||||
assert(_data != nullptr);
|
||||
for (int i = 0; i < size; ++i)
|
||||
assert(i < init.size());
|
||||
_data[i] = *it;
|
||||
}
|
||||
refreshIterators();
|
||||
}
|
||||
Array(const Array &other)
|
||||
: allocated(other.allocated), arraySize(other.arraySize)
|
||||
{
|
||||
_data = new T[other.allocated];
|
||||
assert(_data != nullptr);
|
||||
std::memcpy(_data, other._data, sizeof(T) * allocated);
|
||||
refreshIterators();
|
||||
}
|
||||
Array(Array &&other) noexcept
|
||||
: allocated(std::move(other.allocated)), arraySize(std::move(other.arraySize))
|
||||
{
|
||||
_data = other._data;
|
||||
other._data = nullptr;
|
||||
other.allocated = 0;
|
||||
other.arraySize = 0;
|
||||
refreshIterators();
|
||||
}
|
||||
Array &operator=(const Array &other) noexcept
|
||||
{
|
||||
if (*this != other)
|
||||
{
|
||||
if (_data != nullptr)
|
||||
{
|
||||
assert(i < size);
|
||||
_data[i] = value;
|
||||
delete[] _data;
|
||||
}
|
||||
refreshIterators();
|
||||
}
|
||||
Array(std::initializer_list<T> init)
|
||||
: allocated(init.size())
|
||||
, arraySize(init.size())
|
||||
{
|
||||
_data = (T*)malloc(init.size() * sizeof(T));
|
||||
auto it = init.begin();
|
||||
for (size_t i = 0; it != init.end(); i++, it++)
|
||||
{
|
||||
assert(i < init.size());
|
||||
_data[i] = *it;
|
||||
}
|
||||
refreshIterators();
|
||||
}
|
||||
Array(const Array& other)
|
||||
: allocated(other.allocated)
|
||||
, arraySize(other.arraySize)
|
||||
{
|
||||
_data = (T*)malloc(other.allocated * sizeof(T));
|
||||
assert(_data != nullptr);
|
||||
allocated = other.allocated;
|
||||
arraySize = other.arraySize;
|
||||
_data = new T[other.allocated];
|
||||
std::memcpy(_data, other._data, sizeof(T) * allocated);
|
||||
refreshIterators();
|
||||
}
|
||||
Array(Array&& other) noexcept
|
||||
: allocated(std::move(other.allocated))
|
||||
, arraySize(std::move(other.arraySize))
|
||||
return *this;
|
||||
}
|
||||
Array &operator=(Array &&other) noexcept
|
||||
{
|
||||
if (*this != other)
|
||||
{
|
||||
if (_data != nullptr)
|
||||
{
|
||||
delete[] _data;
|
||||
}
|
||||
allocated = std::move(other.allocated);
|
||||
arraySize = std::move(other.arraySize);
|
||||
_data = other._data;
|
||||
other._data = nullptr;
|
||||
other.allocated = 0;
|
||||
other.arraySize = 0;
|
||||
refreshIterators();
|
||||
}
|
||||
Array& operator=(const Array& other) noexcept
|
||||
return *this;
|
||||
}
|
||||
~Array()
|
||||
{
|
||||
if (_data)
|
||||
{
|
||||
if(*this != other)
|
||||
{
|
||||
if (_data != nullptr)
|
||||
{
|
||||
free(_data);
|
||||
}
|
||||
allocated = other.allocated;
|
||||
arraySize = other.arraySize;
|
||||
_data = (T*)malloc(other.allocated * sizeof(T));
|
||||
std::memcpy(_data, other._data, sizeof(T) * allocated);
|
||||
refreshIterators();
|
||||
}
|
||||
return *this;
|
||||
delete[] _data;
|
||||
_data = nullptr;
|
||||
}
|
||||
Array& operator=(Array&& other) noexcept
|
||||
{
|
||||
if(*this != other)
|
||||
{
|
||||
if (_data != nullptr)
|
||||
{
|
||||
free(_data);
|
||||
}
|
||||
allocated = std::move(other.allocated);
|
||||
arraySize = std::move(other.arraySize);
|
||||
_data = other._data;
|
||||
other._data = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~Array()
|
||||
{
|
||||
if(_data)
|
||||
{
|
||||
free(_data);
|
||||
_data = nullptr;
|
||||
}
|
||||
}
|
||||
template<typename X>
|
||||
class IteratorBase {
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef X value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef X& reference;
|
||||
typedef X* pointer;
|
||||
|
||||
IteratorBase(X* x = nullptr)
|
||||
: p(x)
|
||||
{}
|
||||
IteratorBase(const IteratorBase& i)
|
||||
: p(i.p)
|
||||
{}
|
||||
reference operator*() const
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
inline bool operator!=(const IteratorBase& other)
|
||||
{
|
||||
return p != other.p;
|
||||
}
|
||||
inline bool operator==(const IteratorBase& other)
|
||||
{
|
||||
return p == other.p;
|
||||
}
|
||||
inline int operator-(const IteratorBase& other)
|
||||
{
|
||||
return p - other.p;
|
||||
}
|
||||
IteratorBase& operator++() {
|
||||
p++;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase& operator--() {
|
||||
p--;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator++(int) {
|
||||
IteratorBase tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
IteratorBase operator--(int) {
|
||||
IteratorBase tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
private:
|
||||
X* p;
|
||||
};
|
||||
typedef IteratorBase<T> Iterator;
|
||||
typedef IteratorBase<const T> ConstIterator;
|
||||
|
||||
bool operator==(const Array& other)
|
||||
{
|
||||
return _data == other._data;
|
||||
}
|
||||
|
||||
bool operator!=(const Array& other)
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
Iterator find(const T& item)
|
||||
{
|
||||
for (int i = 0; i < arraySize; ++i)
|
||||
{
|
||||
if (_data[i] == item)
|
||||
{
|
||||
return Iterator(&_data[i]);
|
||||
}
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
Iterator begin()
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
Iterator end()
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
|
||||
T& add(const T& item)
|
||||
{
|
||||
if (arraySize == allocated)
|
||||
{
|
||||
uint32 newSize = arraySize + 1;
|
||||
allocated = calculateGrowth(newSize);
|
||||
void* tempArray = malloc(sizeof(T) * allocated);
|
||||
assert(tempArray != nullptr);
|
||||
std::memset(tempArray, 0, sizeof(T) * allocated);
|
||||
std::memcpy(tempArray, _data, arraySize * sizeof(T));
|
||||
delete _data;
|
||||
_data = (T*)tempArray;
|
||||
}
|
||||
_data[arraySize++] = item;
|
||||
refreshIterators();
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
void remove(Iterator it, bool keepOrder = true)
|
||||
{
|
||||
remove(it - beginIt, keepOrder);
|
||||
}
|
||||
void remove(int index, bool keepOrder = true)
|
||||
{
|
||||
if (keepOrder)
|
||||
{
|
||||
std::memcpy(&_data[index], &_data[index + 1], sizeof(T) * (arraySize - index));
|
||||
}
|
||||
else
|
||||
{
|
||||
_data[index] = _data[arraySize - 1];
|
||||
}
|
||||
arraySize--;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
arraySize = 0;
|
||||
allocated = 0;
|
||||
refreshIterators();
|
||||
}
|
||||
void resize(uint32 newSize)
|
||||
{
|
||||
if (newSize < allocated)
|
||||
{
|
||||
arraySize = newSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
T* newData = (T*)malloc(newSize * sizeof(T));
|
||||
assert(newData != nullptr);
|
||||
allocated = newSize;
|
||||
std::memcpy(newData, _data, sizeof(T) * arraySize);
|
||||
arraySize = newSize;
|
||||
delete _data;
|
||||
_data = newData;
|
||||
}
|
||||
refreshIterators();
|
||||
}
|
||||
inline uint32 size() const
|
||||
{
|
||||
return arraySize;
|
||||
}
|
||||
inline uint32 capacity() const
|
||||
{
|
||||
return allocated;
|
||||
}
|
||||
inline T* data() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
T& back() const
|
||||
{
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
void pop()
|
||||
{
|
||||
arraySize--;
|
||||
}
|
||||
T& operator[](int index) const
|
||||
{
|
||||
assert(index >= 0 && index < arraySize);
|
||||
return _data[index];
|
||||
}
|
||||
private:
|
||||
uint32 calculateGrowth(uint32 newSize) const
|
||||
{
|
||||
const uint32 oldCapacity = capacity();
|
||||
|
||||
if (oldCapacity > UINT32_MAX - oldCapacity / 2) {
|
||||
return newSize; // geometric growth would overflow
|
||||
}
|
||||
|
||||
const uint32 geometric = oldCapacity + oldCapacity / 2;
|
||||
|
||||
if (geometric < newSize) {
|
||||
return newSize; // geometric growth would be insufficient
|
||||
}
|
||||
|
||||
return geometric; // geometric growth is sufficient
|
||||
}
|
||||
void refreshIterators()
|
||||
{
|
||||
beginIt = Iterator(_data);
|
||||
endIt = Iterator(_data + arraySize);
|
||||
}
|
||||
uint32 arraySize;
|
||||
uint32 allocated;
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
T* _data;
|
||||
};
|
||||
|
||||
template<typename T, uint32 N>
|
||||
struct StaticArray
|
||||
}
|
||||
template <typename X>
|
||||
class IteratorBase
|
||||
{
|
||||
public:
|
||||
StaticArray()
|
||||
{
|
||||
beginIt = Iterator(_data);
|
||||
endIt = Iterator(_data + N);
|
||||
}
|
||||
StaticArray(T value)
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
_data[i] = value;
|
||||
}
|
||||
beginIt = Iterator(_data);
|
||||
endIt = Iterator(_data + N);
|
||||
}
|
||||
~StaticArray()
|
||||
{}
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef X value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef X &reference;
|
||||
typedef X *pointer;
|
||||
|
||||
inline uint32 size() const
|
||||
IteratorBase(X *x = nullptr)
|
||||
: p(x)
|
||||
{
|
||||
return N;
|
||||
}
|
||||
inline T* data() const
|
||||
IteratorBase(const IteratorBase &i)
|
||||
: p(i.p)
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
T& operator[](int index)
|
||||
reference operator*() const
|
||||
{
|
||||
assert(index >= 0 && index < N);
|
||||
return _data[index];
|
||||
return *p;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
inline bool operator!=(const IteratorBase &other)
|
||||
{
|
||||
return p != other.p;
|
||||
}
|
||||
inline bool operator==(const IteratorBase &other)
|
||||
{
|
||||
return p == other.p;
|
||||
}
|
||||
inline int operator-(const IteratorBase &other)
|
||||
{
|
||||
return (int)(p - other.p);
|
||||
}
|
||||
IteratorBase &operator++()
|
||||
{
|
||||
p++;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase &operator--()
|
||||
{
|
||||
p--;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator++(int)
|
||||
{
|
||||
IteratorBase tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
IteratorBase operator--(int)
|
||||
{
|
||||
IteratorBase tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
class IteratorBase {
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef X value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef X& reference;
|
||||
typedef X* pointer;
|
||||
|
||||
IteratorBase(X* x = nullptr)
|
||||
: p(x)
|
||||
{}
|
||||
IteratorBase(const IteratorBase& i)
|
||||
: p(i.p)
|
||||
{}
|
||||
reference operator*() const
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
inline bool operator!=(const IteratorBase& other)
|
||||
{
|
||||
return p != other.p;
|
||||
}
|
||||
inline bool operator==(const IteratorBase& other)
|
||||
{
|
||||
return p == other.p;
|
||||
}
|
||||
IteratorBase& operator++() {
|
||||
p++;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator++(int) {
|
||||
IteratorBase tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
private:
|
||||
X* p;
|
||||
};
|
||||
typedef IteratorBase<T> Iterator;
|
||||
typedef IteratorBase<const T> ConstIterator;
|
||||
|
||||
private:
|
||||
T _data[N];
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
X *p;
|
||||
};
|
||||
}
|
||||
typedef IteratorBase<T> Iterator;
|
||||
typedef IteratorBase<const T> ConstIterator;
|
||||
|
||||
bool operator==(const Array &other)
|
||||
{
|
||||
return _data == other._data;
|
||||
}
|
||||
|
||||
bool operator!=(const Array &other)
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
Iterator find(const T &item)
|
||||
{
|
||||
for (uint32 i = 0; i < arraySize; ++i)
|
||||
{
|
||||
if (_data[i] == item)
|
||||
{
|
||||
return Iterator(&_data[i]);
|
||||
}
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
Iterator begin()
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
Iterator begin() const
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
Iterator end()
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
Iterator end() const
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
|
||||
T &add(const T &item = T())
|
||||
{
|
||||
if (arraySize == allocated)
|
||||
{
|
||||
uint32 newSize = arraySize + 1;
|
||||
allocated = calculateGrowth(newSize);
|
||||
T *tempArray = new T[allocated];
|
||||
assert(tempArray != nullptr);
|
||||
for (uint32 i = 0; i < arraySize; ++i)
|
||||
{
|
||||
tempArray[i] = _data[i];
|
||||
}
|
||||
delete[] _data;
|
||||
_data = tempArray;
|
||||
}
|
||||
_data[arraySize++] = item;
|
||||
refreshIterators();
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
void remove(Iterator it, bool keepOrder = true)
|
||||
{
|
||||
remove(it - beginIt, keepOrder);
|
||||
}
|
||||
void remove(int index, bool keepOrder = true)
|
||||
{
|
||||
if (keepOrder)
|
||||
{
|
||||
std::memcpy(&_data[index], &_data[index + 1], sizeof(T) * (arraySize - index));
|
||||
}
|
||||
else
|
||||
{
|
||||
_data[index] = _data[arraySize - 1];
|
||||
}
|
||||
arraySize--;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
delete[] _data;
|
||||
_data = nullptr;
|
||||
arraySize = 0;
|
||||
allocated = 0;
|
||||
refreshIterators();
|
||||
}
|
||||
void resize(uint32 newSize)
|
||||
{
|
||||
if (newSize < allocated)
|
||||
{
|
||||
arraySize = newSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
T *newData = new T[newSize];
|
||||
assert(newData != nullptr);
|
||||
allocated = newSize;
|
||||
std::memcpy(newData, _data, sizeof(T) * arraySize);
|
||||
arraySize = newSize;
|
||||
delete _data;
|
||||
_data = newData;
|
||||
}
|
||||
refreshIterators();
|
||||
}
|
||||
inline uint32 size() const
|
||||
{
|
||||
return arraySize;
|
||||
}
|
||||
inline uint32 capacity() const
|
||||
{
|
||||
return allocated;
|
||||
}
|
||||
inline T *data() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
T &back() const
|
||||
{
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
void pop()
|
||||
{
|
||||
arraySize--;
|
||||
}
|
||||
T &operator[](uint32 index)
|
||||
{
|
||||
assert(index < arraySize);
|
||||
return _data[index];
|
||||
}
|
||||
inline T &operator[](size_t index)
|
||||
{
|
||||
return this->operator[]((uint32)index);
|
||||
}
|
||||
inline T &operator[](int32 index)
|
||||
{
|
||||
return this->operator[]((uint32)index);
|
||||
}
|
||||
const T &operator[](uint32 index) const
|
||||
{
|
||||
assert(index < arraySize);
|
||||
return _data[index];
|
||||
}
|
||||
inline const T &operator[](size_t index) const
|
||||
{
|
||||
return this->operator[]((uint32)index);
|
||||
}
|
||||
inline const T &operator[](int32 index) const
|
||||
{
|
||||
return this->operator[]((uint32)index);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 calculateGrowth(uint32 newSize) const
|
||||
{
|
||||
const uint32 oldCapacity = capacity();
|
||||
|
||||
if (oldCapacity > UINT32_MAX - oldCapacity / 2)
|
||||
{
|
||||
return newSize; // geometric growth would overflow
|
||||
}
|
||||
|
||||
const uint32 geometric = oldCapacity + oldCapacity / 2;
|
||||
|
||||
if (geometric < newSize)
|
||||
{
|
||||
return newSize; // geometric growth would be insufficient
|
||||
}
|
||||
|
||||
return geometric; // geometric growth is sufficient
|
||||
}
|
||||
void refreshIterators()
|
||||
{
|
||||
beginIt = Iterator(_data);
|
||||
endIt = Iterator(_data + arraySize);
|
||||
}
|
||||
uint32 arraySize;
|
||||
uint32 allocated;
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
T *_data;
|
||||
};
|
||||
|
||||
template <typename T, uint32 N>
|
||||
struct StaticArray
|
||||
{
|
||||
public:
|
||||
StaticArray()
|
||||
{
|
||||
beginIt = Iterator(_data);
|
||||
endIt = Iterator(_data + N);
|
||||
}
|
||||
StaticArray(T value)
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
_data[i] = value;
|
||||
}
|
||||
beginIt = Iterator(_data);
|
||||
endIt = Iterator(_data + N);
|
||||
}
|
||||
~StaticArray()
|
||||
{
|
||||
}
|
||||
|
||||
inline uint32 size() const
|
||||
{
|
||||
return N;
|
||||
}
|
||||
inline T *data() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
T &operator[](int index)
|
||||
{
|
||||
assert(index >= 0 && index < N);
|
||||
return _data[index];
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
class IteratorBase
|
||||
{
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef X value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef X &reference;
|
||||
typedef X *pointer;
|
||||
|
||||
IteratorBase(X *x = nullptr)
|
||||
: p(x)
|
||||
{
|
||||
}
|
||||
IteratorBase(const IteratorBase &i)
|
||||
: p(i.p)
|
||||
{
|
||||
}
|
||||
reference operator*() const
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
inline bool operator!=(const IteratorBase &other)
|
||||
{
|
||||
return p != other.p;
|
||||
}
|
||||
inline bool operator==(const IteratorBase &other)
|
||||
{
|
||||
return p == other.p;
|
||||
}
|
||||
IteratorBase &operator++()
|
||||
{
|
||||
p++;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator++(int)
|
||||
{
|
||||
IteratorBase tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
X *p;
|
||||
};
|
||||
typedef IteratorBase<T> Iterator;
|
||||
typedef IteratorBase<const T> ConstIterator;
|
||||
|
||||
private:
|
||||
T _data[N];
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
};
|
||||
} // namespace Seele
|
||||
+196
-187
@@ -2,207 +2,216 @@
|
||||
#include "MinimalEngine.h"
|
||||
namespace Seele
|
||||
{
|
||||
template<typename T>
|
||||
class List
|
||||
template <typename T>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
struct Node
|
||||
{
|
||||
Node *prev;
|
||||
Node *next;
|
||||
T data;
|
||||
};
|
||||
|
||||
public:
|
||||
List()
|
||||
{
|
||||
root = nullptr;
|
||||
tail = nullptr;
|
||||
beginIt = Iterator(root);
|
||||
endIt = Iterator(tail);
|
||||
size = 0;
|
||||
}
|
||||
~List()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
template <typename X>
|
||||
class IteratorBase
|
||||
{
|
||||
private:
|
||||
struct Node
|
||||
{
|
||||
Node* prev;
|
||||
Node* next;
|
||||
T data;
|
||||
};
|
||||
public:
|
||||
List()
|
||||
{
|
||||
root = nullptr;
|
||||
tail = nullptr;
|
||||
beginIt = Iterator(root);
|
||||
endIt = Iterator(tail);
|
||||
size = 0;
|
||||
}
|
||||
~List()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
template<typename X>
|
||||
class IteratorBase {
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef X value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef X& reference;
|
||||
typedef X* pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef X value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef X &reference;
|
||||
typedef X *pointer;
|
||||
|
||||
IteratorBase(Node* x = nullptr)
|
||||
: node(x)
|
||||
{}
|
||||
IteratorBase(const IteratorBase& i)
|
||||
: node(i.node)
|
||||
{}
|
||||
reference operator*() const
|
||||
{
|
||||
return node->data;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return &node->data;
|
||||
}
|
||||
inline bool operator!=(const IteratorBase& other)
|
||||
{
|
||||
return node != other.node;
|
||||
}
|
||||
inline bool operator==(const IteratorBase& other)
|
||||
{
|
||||
return node == other.node;
|
||||
}
|
||||
IteratorBase& operator--() {
|
||||
node = node->prev;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator--(int) {
|
||||
IteratorBase tmp(*this);
|
||||
--* this;
|
||||
return tmp;
|
||||
}
|
||||
IteratorBase& operator++() {
|
||||
node = node->next;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator++(int) {
|
||||
IteratorBase tmp(*this);
|
||||
++* this;
|
||||
return tmp;
|
||||
}
|
||||
private:
|
||||
Node* node;
|
||||
friend class List<T>;
|
||||
};
|
||||
typedef IteratorBase<T> Iterator;
|
||||
typedef IteratorBase<const T> ConstIterator;
|
||||
IteratorBase(Node *x = nullptr)
|
||||
: node(x)
|
||||
{
|
||||
}
|
||||
IteratorBase(const IteratorBase &i)
|
||||
: node(i.node)
|
||||
{
|
||||
}
|
||||
reference operator*() const
|
||||
{
|
||||
return node->data;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return &node->data;
|
||||
}
|
||||
inline bool operator!=(const IteratorBase &other)
|
||||
{
|
||||
return node != other.node;
|
||||
}
|
||||
inline bool operator==(const IteratorBase &other)
|
||||
{
|
||||
return node == other.node;
|
||||
}
|
||||
IteratorBase &operator--()
|
||||
{
|
||||
node = node->prev;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator--(int)
|
||||
{
|
||||
IteratorBase tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
IteratorBase &operator++()
|
||||
{
|
||||
node = node->next;
|
||||
return *this;
|
||||
}
|
||||
IteratorBase operator++(int)
|
||||
{
|
||||
IteratorBase tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T& front()
|
||||
private:
|
||||
Node *node;
|
||||
friend class List<T>;
|
||||
};
|
||||
typedef IteratorBase<T> Iterator;
|
||||
typedef IteratorBase<const T> ConstIterator;
|
||||
|
||||
T &front()
|
||||
{
|
||||
return root->data;
|
||||
}
|
||||
T &back()
|
||||
{
|
||||
return tail->prev->data;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
return root->data;
|
||||
return;
|
||||
}
|
||||
T& back()
|
||||
for (Node *tmp = root; tmp != tail;)
|
||||
{
|
||||
return tail->prev->data;
|
||||
tmp = tmp->next;
|
||||
delete tmp->prev;
|
||||
}
|
||||
void clear()
|
||||
delete tail;
|
||||
tail = nullptr;
|
||||
root = nullptr;
|
||||
}
|
||||
//Insert at the end
|
||||
Iterator add(const T &value)
|
||||
{
|
||||
if (root == nullptr)
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (Node* tmp = root; tmp != tail;)
|
||||
{
|
||||
tmp = tmp->next;
|
||||
delete tmp->prev;
|
||||
}
|
||||
delete tail;
|
||||
tail = nullptr;
|
||||
root = nullptr;
|
||||
root = new Node();
|
||||
tail = root;
|
||||
}
|
||||
//Insert at the end
|
||||
Iterator add(const T& value)
|
||||
tail->data = value;
|
||||
Node *newTail = new Node();
|
||||
newTail->prev = tail;
|
||||
newTail->next = nullptr;
|
||||
tail->next = newTail;
|
||||
Iterator insertedElement(tail);
|
||||
tail = newTail;
|
||||
refreshIterators();
|
||||
size++;
|
||||
return insertedElement;
|
||||
}
|
||||
Iterator remove(Iterator pos)
|
||||
{
|
||||
size--;
|
||||
Node *prev = pos.node->prev;
|
||||
Node *next = pos.node->next;
|
||||
if (prev == nullptr)
|
||||
{
|
||||
if (root == nullptr)
|
||||
{
|
||||
root = new Node();
|
||||
tail = root;
|
||||
}
|
||||
tail->data = value;
|
||||
Node* newTail = new Node();
|
||||
newTail->prev = tail;
|
||||
newTail->next = nullptr;
|
||||
tail->next = newTail;
|
||||
Iterator insertedElement(tail);
|
||||
tail = newTail;
|
||||
root = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = next;
|
||||
}
|
||||
next->prev = prev;
|
||||
delete pos.node;
|
||||
refreshIterators();
|
||||
return Iterator(next);
|
||||
}
|
||||
Iterator insert(Iterator pos, const T &value)
|
||||
{
|
||||
size++;
|
||||
if (root == nullptr)
|
||||
{
|
||||
root = new Node();
|
||||
root->data = value;
|
||||
tail = new Node();
|
||||
root->next = tail;
|
||||
root->prev = nullptr;
|
||||
tail->prev = root;
|
||||
tail->next = nullptr;
|
||||
refreshIterators();
|
||||
size++;
|
||||
return insertedElement;
|
||||
}
|
||||
Iterator remove(Iterator pos)
|
||||
{
|
||||
size--;
|
||||
Node* prev = pos.node->prev;
|
||||
Node* next = pos.node->next;
|
||||
if (prev == nullptr)
|
||||
{
|
||||
root = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = next;
|
||||
}
|
||||
next->prev = prev;
|
||||
delete pos.node;
|
||||
refreshIterators();
|
||||
return Iterator(next);
|
||||
}
|
||||
Iterator insert(Iterator pos, const T& value)
|
||||
{
|
||||
size++;
|
||||
if (root == nullptr)
|
||||
{
|
||||
root = new Node();
|
||||
root->data = value;
|
||||
tail = new Node();
|
||||
root->next = tail;
|
||||
root->prev = nullptr;
|
||||
tail->prev = root;
|
||||
tail->next = nullptr;
|
||||
refreshIterators();
|
||||
return beginIt;
|
||||
}
|
||||
Node* tmp = pos.node->prev;
|
||||
Node* newNode = new Node();
|
||||
newNode->data = value;
|
||||
tmp->next = newNode;
|
||||
newNode->prev = tmp;
|
||||
newNode->next = pos.node;
|
||||
pos.node->prev = newNode;
|
||||
return Iterator(newNode);
|
||||
}
|
||||
Iterator find(const T& value)
|
||||
{
|
||||
for (Node* i = root; i != tail; i = i->next)
|
||||
{
|
||||
if (!(i->data < value) && !(value < i->data))
|
||||
{
|
||||
return Iterator(i);
|
||||
}
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return size == 0;
|
||||
}
|
||||
uint32 length()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
Iterator begin()
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
Iterator end()
|
||||
Node *tmp = pos.node->prev;
|
||||
Node *newNode = new Node();
|
||||
newNode->data = value;
|
||||
tmp->next = newNode;
|
||||
newNode->prev = tmp;
|
||||
newNode->next = pos.node;
|
||||
pos.node->prev = newNode;
|
||||
return Iterator(newNode);
|
||||
}
|
||||
Iterator find(const T &value)
|
||||
{
|
||||
for (Node *i = root; i != tail; i = i->next)
|
||||
{
|
||||
return endIt;
|
||||
if (!(i->data < value) && !(value < i->data))
|
||||
{
|
||||
return Iterator(i);
|
||||
}
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return size == 0;
|
||||
}
|
||||
uint32 length()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
Iterator begin()
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
Iterator end()
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
|
||||
private:
|
||||
void refreshIterators()
|
||||
{
|
||||
beginIt = Iterator(root);
|
||||
endIt = Iterator(tail);
|
||||
}
|
||||
Node* root;
|
||||
Node* tail;
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
uint32 size;
|
||||
};
|
||||
}
|
||||
private:
|
||||
void refreshIterators()
|
||||
{
|
||||
beginIt = Iterator(root);
|
||||
endIt = Iterator(tail);
|
||||
}
|
||||
Node *root;
|
||||
Node *tail;
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
uint32 size;
|
||||
};
|
||||
} // namespace Seele
|
||||
+312
-285
@@ -3,334 +3,361 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template<typename K, typename V>
|
||||
struct Pair
|
||||
template <typename K, typename V>
|
||||
struct Pair
|
||||
{
|
||||
public:
|
||||
Pair()
|
||||
: key(K()), value(V())
|
||||
{
|
||||
public:
|
||||
Pair()
|
||||
: key(K())
|
||||
, value(V())
|
||||
{}
|
||||
Pair(K key, V value)
|
||||
: key(key)
|
||||
, value(value)
|
||||
{}
|
||||
K key;
|
||||
V value;
|
||||
}
|
||||
Pair(K key, V value)
|
||||
: key(key), value(value)
|
||||
{
|
||||
}
|
||||
K key;
|
||||
V value;
|
||||
};
|
||||
template <typename K, typename V>
|
||||
struct Map
|
||||
{
|
||||
private:
|
||||
struct Node
|
||||
{
|
||||
Pair<K, V> pair;
|
||||
Node *leftChild;
|
||||
Node *rightChild;
|
||||
Node(const K &key)
|
||||
: leftChild(nullptr), rightChild(nullptr), pair(key, V())
|
||||
{
|
||||
}
|
||||
Node()
|
||||
: leftChild(nullptr), rightChild(nullptr), pair(K(), V())
|
||||
{
|
||||
}
|
||||
~Node()
|
||||
{
|
||||
if (leftChild != nullptr)
|
||||
{
|
||||
delete leftChild;
|
||||
}
|
||||
if (rightChild != nullptr)
|
||||
{
|
||||
delete rightChild;
|
||||
}
|
||||
}
|
||||
};
|
||||
template<typename K, typename V>
|
||||
struct Map
|
||||
|
||||
public:
|
||||
Map()
|
||||
: root(nullptr), _size(0)
|
||||
{
|
||||
}
|
||||
~Map()
|
||||
{
|
||||
delete root;
|
||||
}
|
||||
class Iterator
|
||||
{
|
||||
private:
|
||||
struct Node
|
||||
{
|
||||
Pair<K, V> pair;
|
||||
Node* leftChild;
|
||||
Node* rightChild;
|
||||
Node(const K& key)
|
||||
: leftChild(nullptr)
|
||||
, rightChild(nullptr)
|
||||
, pair(key, V())
|
||||
{}
|
||||
Node()
|
||||
: leftChild(nullptr)
|
||||
, rightChild(nullptr)
|
||||
, pair(K(), V())
|
||||
{}
|
||||
~Node()
|
||||
{
|
||||
if(leftChild != nullptr)
|
||||
{
|
||||
delete leftChild;
|
||||
}
|
||||
if(rightChild != nullptr)
|
||||
{
|
||||
delete rightChild;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
Map()
|
||||
: root(nullptr)
|
||||
{}
|
||||
~Map()
|
||||
{
|
||||
delete root;
|
||||
}
|
||||
class Iterator {
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef Pair<K, V> value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Pair<K, V>& reference;
|
||||
typedef Pair<K, V>* pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef Pair<K, V> value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Pair<K, V> &reference;
|
||||
typedef Pair<K, V> *pointer;
|
||||
|
||||
Iterator(Node* x = nullptr)
|
||||
: node(x)
|
||||
{}
|
||||
Iterator(Node* x, Array<Node*>&& beginIt)
|
||||
: node(x)
|
||||
, traversal(std::move(beginIt))
|
||||
{}
|
||||
Iterator(const Iterator& i)
|
||||
: node(i.node)
|
||||
, traversal(i.traversal)
|
||||
{}
|
||||
reference operator*() const
|
||||
Iterator(Node *x = nullptr)
|
||||
: node(x)
|
||||
{
|
||||
}
|
||||
Iterator(Node *x, Array<Node *> &&beginIt)
|
||||
: node(x), traversal(std::move(beginIt))
|
||||
{
|
||||
}
|
||||
Iterator(const Iterator &i)
|
||||
: node(i.node), traversal(i.traversal)
|
||||
{
|
||||
}
|
||||
reference operator*() const
|
||||
{
|
||||
return node->pair;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return &node->pair;
|
||||
}
|
||||
inline bool operator!=(const Iterator &other)
|
||||
{
|
||||
return node != other.node;
|
||||
}
|
||||
inline bool operator==(const Iterator &other)
|
||||
{
|
||||
return node == other.node;
|
||||
}
|
||||
Iterator &operator++()
|
||||
{
|
||||
node = node->rightChild;
|
||||
while (node != nullptr && node->leftChild != nullptr)
|
||||
{
|
||||
return node->pair;
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return &node->pair;
|
||||
}
|
||||
inline bool operator!=(const Iterator& other)
|
||||
{
|
||||
return node != other.node;
|
||||
}
|
||||
inline bool operator==(const Iterator& other)
|
||||
{
|
||||
return node == other.node;
|
||||
}
|
||||
Iterator& operator++() {
|
||||
node = node->rightChild;
|
||||
while(node != nullptr && node->leftChild != nullptr)
|
||||
{
|
||||
traversal.add(node);
|
||||
node = node->leftChild;
|
||||
}
|
||||
if(node == nullptr && traversal.size() > 0)
|
||||
{
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Iterator& operator--() {
|
||||
traversal.add(node);
|
||||
node = node->leftChild;
|
||||
while(node != nullptr && node->rightchild != nullptr)
|
||||
{
|
||||
traversal.add(node);
|
||||
node = node->rightChild;
|
||||
}
|
||||
if(node == nullptr && traversal.size() > 0)
|
||||
{
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Iterator operator--(int) {
|
||||
Iterator tmp(*this);
|
||||
++* this;
|
||||
return tmp;
|
||||
}
|
||||
Iterator operator++(int) {
|
||||
Iterator tmp(*this);
|
||||
++* this;
|
||||
return tmp;
|
||||
}
|
||||
private:
|
||||
Node* node;
|
||||
Array<Node*> traversal;
|
||||
};
|
||||
V& operator[](const K& key)
|
||||
{
|
||||
root = splay(root, key);
|
||||
if (root == nullptr || root->pair.key < key || key < root->pair.key)
|
||||
if (node == nullptr && traversal.size() > 0)
|
||||
{
|
||||
root = insert(root, key);
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
}
|
||||
refreshIterators();
|
||||
return root->pair.value;
|
||||
return *this;
|
||||
}
|
||||
Iterator find(const K& key)
|
||||
Iterator &operator--()
|
||||
{
|
||||
root = splay(root, key);
|
||||
if (root == nullptr || root->pair.key != key)
|
||||
node = node->leftChild;
|
||||
while (node != nullptr && node->rightchild != nullptr)
|
||||
{
|
||||
return endIt;
|
||||
traversal.add(node);
|
||||
node = node->rightChild;
|
||||
}
|
||||
return Iterator(root);
|
||||
if (node == nullptr && traversal.size() > 0)
|
||||
{
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Iterator erase(const K& key)
|
||||
Iterator operator--(int)
|
||||
{
|
||||
root = remove(root, key);
|
||||
refreshIterators();
|
||||
return Iterator(root);
|
||||
Iterator tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
bool exists(const K& key)
|
||||
Iterator operator++(int)
|
||||
{
|
||||
return find(key) != endIt;
|
||||
Iterator tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
Iterator begin() const
|
||||
|
||||
private:
|
||||
Node *node;
|
||||
Array<Node *> traversal;
|
||||
};
|
||||
V &operator[](const K &key)
|
||||
{
|
||||
root = splay(root, key);
|
||||
if (root == nullptr || root->pair.key < key || key < root->pair.key)
|
||||
{
|
||||
return beginIt;
|
||||
root = insert(root, key);
|
||||
_size++;
|
||||
}
|
||||
Iterator end() const
|
||||
refreshIterators();
|
||||
return root->pair.value;
|
||||
}
|
||||
Iterator find(const K &key)
|
||||
{
|
||||
root = splay(root, key);
|
||||
if (root == nullptr || root->pair.key != key)
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
private:
|
||||
void refreshIterators()
|
||||
return Iterator(root);
|
||||
}
|
||||
Iterator erase(const K &key)
|
||||
{
|
||||
root = remove(root, key);
|
||||
refreshIterators();
|
||||
return Iterator(root);
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
delete root;
|
||||
root = nullptr;
|
||||
_size = 0;
|
||||
refreshIterators();
|
||||
}
|
||||
bool exists(const K &key)
|
||||
{
|
||||
return find(key) != endIt;
|
||||
}
|
||||
Iterator begin() const
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
Iterator end() const
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
bool empty() const
|
||||
{
|
||||
return root == nullptr;
|
||||
}
|
||||
uint32 size() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
private:
|
||||
void refreshIterators()
|
||||
{
|
||||
Node *beginNode = root;
|
||||
if (root == nullptr)
|
||||
{
|
||||
Node* beginNode = root;
|
||||
if(root == nullptr)
|
||||
beginIt = Iterator(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array<Node *> beginTraversal;
|
||||
while (beginNode != nullptr)
|
||||
{
|
||||
beginIt = Iterator(nullptr);
|
||||
beginTraversal.add(beginNode);
|
||||
beginNode = beginNode->leftChild;
|
||||
}
|
||||
else
|
||||
beginNode = beginTraversal.back();
|
||||
beginTraversal.pop();
|
||||
beginIt = Iterator(beginNode, std::move(beginTraversal));
|
||||
}
|
||||
Node *endNode = root;
|
||||
if (root == nullptr)
|
||||
{
|
||||
endIt = Iterator(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array<Node *> endTraversal;
|
||||
while (endNode != nullptr)
|
||||
{
|
||||
Array<Node*> beginTraversal;
|
||||
while(beginNode != nullptr)
|
||||
{
|
||||
beginTraversal.add(beginNode);
|
||||
beginNode = beginNode->leftChild;
|
||||
}
|
||||
beginNode = beginTraversal.back();
|
||||
beginTraversal.pop();
|
||||
beginIt = Iterator(beginNode, std::move(beginTraversal));
|
||||
endTraversal.add(endNode);
|
||||
endNode = endNode->rightChild;
|
||||
}
|
||||
Node* endNode = root;
|
||||
if(root == nullptr)
|
||||
endIt = Iterator(endNode, std::move(endTraversal));
|
||||
}
|
||||
}
|
||||
Node *root;
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
uint32 _size;
|
||||
Node *rotateRight(Node *node)
|
||||
{
|
||||
Node *y = node->leftChild;
|
||||
node->leftChild = y->rightChild;
|
||||
y->rightChild = node;
|
||||
return y;
|
||||
}
|
||||
Node *rotateLeft(Node *node)
|
||||
{
|
||||
Node *y = node->rightChild;
|
||||
node->rightChild = y->leftChild;
|
||||
y->leftChild = node;
|
||||
return y;
|
||||
}
|
||||
Node *makeNode(const K &key)
|
||||
{
|
||||
return new Node(key);
|
||||
}
|
||||
Node *insert(Node *r, const K &key)
|
||||
{
|
||||
if (r == nullptr)
|
||||
return makeNode(key);
|
||||
|
||||
r = splay(r, key);
|
||||
|
||||
if (!(r->pair.key < key || key < r->pair.key))
|
||||
return r;
|
||||
|
||||
Node *newNode = makeNode(key);
|
||||
|
||||
if (key < r->pair.key)
|
||||
{
|
||||
newNode->rightChild = r;
|
||||
newNode->leftChild = r->leftChild;
|
||||
r->leftChild = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
newNode->leftChild = r;
|
||||
newNode->rightChild = r->rightChild;
|
||||
r->rightChild = nullptr;
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
Node *remove(Node *r, const K &key)
|
||||
{
|
||||
Node *temp;
|
||||
if (!r)
|
||||
return nullptr;
|
||||
|
||||
r = splay(r, key);
|
||||
|
||||
if (r->pair.key < key || key < r->pair.key)
|
||||
return r;
|
||||
|
||||
if (!r->leftChild)
|
||||
{
|
||||
temp = r;
|
||||
r = r->rightChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = r;
|
||||
|
||||
r = splay(r->leftChild, key);
|
||||
r->rightChild = temp->rightChild;
|
||||
}
|
||||
temp->leftChild = nullptr;
|
||||
temp->rightChild = nullptr;
|
||||
_size--;
|
||||
delete temp;
|
||||
return r;
|
||||
}
|
||||
Node *splay(Node *r, const K &key)
|
||||
{
|
||||
if (r == nullptr || !(r->pair.key < key || key < r->pair.key))
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
if (key < r->pair.key)
|
||||
{
|
||||
if (r->leftChild == nullptr)
|
||||
return r;
|
||||
|
||||
if (key < r->leftChild->pair.key)
|
||||
{
|
||||
endIt = Iterator(nullptr);
|
||||
r->leftChild->leftChild = splay(r->leftChild->leftChild, key);
|
||||
|
||||
r = rotateRight(r);
|
||||
}
|
||||
else
|
||||
else if (r->leftChild->pair.key < key)
|
||||
{
|
||||
Array<Node*> endTraversal;
|
||||
while(endNode != nullptr)
|
||||
r->leftChild->rightChild = splay(r->leftChild->rightChild, key);
|
||||
|
||||
if (r->leftChild->rightChild != nullptr)
|
||||
{
|
||||
endTraversal.add(endNode);
|
||||
endNode = endNode->rightChild;
|
||||
r->leftChild = rotateLeft(r->leftChild);
|
||||
}
|
||||
endIt = Iterator(endNode, std::move(endTraversal));
|
||||
}
|
||||
return (r->leftChild == nullptr) ? r : rotateRight(r);
|
||||
}
|
||||
Node* root;
|
||||
Iterator beginIt;
|
||||
Iterator endIt;
|
||||
Node* rotateRight(Node* node)
|
||||
else
|
||||
{
|
||||
Node* y = node->leftChild;
|
||||
node->leftChild = y->rightChild;
|
||||
y->rightChild = node;
|
||||
return y;
|
||||
}
|
||||
Node* rotateLeft(Node* node)
|
||||
{
|
||||
Node* y = node->rightChild;
|
||||
node->rightChild = y->leftChild;
|
||||
y->leftChild = node;
|
||||
return y;
|
||||
}
|
||||
Node* makeNode(const K& key)
|
||||
{
|
||||
return new Node(key);
|
||||
}
|
||||
Node* insert(Node* root, const K& key)
|
||||
{
|
||||
if (root == nullptr) return makeNode(key);
|
||||
if (r->rightChild == nullptr)
|
||||
return r;
|
||||
|
||||
root = splay(root, key);
|
||||
|
||||
if (!(root->pair.key < key || key < root->pair.key)) return root;
|
||||
|
||||
Node* newNode = makeNode(key);
|
||||
|
||||
if (key < root->pair.key)
|
||||
if (key < r->rightChild->pair.key)
|
||||
{
|
||||
newNode->rightChild = root;
|
||||
newNode->leftChild = root->leftChild;
|
||||
root->leftChild = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
newNode->leftChild = root;
|
||||
newNode->rightChild = root->rightChild;
|
||||
root->rightChild = nullptr;
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
Node* remove(Node* root, const K& key)
|
||||
{
|
||||
Node* temp;
|
||||
if (!root)
|
||||
return nullptr;
|
||||
r->rightChild->leftChild = splay(r->rightChild->leftChild, key);
|
||||
|
||||
root = splay(root, key);
|
||||
|
||||
if (root->pair.key < key || key < root->pair.key)
|
||||
return root;
|
||||
|
||||
if (!root->leftChild)
|
||||
{
|
||||
temp = root;
|
||||
root = root->rightChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = root;
|
||||
|
||||
root = splay(root->leftChild, key);
|
||||
root->rightChild = temp->rightChild;
|
||||
}
|
||||
temp->leftChild = nullptr;
|
||||
temp->rightChild = nullptr;
|
||||
delete temp;
|
||||
return root;
|
||||
}
|
||||
Node* splay(Node* root, const K& key)
|
||||
{
|
||||
if (root == nullptr || !(root->pair.key < key || key < root->pair.key))
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
if (key < root->pair.key)
|
||||
{
|
||||
if (root->leftChild == nullptr)
|
||||
return root;
|
||||
|
||||
if (key < root->leftChild->pair.key)
|
||||
if (r->rightChild->leftChild != nullptr)
|
||||
{
|
||||
root->leftChild->leftChild = splay(root->leftChild->leftChild, key);
|
||||
|
||||
root = rotateRight(root);
|
||||
r->rightChild = rotateRight(r->rightChild);
|
||||
}
|
||||
else if (root->leftChild->pair.key < key)
|
||||
{
|
||||
root->leftChild->rightChild = splay(root->leftChild->rightChild, key);
|
||||
|
||||
if (root->leftChild->rightChild != nullptr)
|
||||
{
|
||||
root->leftChild = rotateLeft(root->leftChild);
|
||||
}
|
||||
}
|
||||
return (root->leftChild == nullptr) ? root : rotateRight(root);
|
||||
}
|
||||
else
|
||||
else if (r->rightChild->pair.key < key)
|
||||
{
|
||||
if (root->rightChild == nullptr)
|
||||
return root;
|
||||
|
||||
if (key < root->rightChild->pair.key)
|
||||
{
|
||||
root->rightChild->leftChild = splay(root->rightChild->leftChild, key);
|
||||
|
||||
if (root->rightChild->leftChild != nullptr)
|
||||
{
|
||||
root->rightChild = rotateRight(root->rightChild);
|
||||
}
|
||||
}
|
||||
else if (root->rightChild->pair.key < key)
|
||||
{
|
||||
root->rightChild->rightChild = splay(root->rightChild->rightChild, key);
|
||||
root = rotateLeft(root);
|
||||
}
|
||||
return (root->rightChild == nullptr) ? root : rotateLeft(root);
|
||||
r->rightChild->rightChild = splay(r->rightChild->rightChild, key);
|
||||
r = rotateLeft(r);
|
||||
}
|
||||
return (r->rightChild == nullptr) ? r : rotateLeft(r);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -14,8 +14,6 @@ target_sources(SeeleEngine
|
||||
SceneView.cpp
|
||||
WindowManager.h
|
||||
WindowManager.cpp
|
||||
Window.h
|
||||
Window.cpp
|
||||
GraphicsResources.h
|
||||
GraphicsResources.cpp
|
||||
GraphicsEnums.h)
|
||||
|
||||
@@ -9,5 +9,4 @@ Graphics::Graphics()
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -3,22 +3,32 @@
|
||||
#include "GraphicsResources.h"
|
||||
#include "Containers/Array.h"
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx
|
||||
{
|
||||
class Window;
|
||||
class Graphics
|
||||
{
|
||||
public:
|
||||
Graphics();
|
||||
~Graphics();
|
||||
virtual void init(GraphicsInitializer initializer) = 0;
|
||||
virtual void beginFrame(void* windowHandle) = 0;
|
||||
virtual void endFrame(void* windowHandle) = 0;
|
||||
virtual void* createWindow(const WindowCreateInfo& createInfo) = 0;
|
||||
protected:
|
||||
friend class Window;
|
||||
};
|
||||
DEFINE_REF(Graphics);
|
||||
}
|
||||
}
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class Graphics
|
||||
{
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
virtual void init(GraphicsInitializer initializer) = 0;
|
||||
virtual PWindow createWindow(const WindowCreateInfo &createInfo) = 0;
|
||||
virtual PViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0;
|
||||
|
||||
virtual PRenderPass createRenderPass(PRenderTargetLayout layout) = 0;
|
||||
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
||||
virtual void endRenderPass() = 0;
|
||||
|
||||
virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual PUniformBuffer createUniformBuffer(const BulkResourceData &bulkData) = 0;
|
||||
virtual PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) = 0;
|
||||
virtual PVertexBuffer createVertexBuffer(const BulkResourceData &bulkData) = 0;
|
||||
virtual PIndexBuffer createIndexBuffer(const BulkResourceData &bulkData) = 0;
|
||||
|
||||
protected:
|
||||
friend class Window;
|
||||
};
|
||||
DEFINE_REF(Graphics);
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
+1846
-1769
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
#include "GraphicsResources.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount)
|
||||
@@ -30,8 +31,8 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo
|
||||
}
|
||||
if (descriptorSetLayouts[setIndex] != nullptr)
|
||||
{
|
||||
auto& thisBindings = descriptorSetLayouts[setIndex]->descriptorBindings;
|
||||
auto& otherBindings = layout->descriptorBindings;
|
||||
auto &thisBindings = descriptorSetLayouts[setIndex]->descriptorBindings;
|
||||
auto &otherBindings = layout->descriptorBindings;
|
||||
thisBindings.resize(otherBindings.size());
|
||||
for (size_t i = 0; i < otherBindings.size(); ++i)
|
||||
{
|
||||
@@ -48,44 +49,57 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant)
|
||||
void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant)
|
||||
{
|
||||
pushConstants.add(pushConstant);
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
UniformBuffer::~UniformBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
RenderTargetLayout::RenderTargetLayout()
|
||||
: inputAttachments()
|
||||
, colorAttachments()
|
||||
, depthAttachment()
|
||||
: inputAttachments(), colorAttachments(), depthAttachment()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RenderTargetLayout::RenderTargetLayout(PTexture2D depthAttachment)
|
||||
: inputAttachments()
|
||||
, colorAttachments()
|
||||
, depthAttachment(depthAttachment)
|
||||
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments(), colorAttachments(), depthAttachment(depthAttachment)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RenderTargetLayout::RenderTargetLayout(PTexture2D colorAttachment, PTexture2D depthAttachment)
|
||||
: inputAttachments()
|
||||
, depthAttachment(depthAttachment)
|
||||
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments(), depthAttachment(depthAttachment)
|
||||
{
|
||||
colorAttachments.add(colorAttachment);
|
||||
}
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PTexture2D> colorAttachments, PTexture2D depthAttachmet)
|
||||
: inputAttachments()
|
||||
, colorAttachments(colorAttachments)
|
||||
, depthAttachment(depthAttachment)
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet)
|
||||
: inputAttachments(), colorAttachments(colorAttachments), depthAttachment(depthAttachment)
|
||||
{
|
||||
|
||||
}
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PTexture2D> inputAttachments, Array<PTexture2D> colorAttachments, PTexture2D depthAttachment)
|
||||
: inputAttachments(inputAttachments)
|
||||
, colorAttachments(colorAttachments)
|
||||
, depthAttachment(depthAttachment)
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments(inputAttachments), colorAttachments(colorAttachments), depthAttachment(depthAttachment)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Window::Window(const WindowCreateInfo &createInfo)
|
||||
: sizeX(createInfo.width), sizeY(createInfo.height), bFullscreen(createInfo.bFullscreen), title(createInfo.title), pixelFormat(createInfo.pixelFormat)
|
||||
{
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
}
|
||||
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo &viewportInfo)
|
||||
: sizeX(viewportInfo.sizeX), sizeY(viewportInfo.sizeY), offsetX(viewportInfo.offsetX), offsetY(viewportInfo.offsetY), owner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
Viewport::~Viewport()
|
||||
{
|
||||
}
|
||||
@@ -9,235 +9,366 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct GraphicsInitializer
|
||||
namespace Gfx
|
||||
{
|
||||
enum class QueueType
|
||||
{
|
||||
GRAPHICS = 1,
|
||||
COMPUTE = 2,
|
||||
TRANSFER = 3,
|
||||
DEDICATED_TRANSFER = 4
|
||||
};
|
||||
} // namespace Gfx
|
||||
struct GraphicsInitializer
|
||||
{
|
||||
const char *windowLayoutFile;
|
||||
const char *applicationName;
|
||||
const char *engineName;
|
||||
void *windowHandle;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char *> layers;
|
||||
Array<const char *> instanceExtensions;
|
||||
Array<const char *> deviceExtensions;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine"), engineName("SeeleEngine"), layers{"VK_LAYER_LUNARG_standard_validation"}, instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr)
|
||||
{
|
||||
const char* windowLayoutFile;
|
||||
const char* applicationName;
|
||||
const char* engineName;
|
||||
void* windowHandle;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char*> layers;
|
||||
Array<const char*> instanceExtensions;
|
||||
Array<const char*> deviceExtensions;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine")
|
||||
, engineName("SeeleEngine")
|
||||
, layers{ "VK_LAYER_LUNARG_standard_validation" }
|
||||
, instanceExtensions{}
|
||||
, deviceExtensions{ "VK_KHR_swapchain" }
|
||||
, windowHandle(nullptr)
|
||||
{}
|
||||
GraphicsInitializer(const GraphicsInitializer& other)
|
||||
: applicationName(other.applicationName)
|
||||
, engineName(other.engineName)
|
||||
, layers(other.layers)
|
||||
, instanceExtensions(other.instanceExtensions)
|
||||
, deviceExtensions(other.deviceExtensions)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct WindowCreateInfo
|
||||
{
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char* title;
|
||||
bool bFullscreen;
|
||||
};
|
||||
namespace Gfx
|
||||
{
|
||||
struct SePushConstantRange {
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
};
|
||||
class RenderCommandBase
|
||||
{
|
||||
|
||||
};
|
||||
DEFINE_REF(RenderCommandBase);
|
||||
|
||||
class SamplerState
|
||||
{
|
||||
public:
|
||||
virtual ~SamplerState()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
DEFINE_REF(SamplerState);
|
||||
class DescriptorBinding
|
||||
{
|
||||
public:
|
||||
DescriptorBinding()
|
||||
: binding(0)
|
||||
, descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM)
|
||||
, descriptorCount(-1)
|
||||
, shaderStages(SE_SHADER_STAGE_ALL)
|
||||
{}
|
||||
DescriptorBinding(const DescriptorBinding& other)
|
||||
: binding(other.binding)
|
||||
, descriptorType(other.descriptorType)
|
||||
, descriptorCount(other.descriptorCount)
|
||||
, shaderStages(other.shaderStages)
|
||||
{}
|
||||
void operator=(const DescriptorBinding& other)
|
||||
{
|
||||
binding = other.binding;
|
||||
descriptorType = other.descriptorType;
|
||||
descriptorCount = other.descriptorCount;
|
||||
shaderStages = other.shaderStages;
|
||||
}
|
||||
uint32_t binding;
|
||||
SeDescriptorType descriptorType;
|
||||
uint32_t descriptorCount;
|
||||
SeShaderStageFlags shaderStages;
|
||||
};
|
||||
DEFINE_REF(DescriptorBinding);
|
||||
|
||||
DECLARE_REF(DescriptorSet);
|
||||
class DescriptorAllocator
|
||||
{
|
||||
public:
|
||||
DescriptorAllocator() {}
|
||||
~DescriptorAllocator() {}
|
||||
virtual void allocateDescriptorSet(PDescriptorSet& descriptorSet) = 0;
|
||||
};
|
||||
DEFINE_REF(DescriptorAllocator);
|
||||
DECLARE_REF(UniformBuffer);
|
||||
DECLARE_REF(StructuredBuffer);
|
||||
DECLARE_REF(Texture);
|
||||
class DescriptorSet
|
||||
{
|
||||
public:
|
||||
virtual ~DescriptorSet() {}
|
||||
virtual void writeChanges() = 0;
|
||||
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
|
||||
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
|
||||
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
|
||||
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
|
||||
virtual bool operator<(PDescriptorSet other) = 0;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet);
|
||||
|
||||
class DescriptorLayout
|
||||
{
|
||||
public:
|
||||
DescriptorLayout() {}
|
||||
virtual ~DescriptorLayout() {}
|
||||
void operator=(const DescriptorLayout& other)
|
||||
{
|
||||
descriptorBindings.resize(other.descriptorBindings.size());
|
||||
std::memcpy(descriptorBindings.data(), other.descriptorBindings.data(), sizeof(DescriptorLayout) * descriptorBindings.size());
|
||||
}
|
||||
virtual void create() = 0;
|
||||
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
|
||||
virtual PDescriptorSet allocatedDescriptorSet();
|
||||
const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
|
||||
protected:
|
||||
Array<DescriptorBinding> descriptorBindings;
|
||||
PDescriptorAllocator allocator;
|
||||
friend class PipelineLayout;
|
||||
friend class DescriptorAllocator;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout);
|
||||
class PipelineLayout
|
||||
{
|
||||
public:
|
||||
PipelineLayout() {}
|
||||
virtual ~PipelineLayout() {}
|
||||
virtual void create() = 0;
|
||||
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
|
||||
void addPushConstants(const SePushConstantRange& pushConstants);
|
||||
virtual uint32 getHash() const = 0;
|
||||
protected:
|
||||
Array<PDescriptorLayout> descriptorSetLayouts;
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout);
|
||||
class VertexDeclaration
|
||||
{
|
||||
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration);
|
||||
class GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
virtual ~GraphicsPipeline()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline);
|
||||
class UniformBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~UniformBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
DEFINE_REF(UniformBuffer);
|
||||
class Viewport
|
||||
{
|
||||
|
||||
};
|
||||
DEFINE_REF(Viewport);
|
||||
class VertexBuffer
|
||||
{
|
||||
|
||||
};
|
||||
DEFINE_REF(VertexBuffer);
|
||||
class IndexBuffer
|
||||
{
|
||||
|
||||
};
|
||||
DEFINE_REF(IndexBuffer);
|
||||
class StructuredBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~StructuredBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
DEFINE_REF(StructuredBuffer);
|
||||
class Texture
|
||||
{
|
||||
|
||||
};
|
||||
DEFINE_REF(Texture);
|
||||
class Texture2D : public Texture
|
||||
{
|
||||
public:
|
||||
virtual ~Texture2D()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
DEFINE_REF(Texture2D);
|
||||
|
||||
class RenderTargetLayout
|
||||
{
|
||||
public:
|
||||
RenderTargetLayout();
|
||||
RenderTargetLayout(PTexture2D depthAttachment);
|
||||
RenderTargetLayout(PTexture2D colorAttachment, PTexture2D depthAttachment);
|
||||
RenderTargetLayout(Array<PTexture2D> colorAttachments, PTexture2D depthAttachmet);
|
||||
RenderTargetLayout(Array<PTexture2D> inputAttachments, Array<PTexture2D> colorAttachments, PTexture2D depthAttachment);
|
||||
Array<PTexture2D> inputAttachments;
|
||||
Array<PTexture2D> colorAttachments;
|
||||
PTexture2D depthAttachment;
|
||||
};
|
||||
DEFINE_REF(RenderTargetLayout);
|
||||
|
||||
class RenderPass
|
||||
{
|
||||
|
||||
};
|
||||
DEFINE_REF(RenderPass);
|
||||
}
|
||||
}
|
||||
GraphicsInitializer(const GraphicsInitializer &other)
|
||||
: applicationName(other.applicationName), engineName(other.engineName), layers(other.layers), instanceExtensions(other.instanceExtensions), deviceExtensions(other.deviceExtensions)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct WindowCreateInfo
|
||||
{
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char *title;
|
||||
bool bFullscreen;
|
||||
Gfx::SeFormat pixelFormat;
|
||||
void *windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo
|
||||
{
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
bool bFullscreen;
|
||||
bool bVsync;
|
||||
};
|
||||
struct TextureCreateInfo
|
||||
{
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 depth;
|
||||
bool bArray;
|
||||
uint32 arrayLayers;
|
||||
uint32 mipLevels;
|
||||
uint32 samples;
|
||||
Gfx::SeFormat format;
|
||||
Gfx::SeImageUsageFlagBits usage;
|
||||
Gfx::QueueType queueType;
|
||||
TextureCreateInfo()
|
||||
: width(1), height(1), depth(1), bArray(false), arrayLayers(1), mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
|
||||
{
|
||||
}
|
||||
};
|
||||
//doesnt own the data, only proxy it
|
||||
struct BulkResourceData
|
||||
{
|
||||
uint32 size;
|
||||
uint8 *data;
|
||||
Gfx::QueueType owner;
|
||||
};
|
||||
namespace Gfx
|
||||
{
|
||||
struct SePushConstantRange
|
||||
{
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
};
|
||||
class RenderCommandBase
|
||||
{
|
||||
public:
|
||||
virtual ~RenderCommandBase()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(RenderCommandBase);
|
||||
class SamplerState
|
||||
{
|
||||
public:
|
||||
virtual ~SamplerState()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(SamplerState);
|
||||
class DescriptorBinding
|
||||
{
|
||||
public:
|
||||
DescriptorBinding()
|
||||
: binding(0), descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM), descriptorCount(0x7fff), shaderStages(SE_SHADER_STAGE_ALL)
|
||||
{
|
||||
}
|
||||
DescriptorBinding(const DescriptorBinding &other)
|
||||
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
|
||||
{
|
||||
}
|
||||
void operator=(const DescriptorBinding &other)
|
||||
{
|
||||
binding = other.binding;
|
||||
descriptorType = other.descriptorType;
|
||||
descriptorCount = other.descriptorCount;
|
||||
shaderStages = other.shaderStages;
|
||||
}
|
||||
uint32_t binding;
|
||||
SeDescriptorType descriptorType;
|
||||
uint32_t descriptorCount;
|
||||
SeShaderStageFlags shaderStages;
|
||||
};
|
||||
DEFINE_REF(DescriptorBinding);
|
||||
|
||||
DECLARE_REF(DescriptorSet);
|
||||
class DescriptorAllocator
|
||||
{
|
||||
public:
|
||||
DescriptorAllocator() {}
|
||||
virtual ~DescriptorAllocator() {}
|
||||
virtual void allocateDescriptorSet(PDescriptorSet &descriptorSet) = 0;
|
||||
};
|
||||
DEFINE_REF(DescriptorAllocator);
|
||||
DECLARE_REF(UniformBuffer);
|
||||
DECLARE_REF(StructuredBuffer);
|
||||
DECLARE_REF(Texture);
|
||||
class DescriptorSet
|
||||
{
|
||||
public:
|
||||
virtual ~DescriptorSet() {}
|
||||
virtual void writeChanges() = 0;
|
||||
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
|
||||
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
|
||||
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
|
||||
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
|
||||
virtual bool operator<(PDescriptorSet other) = 0;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet);
|
||||
|
||||
class DescriptorLayout
|
||||
{
|
||||
public:
|
||||
DescriptorLayout() {}
|
||||
virtual ~DescriptorLayout() {}
|
||||
void operator=(const DescriptorLayout &other)
|
||||
{
|
||||
descriptorBindings.resize(other.descriptorBindings.size());
|
||||
std::memcpy(descriptorBindings.data(), other.descriptorBindings.data(), sizeof(DescriptorLayout) * descriptorBindings.size());
|
||||
}
|
||||
virtual void create() = 0;
|
||||
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
|
||||
virtual PDescriptorSet allocatedDescriptorSet();
|
||||
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
|
||||
|
||||
protected:
|
||||
Array<DescriptorBinding> descriptorBindings;
|
||||
PDescriptorAllocator allocator;
|
||||
friend class PipelineLayout;
|
||||
friend class DescriptorAllocator;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout);
|
||||
class PipelineLayout
|
||||
{
|
||||
public:
|
||||
PipelineLayout() {}
|
||||
virtual ~PipelineLayout() {}
|
||||
virtual void create() = 0;
|
||||
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
|
||||
void addPushConstants(const SePushConstantRange &pushConstants);
|
||||
virtual uint32 getHash() const = 0;
|
||||
|
||||
protected:
|
||||
Array<PDescriptorLayout> descriptorSetLayouts;
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout);
|
||||
class VertexDeclaration
|
||||
{
|
||||
public:
|
||||
virtual ~VertexDeclaration()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration);
|
||||
class GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
virtual ~GraphicsPipeline()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline);
|
||||
class UniformBuffer
|
||||
{
|
||||
public:
|
||||
UniformBuffer();
|
||||
virtual ~UniformBuffer();
|
||||
};
|
||||
DEFINE_REF(UniformBuffer);
|
||||
class VertexBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~VertexBuffer()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(VertexBuffer);
|
||||
class IndexBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~IndexBuffer()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(IndexBuffer);
|
||||
class StructuredBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~StructuredBuffer()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(StructuredBuffer);
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
virtual ~Texture()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(Texture);
|
||||
class Texture2D : public Texture
|
||||
{
|
||||
public:
|
||||
virtual ~Texture2D()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(Texture2D);
|
||||
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
Window(const WindowCreateInfo &createInfo);
|
||||
virtual ~Window();
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
virtual void onWindowCloseEvent() = 0;
|
||||
virtual PTexture2D getBackBuffer() = 0;
|
||||
|
||||
protected:
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
bool bFullscreen;
|
||||
const char *title;
|
||||
SeFormat pixelFormat;
|
||||
};
|
||||
DEFINE_REF(Window);
|
||||
|
||||
class Viewport
|
||||
{
|
||||
public:
|
||||
Viewport(PWindow owner, const ViewportCreateInfo &createInfo);
|
||||
virtual ~Viewport();
|
||||
|
||||
protected:
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
PWindow owner;
|
||||
};
|
||||
DEFINE_REF(Viewport);
|
||||
|
||||
class RenderTargetAttachment
|
||||
{
|
||||
public:
|
||||
RenderTargetAttachment(PTexture2D texture,
|
||||
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
|
||||
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
|
||||
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
|
||||
: texture(texture), loadOp(loadOp), storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp)
|
||||
{
|
||||
}
|
||||
virtual ~RenderTargetAttachment()
|
||||
{
|
||||
}
|
||||
virtual PTexture2D getTexture()
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
inline SeAttachmentLoadOp getLoadOp() const { return loadOp; }
|
||||
inline SeAttachmentStoreOp getStoreOp() const { return storeOp; }
|
||||
inline SeAttachmentLoadOp getStencilLoadOp() const { return stencilLoadOp; }
|
||||
inline SeAttachmentStoreOp getStencilStoreOp() const { return stencilStoreOp; }
|
||||
|
||||
protected:
|
||||
PTexture2D texture;
|
||||
SeAttachmentLoadOp loadOp;
|
||||
SeAttachmentStoreOp storeOp;
|
||||
SeAttachmentLoadOp stencilLoadOp;
|
||||
SeAttachmentStoreOp stencilStoreOp;
|
||||
};
|
||||
DEFINE_REF(RenderTargetAttachment);
|
||||
|
||||
class SwapchainAttachment : public RenderTargetAttachment
|
||||
{
|
||||
public:
|
||||
SwapchainAttachment(PWindow owner,
|
||||
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
|
||||
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
|
||||
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
|
||||
: RenderTargetAttachment(owner->getBackBuffer(), loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner)
|
||||
{
|
||||
}
|
||||
virtual PTexture2D getTexture() override
|
||||
{
|
||||
return owner->getBackBuffer();
|
||||
}
|
||||
|
||||
private:
|
||||
PWindow owner;
|
||||
};
|
||||
DEFINE_REF(SwapchainAttachment);
|
||||
|
||||
class RenderTargetLayout
|
||||
{
|
||||
public:
|
||||
RenderTargetLayout();
|
||||
RenderTargetLayout(PRenderTargetAttachment depthAttachment);
|
||||
RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment);
|
||||
RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet);
|
||||
RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment);
|
||||
Array<PRenderTargetAttachment> inputAttachments;
|
||||
Array<PRenderTargetAttachment> colorAttachments;
|
||||
PRenderTargetAttachment depthAttachment;
|
||||
};
|
||||
DEFINE_REF(RenderTargetLayout);
|
||||
|
||||
class RenderPass
|
||||
{
|
||||
public:
|
||||
virtual ~RenderPass()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(RenderPass);
|
||||
|
||||
DEFINE_REF(RenderPass);
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -21,7 +21,7 @@ void Seele::RenderCore::init()
|
||||
|
||||
void Seele::RenderCore::renderLoop()
|
||||
{
|
||||
while(windowManager->isActive())
|
||||
while (windowManager->isActive())
|
||||
{
|
||||
windowManager->beginFrame();
|
||||
windowManager->endFrame();
|
||||
|
||||
@@ -2,15 +2,16 @@
|
||||
#include "WindowManager.h"
|
||||
namespace Seele
|
||||
{
|
||||
class RenderCore
|
||||
{
|
||||
public:
|
||||
RenderCore();
|
||||
~RenderCore();
|
||||
void init();
|
||||
void renderLoop();
|
||||
void shutdown();
|
||||
private:
|
||||
PWindowManager windowManager;
|
||||
};
|
||||
}
|
||||
class RenderCore
|
||||
{
|
||||
public:
|
||||
RenderCore();
|
||||
~RenderCore();
|
||||
void init();
|
||||
void renderLoop();
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
PWindowManager windowManager;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -2,20 +2,21 @@
|
||||
#include "Graphics.h"
|
||||
namespace Seele
|
||||
{
|
||||
//A renderpath is a general Renderer for a view.
|
||||
class RenderPath
|
||||
{
|
||||
public:
|
||||
RenderPath(Gfx::PGraphics graphics);
|
||||
virtual ~RenderPath();
|
||||
virtual void applyArea(Rect area) = 0;
|
||||
virtual void init() = 0;
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
Rect area;
|
||||
};
|
||||
DEFINE_REF(RenderPath);
|
||||
}
|
||||
//A renderpath is a general Renderer for a view.
|
||||
class RenderPath
|
||||
{
|
||||
public:
|
||||
RenderPath(Gfx::PGraphics graphics);
|
||||
virtual ~RenderPath();
|
||||
virtual void applyArea(Rect area) = 0;
|
||||
virtual void init() = 0;
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
Rect area;
|
||||
};
|
||||
DEFINE_REF(RenderPath);
|
||||
} // namespace Seele
|
||||
@@ -9,8 +9,9 @@ Seele::SceneRenderPath::~SceneRenderPath()
|
||||
{
|
||||
}
|
||||
|
||||
void Seele::SceneRenderPath::applyArea(Rect area)
|
||||
void Seele::SceneRenderPath::applyArea(Rect newArea)
|
||||
{
|
||||
area = newArea;
|
||||
}
|
||||
|
||||
void Seele::SceneRenderPath::init()
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class SceneRenderPath : public RenderPath
|
||||
{
|
||||
public:
|
||||
SceneRenderPath(Gfx::PGraphics graphics);
|
||||
virtual ~SceneRenderPath();
|
||||
virtual void applyArea(Rect area) override;
|
||||
virtual void init() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
};
|
||||
}
|
||||
class SceneRenderPath : public RenderPath
|
||||
{
|
||||
public:
|
||||
SceneRenderPath(Gfx::PGraphics graphics);
|
||||
virtual ~SceneRenderPath();
|
||||
virtual void applyArea(Rect area) override;
|
||||
virtual void init() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -2,10 +2,10 @@
|
||||
#include "View.h"
|
||||
namespace Seele
|
||||
{
|
||||
class SceneView : public View
|
||||
{
|
||||
public:
|
||||
SceneView(Gfx::PGraphics graphics);
|
||||
~SceneView();
|
||||
};
|
||||
}
|
||||
class SceneView : public View
|
||||
{
|
||||
public:
|
||||
SceneView(Gfx::PGraphics graphics);
|
||||
~SceneView();
|
||||
};
|
||||
} // namespace Seele
|
||||
+16
-15
@@ -2,19 +2,20 @@
|
||||
#include "RenderPath.h"
|
||||
namespace Seele
|
||||
{
|
||||
// A view is a part of the window, which can be anything from a viewport to an editor
|
||||
class View
|
||||
{
|
||||
public:
|
||||
View(Gfx::PGraphics graphics);
|
||||
virtual ~View();
|
||||
void beginFrame();
|
||||
void endFrame();
|
||||
void applyArea(Rect area);
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
PRenderPath renderer;
|
||||
};
|
||||
// A view is a part of the window, which can be anything from a viewport to an editor
|
||||
class View
|
||||
{
|
||||
public:
|
||||
View(Gfx::PGraphics graphics);
|
||||
virtual ~View();
|
||||
void beginFrame();
|
||||
void endFrame();
|
||||
void applyArea(Rect area);
|
||||
|
||||
DEFINE_REF(View)
|
||||
}
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
PRenderPath renderer;
|
||||
};
|
||||
|
||||
DEFINE_REF(View)
|
||||
} // namespace Seele
|
||||
@@ -20,4 +20,5 @@ target_sources(SeeleEngine
|
||||
VulkanRenderPass.cpp
|
||||
VulkanTexture.cpp
|
||||
VulkanQueue.h
|
||||
VulkanQueue.cpp)
|
||||
VulkanQueue.cpp
|
||||
VulkanViewport.cpp)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
SubAllocation::SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 size, uint32 alignedOffset, uint32 allocatedSize)
|
||||
SubAllocation::SubAllocation(Allocation* owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
|
||||
: owner(owner)
|
||||
, size(size)
|
||||
, allocatedOffset(allocatedOffset)
|
||||
@@ -14,11 +14,43 @@ SubAllocation::SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 s
|
||||
{
|
||||
}
|
||||
|
||||
Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated)
|
||||
SubAllocation::~SubAllocation()
|
||||
{
|
||||
owner->markFree(this);
|
||||
}
|
||||
|
||||
VkDeviceMemory SubAllocation::getHandle() const
|
||||
{
|
||||
return owner->getHandle();
|
||||
}
|
||||
|
||||
bool SubAllocation::isReadable() const
|
||||
{
|
||||
return owner->isReadable();
|
||||
}
|
||||
|
||||
void* SubAllocation::getMappedPointer()
|
||||
{
|
||||
return (uint8*)owner->getMappedPointer() + alignedOffset;
|
||||
}
|
||||
|
||||
void SubAllocation::flushMemory()
|
||||
{
|
||||
owner->flushMemory();
|
||||
}
|
||||
|
||||
void SubAllocation::invalidateMemory()
|
||||
{
|
||||
owner->invalidateMemory();
|
||||
}
|
||||
|
||||
Allocation::Allocation(PGraphics graphics, Allocator* allocator, VkDeviceSize size, uint8 memoryTypeIndex,
|
||||
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo* dedicatedInfo)
|
||||
: device(graphics->getDevice())
|
||||
, allocator(allocator)
|
||||
, bytesAllocated(0)
|
||||
, bytesUsed(0)
|
||||
, readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||
, properties(properties)
|
||||
, memoryTypeIndex(memoryTypeIndex)
|
||||
{
|
||||
@@ -26,38 +58,52 @@ Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, ui
|
||||
init::MemoryAllocateInfo();
|
||||
allocInfo.allocationSize = size;
|
||||
allocInfo.memoryTypeIndex = memoryTypeIndex;
|
||||
isDedicated = dedicatedInfo != nullptr;
|
||||
allocInfo.pNext = dedicatedInfo;
|
||||
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
|
||||
bytesAllocated = size;
|
||||
PSubAllocation freeRange = new SubAllocation(this, 0, size, 0, size);
|
||||
freeRanges.add(freeRange);
|
||||
freeRanges[0] = freeRange;
|
||||
|
||||
canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||
isMapped = false;
|
||||
}
|
||||
|
||||
PSubAllocation Allocation::getSuballocation(uint32 requestedSize, uint32 alignment)
|
||||
Allocation::~Allocation()
|
||||
{
|
||||
allocator->free(this);
|
||||
}
|
||||
|
||||
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
|
||||
{
|
||||
if (isDedicated)
|
||||
{
|
||||
if (activeAllocations.size() == 0)
|
||||
if (activeAllocations.empty())
|
||||
{
|
||||
assert(requestedSize == bytesAllocated);
|
||||
activeAllocations.add(freeRanges.back());
|
||||
PSubAllocation suballoc = freeRanges[0];
|
||||
activeAllocations[0] = suballoc.getHandle();
|
||||
freeRanges.clear();
|
||||
bytesUsed += requestedSize;
|
||||
return suballoc;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < freeRanges.size(); ++i)
|
||||
for (uint32 i = 0; i < freeRanges.size(); ++i)
|
||||
{
|
||||
PSubAllocation freeAllocation = freeRanges[i];
|
||||
uint32 allocatedOffset = freeAllocation->allocatedOffset;
|
||||
uint32 alignedOffset = align(allocatedOffset, alignment);
|
||||
uint32 alignmentAdjustment = alignedOffset - allocatedOffset;
|
||||
uint32 size = alignmentAdjustment + requestedSize;
|
||||
VkDeviceSize allocatedOffset = freeAllocation->allocatedOffset;
|
||||
VkDeviceSize alignedOffset = align(allocatedOffset, alignment);
|
||||
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
|
||||
VkDeviceSize size = alignmentAdjustment + requestedSize;
|
||||
if (freeAllocation->size == size)
|
||||
{
|
||||
freeRanges.remove(i);
|
||||
activeAllocations.add(freeAllocation);
|
||||
freeRanges.erase(allocatedOffset);
|
||||
activeAllocations[allocatedOffset] = freeAllocation.getHandle();
|
||||
bytesUsed += size;
|
||||
return freeAllocation;
|
||||
}
|
||||
else if (size < freeAllocation->allocatedSize)
|
||||
@@ -67,19 +113,61 @@ PSubAllocation Allocation::getSuballocation(uint32 requestedSize, uint32 alignme
|
||||
freeAllocation->allocatedOffset += allocatedOffset;
|
||||
freeAllocation->alignedOffset += allocatedOffset;
|
||||
PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size);
|
||||
activeAllocations.add(subAlloc);
|
||||
activeAllocations[allocatedOffset] = subAlloc.getHandle();
|
||||
freeRanges.erase(allocatedOffset);
|
||||
freeRanges[freeAllocation->allocatedOffset] = freeAllocation;
|
||||
bytesUsed += size;
|
||||
return subAlloc;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Allocation::markFree(SubAllocation* allocation)
|
||||
{
|
||||
VkDeviceSize lowerBound = allocation->allocatedOffset;
|
||||
VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
|
||||
PSubAllocation allocHandle;
|
||||
for(auto freeRange : freeRanges)
|
||||
{
|
||||
PSubAllocation freeAlloc = freeRange.value;
|
||||
if(freeAlloc->allocatedOffset + freeAlloc->allocatedSize + 1 == lowerBound)
|
||||
{
|
||||
freeAlloc->allocatedSize += allocation->allocatedSize;
|
||||
allocHandle = freeAlloc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto foundAlloc = freeRanges.find(upperBound + 1);
|
||||
if(foundAlloc != freeRanges.end())
|
||||
{
|
||||
if(allocHandle == nullptr)
|
||||
{
|
||||
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
}
|
||||
else
|
||||
{
|
||||
allocHandle = foundAlloc->value;
|
||||
allocHandle->allocatedOffset -= allocation->allocatedSize;
|
||||
allocHandle->alignedOffset -= allocation->allocatedSize;
|
||||
}
|
||||
}
|
||||
if(allocHandle == nullptr)
|
||||
{
|
||||
allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
|
||||
freeRanges[allocation->allocatedOffset] = allocHandle;
|
||||
}
|
||||
activeAllocations.erase(allocation->allocatedOffset);
|
||||
bytesUsed -= allocation->allocatedSize;
|
||||
}
|
||||
|
||||
Allocator::Allocator(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties);
|
||||
heaps.resize(memProperties.memoryHeapCount);
|
||||
for (size_t i = 0; i < memProperties.memoryHeapCount; i++)
|
||||
for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
|
||||
{
|
||||
VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
|
||||
HeapInfo& heapInfo = heaps[i];
|
||||
@@ -89,25 +177,68 @@ Allocator::Allocator(PGraphics graphics)
|
||||
|
||||
Allocator::~Allocator()
|
||||
{
|
||||
for(auto heap : heaps)
|
||||
{
|
||||
for(auto alloc : heap.allocations)
|
||||
{
|
||||
assert(alloc->activeAllocations.empty());
|
||||
assert(alloc->freeRanges.size() == 1);
|
||||
}
|
||||
heap.allocations.clear();
|
||||
}
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
PSubAllocation Allocator::allocate(uint64 size, const VkMemoryRequirements2& memRequirements2, VkMemoryPropertyFlags properties)
|
||||
PSubAllocation Allocator::allocate(const VkMemoryRequirements2& memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo* dedicatedInfo)
|
||||
{
|
||||
// no suitable allocations found, allocate new block
|
||||
const VkMemoryRequirements& requirements = memRequirements2.memoryRequirements;
|
||||
uint32 memoryTypeIndex;
|
||||
uint8 memoryTypeIndex;
|
||||
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
|
||||
|
||||
bool isDedicated = memRequirements2.pNext != nullptr;
|
||||
PAllocation newAllocation = new Allocation(graphics, this, MemoryBlockSize, memoryTypeIndex, properties, isDedicated);
|
||||
uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex;
|
||||
|
||||
if(memRequirements2.pNext != nullptr)
|
||||
{
|
||||
VkMemoryDedicatedRequirements* dedicatedReq = (VkMemoryDedicatedRequirements*)memRequirements2.pNext;
|
||||
if(dedicatedReq->prefersDedicatedAllocation)
|
||||
{
|
||||
PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
|
||||
heaps[heapIndex].allocations.add(newAllocation);
|
||||
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
}
|
||||
for(auto alloc : heaps[heapIndex].allocations)
|
||||
{
|
||||
PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
|
||||
if(suballoc != nullptr)
|
||||
{
|
||||
return suballoc;
|
||||
}
|
||||
}
|
||||
|
||||
// no suitable allocations found, allocate new block
|
||||
PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : MemoryBlockSize, memoryTypeIndex, properties, nullptr);
|
||||
heaps[heapIndex].allocations.add(newAllocation);
|
||||
return newAllocation->getSuballocation(size, requirements.alignment);
|
||||
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
|
||||
VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex)
|
||||
void Allocator::free(Allocation* allocation)
|
||||
{
|
||||
for (int memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex)
|
||||
for(auto heap : heaps)
|
||||
{
|
||||
for(uint32 i = 0; i < heap.allocations.size(); ++i)
|
||||
{
|
||||
if(heap.allocations[i] == allocation)
|
||||
{
|
||||
heap.allocations.remove(i, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8* typeIndex)
|
||||
{
|
||||
for (uint8 memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex)
|
||||
{
|
||||
if ((typeBits & 1) == 1)
|
||||
{
|
||||
@@ -121,4 +252,79 @@ VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags proper
|
||||
}
|
||||
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
StagingBuffer::StagingBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StagingBuffer::~StagingBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StagingManager::StagingManager(PGraphics graphics, PAllocator allocator)
|
||||
: graphics(graphics)
|
||||
, allocator(allocator)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StagingManager::~StagingManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StagingManager::clearPending()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
|
||||
{
|
||||
for(auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||
{
|
||||
auto freeBuffer = *it;
|
||||
if(freeBuffer->allocation->getSize() == size && freeBuffer->allocation->isReadable() == bCPURead)
|
||||
{
|
||||
activeBuffers.add(freeBuffer.getHandle());
|
||||
freeBuffers.remove(it, false);
|
||||
return freeBuffer;
|
||||
}
|
||||
}
|
||||
PStagingBuffer stagingBuffer = new StagingBuffer();
|
||||
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
|
||||
VkDevice vulkanDevice = graphics->getDevice();
|
||||
|
||||
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer));
|
||||
|
||||
VkMemoryDedicatedRequirements dedicatedReqs;
|
||||
dedicatedReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
||||
dedicatedReqs.pNext = nullptr;
|
||||
VkMemoryRequirements2 memReqs;
|
||||
memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
memReqs.pNext = &dedicatedReqs;
|
||||
VkBufferMemoryRequirementsInfo2 bufferQuery;
|
||||
bufferQuery.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
||||
bufferQuery.pNext = nullptr;
|
||||
bufferQuery.buffer = stagingBuffer->buffer;
|
||||
vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs);
|
||||
|
||||
memReqs.memoryRequirements.alignment =
|
||||
(16 > memReqs.memoryRequirements.alignment) ?
|
||||
16 : memReqs.memoryRequirements.alignment;
|
||||
|
||||
stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_CACHED_BIT : VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), stagingBuffer->buffer);
|
||||
stagingBuffer->bReadable = bCPURead;
|
||||
vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
|
||||
|
||||
activeBuffers.add(stagingBuffer.getHandle());
|
||||
return stagingBuffer;
|
||||
}
|
||||
|
||||
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
|
||||
{
|
||||
freeBuffers.add(buffer);
|
||||
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
|
||||
}
|
||||
@@ -6,69 +6,211 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(Graphics);
|
||||
class Allocation;
|
||||
class Allocator;
|
||||
class SubAllocation
|
||||
{
|
||||
public:
|
||||
SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize);
|
||||
~SubAllocation();
|
||||
VkDeviceMemory getHandle() const;
|
||||
inline VkDeviceSize getSize() const
|
||||
{
|
||||
DECLARE_REF(Graphics);
|
||||
class Allocation;
|
||||
class Allocator;
|
||||
class SubAllocation
|
||||
{
|
||||
public:
|
||||
SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 size, uint32 alignedOffset, uint32 allocatedSize);
|
||||
private:
|
||||
Allocation* owner;
|
||||
uint32 allocatedOffset;
|
||||
uint32 size;
|
||||
uint32 alignedOffset;
|
||||
uint32 allocatedSize;
|
||||
friend class Allocation;
|
||||
friend class Allocator;
|
||||
};
|
||||
DEFINE_REF(SubAllocation);
|
||||
class Allocation
|
||||
{
|
||||
public:
|
||||
Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated);
|
||||
PSubAllocation getSuballocation(uint32 size, uint32 alignment);
|
||||
private:
|
||||
Allocator* allocator;
|
||||
VkDevice device;
|
||||
VkDeviceMemory allocatedMemory;
|
||||
VkDeviceSize bytesAllocated;
|
||||
VkDeviceSize bytesUsed;
|
||||
VkMemoryPropertyFlags properties;
|
||||
Array<PSubAllocation> activeAllocations;
|
||||
Array<PSubAllocation> freeRanges;
|
||||
void* mappedPointer;
|
||||
uint8 isDedicated : 1;
|
||||
uint8 canMap : 1;
|
||||
uint8 memoryTypeIndex;
|
||||
friend class Allocator;
|
||||
};
|
||||
DEFINE_REF(Allocation);
|
||||
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
Allocator(PGraphics graphics);
|
||||
~Allocator();
|
||||
PSubAllocation allocate(uint64 size, const VkMemoryRequirements2& requirements, VkMemoryPropertyFlags props);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
MemoryBlockSize = 64 * 1024 * 1024 // 64MB
|
||||
};
|
||||
struct HeapInfo
|
||||
{
|
||||
uint32 maxSize = 0;
|
||||
Array<PAllocation> allocations;
|
||||
};
|
||||
Array<HeapInfo> heaps;
|
||||
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex);
|
||||
PGraphics graphics;
|
||||
VkPhysicalDeviceMemoryProperties memProperties;
|
||||
};
|
||||
DEFINE_REF(Allocator);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
inline VkDeviceSize getOffset() const
|
||||
{
|
||||
return alignedOffset;
|
||||
}
|
||||
inline bool isReadable() const;
|
||||
void *getMappedPointer();
|
||||
void flushMemory();
|
||||
void invalidateMemory();
|
||||
|
||||
private:
|
||||
Allocation *owner;
|
||||
VkDeviceSize allocatedOffset;
|
||||
VkDeviceSize size;
|
||||
VkDeviceSize alignedOffset;
|
||||
VkDeviceSize allocatedSize;
|
||||
friend class Allocation;
|
||||
friend class Allocator;
|
||||
};
|
||||
DEFINE_REF(SubAllocation);
|
||||
class Allocation
|
||||
{
|
||||
public:
|
||||
Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize size, uint8 memoryTypeIndex,
|
||||
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
|
||||
~Allocation();
|
||||
PSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
|
||||
void markFree(SubAllocation *alloc);
|
||||
inline VkDeviceMemory getHandle() const
|
||||
{
|
||||
return allocatedMemory;
|
||||
}
|
||||
inline void *getMappedPointer()
|
||||
{
|
||||
if (!canMap)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!isMapped)
|
||||
{
|
||||
vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer);
|
||||
isMapped = true;
|
||||
}
|
||||
return mappedPointer;
|
||||
}
|
||||
|
||||
inline bool isReadable() const
|
||||
{
|
||||
return readable;
|
||||
}
|
||||
|
||||
void flushMemory()
|
||||
{
|
||||
VkMappedMemoryRange range;
|
||||
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
range.pNext = 0;
|
||||
range.memory = allocatedMemory;
|
||||
range.size = bytesAllocated;
|
||||
range.offset = 0;
|
||||
vkFlushMappedMemoryRanges(device, 1, &range);
|
||||
}
|
||||
|
||||
void invalidateMemory()
|
||||
{
|
||||
VkMappedMemoryRange range;
|
||||
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
range.pNext = 0;
|
||||
range.memory = allocatedMemory;
|
||||
range.size = bytesAllocated;
|
||||
vkInvalidateMappedMemoryRanges(device, 1, &range);
|
||||
}
|
||||
|
||||
private:
|
||||
Allocator *allocator;
|
||||
VkDevice device;
|
||||
VkDeviceMemory allocatedMemory;
|
||||
VkDeviceSize bytesAllocated;
|
||||
VkDeviceSize bytesUsed;
|
||||
VkMemoryPropertyFlags properties;
|
||||
Map<VkDeviceSize, SubAllocation *> activeAllocations;
|
||||
Map<VkDeviceSize, PSubAllocation> freeRanges;
|
||||
void *mappedPointer;
|
||||
uint8 memoryTypeIndex;
|
||||
uint8 isDedicated : 1;
|
||||
uint8 canMap : 1;
|
||||
uint8 isMapped : 1;
|
||||
uint8 readable : 1;
|
||||
friend class Allocator;
|
||||
};
|
||||
DEFINE_REF(Allocation);
|
||||
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
Allocator(PGraphics graphics);
|
||||
~Allocator();
|
||||
PSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
|
||||
VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
|
||||
inline PSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
|
||||
VkBuffer buffer)
|
||||
{
|
||||
VkMemoryDedicatedAllocateInfo allocInfo;
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
|
||||
allocInfo.pNext = nullptr;
|
||||
allocInfo.buffer = buffer;
|
||||
allocInfo.image = VK_NULL_HANDLE;
|
||||
return allocate(requirements, props, &allocInfo);
|
||||
}
|
||||
inline PSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
|
||||
VkImage image)
|
||||
{
|
||||
VkMemoryDedicatedAllocateInfo allocInfo;
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
|
||||
allocInfo.pNext = nullptr;
|
||||
allocInfo.buffer = VK_NULL_HANDLE;
|
||||
allocInfo.image = image;
|
||||
return allocate(requirements, props, &allocInfo);
|
||||
}
|
||||
|
||||
void free(Allocation *allocation);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
MemoryBlockSize = 64 * 1024 * 1024 // 64MB
|
||||
};
|
||||
struct HeapInfo
|
||||
{
|
||||
VkDeviceSize maxSize = 0;
|
||||
Array<PAllocation> allocations;
|
||||
};
|
||||
Array<HeapInfo> heaps;
|
||||
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8 *typeIndex);
|
||||
PGraphics graphics;
|
||||
VkPhysicalDeviceMemoryProperties memProperties;
|
||||
};
|
||||
DEFINE_REF(Allocator);
|
||||
|
||||
class StagingBuffer
|
||||
{
|
||||
public:
|
||||
StagingBuffer();
|
||||
~StagingBuffer();
|
||||
void *getMappedPointer()
|
||||
{
|
||||
return allocation->getMappedPointer();
|
||||
}
|
||||
void flushMappedMemory()
|
||||
{
|
||||
allocation->flushMemory();
|
||||
}
|
||||
void invalidateMemory()
|
||||
{
|
||||
allocation->invalidateMemory();
|
||||
}
|
||||
VkBuffer getHandle() const
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
VkDeviceMemory getMemoryHandle() const
|
||||
{
|
||||
return allocation->getHandle();
|
||||
}
|
||||
VkDeviceSize getOffset() const
|
||||
{
|
||||
return allocation->getOffset();
|
||||
}
|
||||
|
||||
private:
|
||||
PSubAllocation allocation;
|
||||
VkBuffer buffer;
|
||||
uint8 bReadable;
|
||||
friend class StagingManager;
|
||||
};
|
||||
DEFINE_REF(StagingBuffer);
|
||||
|
||||
class StagingManager
|
||||
{
|
||||
public:
|
||||
StagingManager(PGraphics graphics, PAllocator allocator);
|
||||
~StagingManager();
|
||||
PStagingBuffer allocateStagingBuffer(uint32 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
|
||||
void releaseStagingBuffer(PStagingBuffer buffer);
|
||||
void clearPending();
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PAllocator allocator;
|
||||
Array<PStagingBuffer> freeBuffers;
|
||||
Array<StagingBuffer *> activeBuffers;
|
||||
};
|
||||
DEFINE_REF(StagingManager);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -1,28 +1,329 @@
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanAllocator.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, QueueType startQueueType)
|
||||
: graphics(graphics)
|
||||
, currentOwner(startQueueType)
|
||||
struct PendingBuffer
|
||||
{
|
||||
}
|
||||
PStagingBuffer stagingBuffer;
|
||||
Gfx::QueueType prevQueue;
|
||||
bool bWriteOnly;
|
||||
};
|
||||
|
||||
QueueOwnedResource::~QueueOwnedResource()
|
||||
{
|
||||
}
|
||||
static Map<Buffer *, PendingBuffer> pendingBuffers;
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType)
|
||||
: QueueOwnedResource(graphics, queueType)
|
||||
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
|
||||
: QueueOwnedResource(graphics, queueType), currentBuffer(0), size(size)
|
||||
{
|
||||
if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ||
|
||||
usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT ||
|
||||
usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ||
|
||||
usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
|
||||
{
|
||||
numBuffers = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBuffers = Gfx::numFramesBuffered;
|
||||
}
|
||||
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
VkBufferCreateInfo info =
|
||||
init::BufferCreateInfo(
|
||||
usage,
|
||||
size);
|
||||
VkBufferMemoryRequirementsInfo2 bufferReqInfo;
|
||||
bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
||||
bufferReqInfo.pNext = nullptr;
|
||||
VkMemoryDedicatedRequirements dedicatedRequirements;
|
||||
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
||||
dedicatedRequirements.pNext = nullptr;
|
||||
VkMemoryRequirements2 memRequirements;
|
||||
memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
memRequirements.pNext = &dedicatedRequirements;
|
||||
for (uint32 i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer);
|
||||
bufferReqInfo.buffer = buffers[i].buffer;
|
||||
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
|
||||
buffers[i].allocation = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
|
||||
vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset());
|
||||
}
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
for (uint32 i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
vkDestroyBuffer(graphics->getDevice(), buffers[i].buffer, nullptr);
|
||||
buffers[i].allocation = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::executeOwnershipBarrier(QueueType newOwner)
|
||||
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
VkBufferMemoryBarrier barrier =
|
||||
init::BufferMemoryBarrier();
|
||||
PCommandBufferManager sourceManager = getCommands();
|
||||
PCommandBufferManager dstManager = nullptr;
|
||||
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
||||
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
|
||||
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
|
||||
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
||||
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
{
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
else if (currentOwner == Gfx::QueueType::COMPUTE)
|
||||
{
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
}
|
||||
else if (currentOwner == Gfx::QueueType::GRAPHICS)
|
||||
{
|
||||
barrier.srcAccessMask = getSourceAccessMask();
|
||||
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
}
|
||||
if (newOwner == Gfx::QueueType::TRANSFER)
|
||||
{
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstManager = graphics->getTransferCommands();
|
||||
}
|
||||
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
{
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstManager = graphics->getDedicatedTransferCommands();
|
||||
}
|
||||
else if (newOwner == Gfx::QueueType::COMPUTE)
|
||||
{
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
dstManager = graphics->getComputeCommands();
|
||||
}
|
||||
else if (newOwner == Gfx::QueueType::GRAPHICS)
|
||||
{
|
||||
barrier.dstAccessMask = getDestAccessMask();
|
||||
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
dstManager = graphics->getGraphicsCommands();
|
||||
}
|
||||
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
|
||||
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
|
||||
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
||||
for (uint32_t i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
dynamicBarriers[i] = barrier;
|
||||
dynamicBarriers[i].buffer = buffers[i].buffer;
|
||||
dynamicBarriers[i].offset = 0;
|
||||
dynamicBarriers[i].size = buffers[i].allocation->getSize();
|
||||
}
|
||||
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||
sourceManager->submitCommands();
|
||||
cachedCmdBufferManager = dstManager;
|
||||
}
|
||||
|
||||
void *Buffer::lock(bool bWriteOnly)
|
||||
{
|
||||
void *data = nullptr;
|
||||
|
||||
/*if (bVolatile)
|
||||
{
|
||||
if (lockMode == RLM_ReadOnly)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new std::logic_error("TODO implement volatile buffers");
|
||||
//device->getRHIDevice()->getTemp
|
||||
}
|
||||
}*/
|
||||
//assert(bStatic || bDynamic || bUAV);
|
||||
|
||||
PendingBuffer pending;
|
||||
pending.bWriteOnly = bWriteOnly;
|
||||
pending.prevQueue = currentOwner;
|
||||
if (bWriteOnly)
|
||||
{
|
||||
transferOwnership(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
data = stagingBuffer->getMappedPointer();
|
||||
pending.stagingBuffer = stagingBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
PCmdBuffer current = getCommands()->getCommands();
|
||||
getCommands()->submitCommands();
|
||||
getCommands()->waitForCommands(current);
|
||||
|
||||
transferOwnership(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
VkCommandBuffer handle = getCommands()->getCommands()->getHandle();
|
||||
|
||||
VkBufferMemoryBarrier barrier =
|
||||
init::BufferMemoryBarrier();
|
||||
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
barrier.buffer = buffers[currentBuffer].buffer;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.offset = 0;
|
||||
barrier.size = size;
|
||||
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
|
||||
|
||||
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||
|
||||
VkBufferCopy regions;
|
||||
regions.size = size;
|
||||
regions.srcOffset = 0;
|
||||
regions.dstOffset = 0;
|
||||
|
||||
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, ®ions);
|
||||
|
||||
getCommands()->submitCommands();
|
||||
vkQueueWaitIdle(getCommands()->getQueue()->getHandle());
|
||||
|
||||
stagingBuffer->flushMappedMemory();
|
||||
pending.stagingBuffer = stagingBuffer;
|
||||
|
||||
data = stagingBuffer->getMappedPointer();
|
||||
}
|
||||
pendingBuffers[this] = pending;
|
||||
|
||||
assert(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void Buffer::unlock()
|
||||
{
|
||||
auto found = pendingBuffers.find(this);
|
||||
if (found != pendingBuffers.end())
|
||||
{
|
||||
PendingBuffer pending = found->value;
|
||||
pending.stagingBuffer->flushMappedMemory();
|
||||
pendingBuffers.erase(this);
|
||||
if (pending.bWriteOnly)
|
||||
{
|
||||
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
||||
PCmdBuffer cmdBuffer = getCommands()->getCommands();
|
||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||
|
||||
VkBufferCopy region;
|
||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||
region.size = size;
|
||||
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||
|
||||
graphics->getStagingManager()->releaseStagingBuffer(stagingBuffer);
|
||||
}
|
||||
transferOwnership(pending.prevQueue);
|
||||
}
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
UniformBuffer::~UniformBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
VkAccessFlags UniformBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
|
||||
VkAccessFlags UniformBuffer::getDestAccessMask()
|
||||
{
|
||||
return VK_ACCESS_UNIFORM_READ_BIT;
|
||||
}
|
||||
|
||||
StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
StructuredBuffer::~StructuredBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
VkAccessFlags StructuredBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
|
||||
VkAccessFlags StructuredBuffer::getDestAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_READ_BIT;
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.owner)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
VkAccessFlags VertexBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
|
||||
VkAccessFlags VertexBuffer::getDestAccessMask()
|
||||
{
|
||||
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.owner)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
VkAccessFlags IndexBuffer::getSourceAccessMask()
|
||||
{
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
|
||||
VkAccessFlags IndexBuffer::getDestAccessMask()
|
||||
{
|
||||
return VK_ACCESS_INDEX_READ_BIT;
|
||||
}
|
||||
@@ -9,34 +9,34 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
CmdBufferBase::CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: graphics(graphics)
|
||||
, owner(cmdPool)
|
||||
: graphics(graphics), owner(cmdPool)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CmdBufferBase::~CmdBufferBase()
|
||||
{
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: CmdBufferBase(graphics, cmdPool)
|
||||
, renderPass(nullptr)
|
||||
, framebuffer(nullptr)
|
||||
, subpassIndex(0)
|
||||
: CmdBufferBase(graphics, cmdPool), renderPass(nullptr), framebuffer(nullptr), subpassIndex(0)
|
||||
{
|
||||
VkCommandBufferAllocateInfo allocInfo =
|
||||
init::CommandBufferAllocateInfo(cmdPool,
|
||||
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
1);
|
||||
|
||||
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
1);
|
||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle))
|
||||
|
||||
fence = new Fence(graphics);
|
||||
state = State::ReadyBegin;
|
||||
}
|
||||
|
||||
CmdBuffer::~CmdBuffer()
|
||||
{
|
||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||
renderPass = nullptr;
|
||||
framebuffer = nullptr;
|
||||
waitSemaphores.clear();
|
||||
}
|
||||
|
||||
void CmdBuffer::begin()
|
||||
@@ -54,8 +54,11 @@ void CmdBuffer::end()
|
||||
state = State::Ended;
|
||||
}
|
||||
|
||||
void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFramebuffer)
|
||||
{
|
||||
renderPass = newRenderPass;
|
||||
framebuffer = newFramebuffer;
|
||||
|
||||
VkRenderPassBeginInfo beginInfo =
|
||||
init::RenderPassBeginInfo();
|
||||
beginInfo.clearValueCount = renderPass->getClearValueCount();
|
||||
@@ -64,11 +67,49 @@ void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer
|
||||
beginInfo.renderPass = renderPass->getHandle();
|
||||
beginInfo.framebuffer = framebuffer->getHandle();
|
||||
vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents());
|
||||
state = State::RenderPassActive;
|
||||
}
|
||||
|
||||
void CmdBuffer::endRenderPass()
|
||||
{
|
||||
vkCmdEndRenderPass(handle);
|
||||
state = State::InsideBegin;
|
||||
|
||||
}
|
||||
|
||||
void CmdBuffer::executeCommands(Array<PSecondaryCmdBuffer> commands)
|
||||
{
|
||||
assert(state == State::RenderPassActive);
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
cmdBuffers[i] = commands[i]->getHandle();
|
||||
}
|
||||
vkCmdExecuteCommands(handle, cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
||||
{
|
||||
waitSemaphores.add(semaphore);
|
||||
waitFlags.add(flags);
|
||||
}
|
||||
|
||||
void CmdBuffer::refreshFence()
|
||||
{
|
||||
if (state == State::Submitted)
|
||||
{
|
||||
if (fence->isSignaled())
|
||||
{
|
||||
state = State::ReadyBegin;
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
|
||||
fence->reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!fence->isSignaled());
|
||||
}
|
||||
}
|
||||
|
||||
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
|
||||
@@ -76,8 +117,8 @@ SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool
|
||||
{
|
||||
VkCommandBufferAllocateInfo allocInfo =
|
||||
init::CommandBufferAllocateInfo(cmdPool,
|
||||
VK_COMMAND_BUFFER_LEVEL_SECONDARY,
|
||||
1);
|
||||
VK_COMMAND_BUFFER_LEVEL_SECONDARY,
|
||||
1);
|
||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
|
||||
}
|
||||
|
||||
@@ -105,8 +146,7 @@ void SecondaryCmdBuffer::end()
|
||||
}
|
||||
|
||||
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
: graphics(graphics)
|
||||
, queue(queue)
|
||||
: graphics(graphics), queue(queue)
|
||||
{
|
||||
VkCommandPoolCreateInfo info =
|
||||
init::CommandPoolCreateInfo();
|
||||
@@ -117,11 +157,14 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
|
||||
activeCmdBuffer = new CmdBuffer(graphics, commandPool);
|
||||
activeCmdBuffer->begin();
|
||||
allocatedBuffers.add(activeCmdBuffer);
|
||||
}
|
||||
|
||||
CommandBufferManager::~CommandBufferManager()
|
||||
{
|
||||
vkDestroyCommandPool(graphics->getDevice(), commandPool, nullptr);
|
||||
graphics = nullptr;
|
||||
queue = nullptr;
|
||||
}
|
||||
|
||||
PCmdBuffer CommandBufferManager::getCommands()
|
||||
@@ -136,16 +179,15 @@ PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer()
|
||||
|
||||
void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
{
|
||||
if(activeCmdBuffer->state == CmdBuffer::State::InsideBegin
|
||||
|| activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
|
||||
if (activeCmdBuffer->state == CmdBuffer::State::InsideBegin || activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
|
||||
{
|
||||
if(!activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
|
||||
if (activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
|
||||
{
|
||||
std::cout << "End of renderpass forced" << std::endl;
|
||||
activeCmdBuffer->endRenderPass();
|
||||
}
|
||||
activeCmdBuffer->end();
|
||||
if(signalSemaphore != nullptr)
|
||||
if (signalSemaphore != nullptr)
|
||||
{
|
||||
queue->submitCommandBuffer(activeCmdBuffer, signalSemaphore->getHandle());
|
||||
}
|
||||
@@ -154,11 +196,11 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
queue->submitCommandBuffer(activeCmdBuffer);
|
||||
}
|
||||
}
|
||||
for(int32_t i = 0; i < allocatedBuffers.size(); ++i)
|
||||
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
|
||||
{
|
||||
PCmdBuffer cmdBuffer = allocatedBuffers[i];
|
||||
cmdBuffer->refreshFences();
|
||||
if(cmdBuffer->state == CmdBuffer::State::ReadyBegin)
|
||||
cmdBuffer->refreshFence();
|
||||
if (cmdBuffer->state == CmdBuffer::State::ReadyBegin)
|
||||
{
|
||||
activeCmdBuffer = cmdBuffer;
|
||||
activeCmdBuffer->begin();
|
||||
@@ -173,3 +215,9 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
allocatedBuffers.add(activeCmdBuffer);
|
||||
activeCmdBuffer->begin();
|
||||
}
|
||||
|
||||
void CommandBufferManager::waitForCommands(PCmdBuffer cmdBuffer, uint32 timeout)
|
||||
{
|
||||
cmdBuffer->fence->wait(timeout);
|
||||
cmdBuffer->refreshFence();
|
||||
}
|
||||
@@ -4,88 +4,100 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(RenderPass);
|
||||
DECLARE_REF(Framebuffer);
|
||||
class CmdBufferBase : public Gfx::RenderCommandBase
|
||||
{
|
||||
public:
|
||||
CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~CmdBufferBase();
|
||||
inline VkCommandBuffer getHandle()
|
||||
{
|
||||
DECLARE_REF(RenderPass);
|
||||
DECLARE_REF(Framebuffer);
|
||||
class CmdBufferBase : public Gfx::RenderCommandBase
|
||||
{
|
||||
public:
|
||||
CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~CmdBufferBase();
|
||||
inline VkCommandBuffer getHandle()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
void reset();
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
};
|
||||
DEFINE_REF(CmdBufferBase);
|
||||
|
||||
DECLARE_REF(SecondaryCmdBuffer);
|
||||
class CmdBuffer : public CmdBufferBase
|
||||
{
|
||||
public:
|
||||
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~CmdBuffer();
|
||||
void begin();
|
||||
void end();
|
||||
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void endRenderPass();
|
||||
void executeCommands(Array<PSecondaryCmdBuffer> secondaryCommands);
|
||||
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
enum State
|
||||
{
|
||||
ReadyBegin,
|
||||
InsideBegin,
|
||||
RenderPassActive,
|
||||
Ended,
|
||||
Submitted,
|
||||
};
|
||||
|
||||
private:
|
||||
PRenderPass renderPass;
|
||||
PFramebuffer framebuffer;
|
||||
uint32 subpassIndex;
|
||||
State state;
|
||||
friend class SecondaryCmdBuffer;
|
||||
friend class CommandBufferManager;
|
||||
};
|
||||
DEFINE_REF(CmdBuffer);
|
||||
|
||||
class SecondaryCmdBuffer : public CmdBufferBase
|
||||
{
|
||||
public:
|
||||
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~SecondaryCmdBuffer();
|
||||
void begin(PCmdBuffer parent);
|
||||
void end();
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(SecondaryCmdBuffer);
|
||||
|
||||
class CommandBufferManager
|
||||
{
|
||||
public:
|
||||
CommandBufferManager(PGraphics graphics, PQueue queue);
|
||||
virtual ~CommandBufferManager();
|
||||
PCmdBuffer getCommands();
|
||||
PSecondaryCmdBuffer createSecondaryCmdBuffer();
|
||||
void submitCommands(PSemaphore signalSemaphore = nullptr);
|
||||
void waitForCommands(PCmdBuffer cmdBuffer, float timeToWait = 1.0f);
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkCommandPool commandPool;
|
||||
PQueue queue;
|
||||
uint32 queueFamilyIndex;
|
||||
PCmdBuffer activeCmdBuffer;
|
||||
Array<PCmdBuffer> allocatedBuffers;
|
||||
};
|
||||
DEFINE_REF(CommandBufferManager);
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
void reset();
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
};
|
||||
DEFINE_REF(CmdBufferBase);
|
||||
|
||||
DECLARE_REF(SecondaryCmdBuffer);
|
||||
class CmdBuffer : public CmdBufferBase
|
||||
{
|
||||
public:
|
||||
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~CmdBuffer();
|
||||
void begin();
|
||||
void end();
|
||||
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void endRenderPass();
|
||||
void executeCommands(Array<PSecondaryCmdBuffer> secondaryCommands);
|
||||
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void refreshFence();
|
||||
enum State
|
||||
{
|
||||
ReadyBegin,
|
||||
InsideBegin,
|
||||
RenderPassActive,
|
||||
Ended,
|
||||
Submitted,
|
||||
};
|
||||
|
||||
private:
|
||||
PRenderPass renderPass;
|
||||
PFramebuffer framebuffer;
|
||||
PFence fence;
|
||||
uint32 subpassIndex;
|
||||
State state;
|
||||
Array<PSemaphore> waitSemaphores;
|
||||
Array<VkPipelineStageFlags> waitFlags;
|
||||
friend class SecondaryCmdBuffer;
|
||||
friend class CommandBufferManager;
|
||||
friend class Queue;
|
||||
};
|
||||
DEFINE_REF(CmdBuffer);
|
||||
|
||||
class SecondaryCmdBuffer : public CmdBufferBase
|
||||
{
|
||||
public:
|
||||
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~SecondaryCmdBuffer();
|
||||
void begin(PCmdBuffer parent);
|
||||
void end();
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(SecondaryCmdBuffer);
|
||||
|
||||
class CommandBufferManager
|
||||
{
|
||||
public:
|
||||
CommandBufferManager(PGraphics graphics, PQueue queue);
|
||||
virtual ~CommandBufferManager();
|
||||
inline PQueue getQueue() const
|
||||
{
|
||||
return queue;
|
||||
}
|
||||
PCmdBuffer getCommands();
|
||||
PSecondaryCmdBuffer createSecondaryCmdBuffer();
|
||||
void submitCommands(PSemaphore signalSemaphore = nullptr);
|
||||
void waitForCommands(PCmdBuffer cmdBuffer, uint32 timeToWait = 1000000u);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkCommandPool commandPool;
|
||||
PQueue queue;
|
||||
uint32 queueFamilyIndex;
|
||||
PCmdBuffer activeCmdBuffer;
|
||||
Array<PCmdBuffer> allocatedBuffers;
|
||||
};
|
||||
DEFINE_REF(CommandBufferManager);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -23,8 +24,8 @@ void DescriptorLayout::create()
|
||||
bindings.resize(descriptorBindings.size());
|
||||
for (size_t i = 0; i < descriptorBindings.size(); ++i)
|
||||
{
|
||||
VkDescriptorSetLayoutBinding& binding = bindings[i];
|
||||
const Gfx::DescriptorBinding& rhiBinding = descriptorBindings[i];
|
||||
VkDescriptorSetLayoutBinding &binding = bindings[i];
|
||||
const Gfx::DescriptorBinding &rhiBinding = descriptorBindings[i];
|
||||
binding.binding = rhiBinding.binding;
|
||||
binding.descriptorCount = rhiBinding.descriptorCount;
|
||||
binding.descriptorType = cast(rhiBinding.descriptorType);
|
||||
@@ -78,8 +79,8 @@ DescriptorSet::~DescriptorSet()
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
|
||||
{
|
||||
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
|
||||
// bufferInfos.add(bufferInfo);
|
||||
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
|
||||
// bufferInfos.add(bufferInfo);
|
||||
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
@@ -88,8 +89,8 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
|
||||
{
|
||||
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
|
||||
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
|
||||
// bufferInfos.add(bufferInfo);
|
||||
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
|
||||
// bufferInfos.add(bufferInfo);
|
||||
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
@@ -111,23 +112,23 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerSt
|
||||
|
||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
|
||||
{
|
||||
// VulkanTextureBase* vulkanTexture = VulkanTextureBase::cast(texture);
|
||||
PTextureHandle vulkanTexture = TextureBase::cast(texture);
|
||||
//It is assumed that the image is in the correct layout
|
||||
// VkDescriptorImageInfo imageInfo =
|
||||
// init::DescriptorImageInfo(
|
||||
// VK_NULL_HANDLE,
|
||||
// vulkanTexture->defaultView.view,
|
||||
// graphics->getRHIDevice().findLayout(vulkanTexture->surface.image));
|
||||
VkDescriptorImageInfo imageInfo =
|
||||
init::DescriptorImageInfo(
|
||||
VK_NULL_HANDLE,
|
||||
vulkanTexture->getView(),
|
||||
vulkanTexture->getLayout());
|
||||
if (samplerState != nullptr)
|
||||
{
|
||||
// PVulkanSamplerState vulkanSampler = samplerState.cast<VulkanSamplerState>();
|
||||
// imageInfo.sampler = vulkanSampler->sampler;
|
||||
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
||||
imageInfo.sampler = vulkanSampler->sampler;
|
||||
}
|
||||
// imageInfos.add(imageInfo);
|
||||
imageInfos.add(imageInfo);
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, binding, &imageInfos.back());
|
||||
// if (vulkanTexture->surface.usageFlags & TexCreate_UAV)
|
||||
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
|
||||
{
|
||||
// writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
}
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
}
|
||||
@@ -149,20 +150,19 @@ void DescriptorSet::writeChanges()
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout)
|
||||
: layout(layout)
|
||||
, graphics(graphics)
|
||||
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout)
|
||||
: layout(layout), graphics(graphics)
|
||||
{
|
||||
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_END_RANGE];
|
||||
std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
|
||||
for (int i = 0; i < layout.getBindings().size(); ++i)
|
||||
for (uint32 i = 0; i < layout.getBindings().size(); ++i)
|
||||
{
|
||||
auto& binding = layout.getBindings()[i];
|
||||
auto &binding = layout.getBindings()[i];
|
||||
int typeIndex = binding.descriptorType;
|
||||
perTypeSizes[typeIndex] += 256;
|
||||
}
|
||||
Array<VkDescriptorPoolSize> poolSizes;
|
||||
for (int i = 0; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i)
|
||||
for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i)
|
||||
{
|
||||
if (perTypeSizes[i] > 0)
|
||||
{
|
||||
@@ -179,9 +179,10 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& l
|
||||
DescriptorAllocator::~DescriptorAllocator()
|
||||
{
|
||||
vkDestroyDescriptorPool(graphics->getDevice(), poolHandle, nullptr);
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet& descriptorSet)
|
||||
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet)
|
||||
{
|
||||
descriptorSet = new DescriptorSet(graphics, this);
|
||||
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
#include "VulkanGraphicsResources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(Graphics);
|
||||
class DescriptorLayout : public Gfx::DescriptorLayout
|
||||
{
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics)
|
||||
: graphics(graphics), layoutHandle(VK_NULL_HANDLE)
|
||||
{
|
||||
}
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create();
|
||||
inline VkDescriptorSetLayout getHandle() const
|
||||
{
|
||||
return layoutHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Array<VkDescriptorSetLayoutBinding> bindings;
|
||||
VkDescriptorSetLayout layoutHandle;
|
||||
friend class PipelineStateCacheManager;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout);
|
||||
class PipelineLayout : public Gfx::PipelineLayout
|
||||
{
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics)
|
||||
: graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE)
|
||||
{
|
||||
}
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create();
|
||||
inline VkPipelineLayout getHandle() const
|
||||
{
|
||||
return layoutHandle;
|
||||
}
|
||||
virtual uint32 getHash() const
|
||||
{
|
||||
return layoutHash;
|
||||
}
|
||||
|
||||
private:
|
||||
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
|
||||
uint32 layoutHash;
|
||||
VkPipelineLayout layoutHandle;
|
||||
PGraphics graphics;
|
||||
friend class PipelineStateCacheManager;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout);
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet
|
||||
{
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
|
||||
: graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE)
|
||||
{
|
||||
}
|
||||
virtual ~DescriptorSet();
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
|
||||
virtual bool operator<(Gfx::PDescriptorSet other);
|
||||
inline VkDescriptorSet getHandle() const
|
||||
{
|
||||
return setHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void writeChanges();
|
||||
Array<VkDescriptorImageInfo> imageInfos;
|
||||
Array<VkDescriptorBufferInfo> bufferInfos;
|
||||
Array<VkWriteDescriptorSet> writeDescriptors;
|
||||
VkDescriptorSet setHandle;
|
||||
PDescriptorAllocator owner;
|
||||
PGraphics graphics;
|
||||
friend class DescriptorAllocator;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet);
|
||||
|
||||
class DescriptorAllocator : public Gfx::DescriptorAllocator
|
||||
{
|
||||
public:
|
||||
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
|
||||
virtual ~DescriptorAllocator();
|
||||
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
|
||||
|
||||
inline VkDescriptorPool getHandle()
|
||||
{
|
||||
return poolHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
int maxSets = 512;
|
||||
VkDescriptorPool poolHandle;
|
||||
DescriptorLayout &layout;
|
||||
};
|
||||
DEFINE_REF(DescriptorAllocator);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -12,23 +12,27 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
|
||||
, layout(renderTargetLayout)
|
||||
, renderPass(renderPass)
|
||||
{
|
||||
FramebufferDescription description;
|
||||
std::memset(&description, 0, sizeof(FramebufferDescription));
|
||||
Array<VkImageView> attachments;
|
||||
for(auto inputAttachment : layout->inputAttachments)
|
||||
for (auto inputAttachment : layout->inputAttachments)
|
||||
{
|
||||
PTexture2D vkInputAttachment = inputAttachment.cast<Texture2D>();
|
||||
PTexture2D vkInputAttachment = inputAttachment->getTexture().cast<Texture2D>();
|
||||
attachments.add(vkInputAttachment->getView());
|
||||
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
|
||||
}
|
||||
for(auto colorAttachment : layout->colorAttachments)
|
||||
for (auto colorAttachment : layout->colorAttachments)
|
||||
{
|
||||
PTexture2D vkColorAttachment = colorAttachment.cast<Texture2D>();
|
||||
PTexture2D vkColorAttachment = colorAttachment->getTexture().cast<Texture2D>();
|
||||
attachments.add(vkColorAttachment->getView());
|
||||
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
|
||||
}
|
||||
if(layout->depthAttachment != nullptr)
|
||||
if (layout->depthAttachment != nullptr)
|
||||
{
|
||||
PTexture2D vkDepthAttachment = layout->depthAttachment.cast<Texture2D>();
|
||||
PTexture2D vkDepthAttachment = layout->depthAttachment->getTexture().cast<Texture2D>();
|
||||
attachments.add(vkDepthAttachment->getView());
|
||||
description.depthAttachment = vkDepthAttachment->getView();
|
||||
}
|
||||
|
||||
VkFramebufferCreateInfo createInfo =
|
||||
init::FramebufferCreateInfo(
|
||||
renderPass->getHandle(),
|
||||
@@ -36,9 +40,10 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
|
||||
attachments.data(),
|
||||
renderPass->getRenderArea().extent.width,
|
||||
renderPass->getRenderArea().extent.height,
|
||||
1
|
||||
);
|
||||
1);
|
||||
VK_CHECK(vkCreateFramebuffer(graphics->getDevice(), &createInfo, nullptr, &handle));
|
||||
|
||||
hash = memCrc32(&description, sizeof(FramebufferDescription));
|
||||
}
|
||||
|
||||
Framebuffer::~Framebuffer()
|
||||
|
||||
@@ -3,24 +3,37 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(RenderPass);
|
||||
struct FramebufferDescription
|
||||
{
|
||||
VkImageView inputAttachments[16];
|
||||
VkImageView colorAttachments[16];
|
||||
VkImageView depthAttachment;
|
||||
uint32 numInputAttachments;
|
||||
uint32 numColorAttachments;
|
||||
};
|
||||
class Framebuffer
|
||||
{
|
||||
public:
|
||||
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::PRenderTargetLayout renderTargetLayout);
|
||||
virtual ~Framebuffer();
|
||||
inline VkFramebuffer getHandle() const
|
||||
{
|
||||
DECLARE_REF(RenderPass);
|
||||
class Framebuffer
|
||||
{
|
||||
public:
|
||||
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::PRenderTargetLayout renderTargetLayout);
|
||||
virtual ~Framebuffer();
|
||||
inline VkFramebuffer getHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkFramebuffer handle;
|
||||
Gfx::PRenderTargetLayout layout;
|
||||
PRenderPass renderPass;
|
||||
};
|
||||
DEFINE_REF(Framebuffer);
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
inline uint32 getHash() const
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
private:
|
||||
uint32 hash;
|
||||
PGraphics graphics;
|
||||
VkFramebuffer handle;
|
||||
Gfx::PRenderTargetLayout layout;
|
||||
PRenderPass renderPass;
|
||||
};
|
||||
DEFINE_REF(Framebuffer);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -1,26 +1,33 @@
|
||||
#include "Containers/Array.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanQueue.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include <glfw/glfw3.h>
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Graphics::Graphics()
|
||||
: callback(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), instance(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE)
|
||||
{
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
}
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
allocator = nullptr;
|
||||
stagingManager = nullptr;
|
||||
graphicsCommands = nullptr;
|
||||
computeCommands = nullptr;
|
||||
transferCommands = nullptr;
|
||||
dedicatedTransferCommands = nullptr;
|
||||
viewports.clear();
|
||||
vkDestroyDevice(handle, nullptr);
|
||||
DestroyDebugReportCallbackEXT(instance, nullptr, callback);
|
||||
vkDestroyInstance(instance, nullptr);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
void Graphics::init(GraphicsInitializer initInfo)
|
||||
@@ -30,27 +37,86 @@ void Graphics::init(GraphicsInitializer initInfo)
|
||||
pickPhysicalDevice();
|
||||
createDevice(initInfo);
|
||||
allocator = new Allocator(this);
|
||||
stagingManager = new StagingManager(this, allocator);
|
||||
graphicsCommands = new CommandBufferManager(this, graphicsQueue);
|
||||
computeCommands = new CommandBufferManager(this, computeQueue);
|
||||
transferCommands = new CommandBufferManager(this, transferQueue);
|
||||
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
|
||||
}
|
||||
|
||||
void Graphics::beginFrame(void *windowHandle)
|
||||
Gfx::PWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||
{
|
||||
GLFWwindow *window = static_cast<GLFWwindow *>(windowHandle);
|
||||
glfwPollEvents();
|
||||
PWindow result = new Window(this, createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Graphics::endFrame(void *windowHandle)
|
||||
Gfx::PViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
|
||||
{
|
||||
GLFWwindow *window = static_cast<GLFWwindow *>(windowHandle);
|
||||
PViewport result = new Viewport(this, owner, viewportInfo);
|
||||
viewports.add(result);
|
||||
return result;
|
||||
}
|
||||
Gfx::PRenderPass Graphics::createRenderPass(Gfx::PRenderTargetLayout layout)
|
||||
{
|
||||
PRenderPass result = new RenderPass(this, layout);
|
||||
return result;
|
||||
}
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
||||
{
|
||||
PRenderPass rp = renderPass.cast<RenderPass>();
|
||||
uint32 framebufferHash = rp->getFramebufferHash();
|
||||
PFramebuffer framebuffer;
|
||||
auto found = allocatedFramebuffers.find(framebufferHash);
|
||||
if(found == allocatedFramebuffers.end())
|
||||
{
|
||||
framebuffer = new Framebuffer(this, rp, rp->getLayout());
|
||||
}
|
||||
else
|
||||
{
|
||||
framebuffer = found->value;
|
||||
}
|
||||
graphicsCommands->getCommands()->beginRenderPass(rp, framebuffer);
|
||||
}
|
||||
|
||||
void *Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||
void Graphics::endRenderPass()
|
||||
{
|
||||
GLFWwindow *window = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
|
||||
return window;
|
||||
graphicsCommands->getCommands()->endRenderPass();
|
||||
}
|
||||
|
||||
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
PTexture2D result = new Texture2D(this, createInfo.width, createInfo.height, createInfo.bArray,
|
||||
createInfo.bArray, createInfo.arrayLayers, createInfo.format,
|
||||
createInfo.samples, createInfo.usage, createInfo.queueType);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::PUniformBuffer Graphics::createUniformBuffer(const BulkResourceData &bulkData)
|
||||
{
|
||||
PUniformBuffer uniformBuffer = new UniformBuffer(this, bulkData);
|
||||
return uniformBuffer;
|
||||
}
|
||||
|
||||
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const BulkResourceData &bulkData)
|
||||
{
|
||||
PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData);
|
||||
return structuredBuffer;
|
||||
}
|
||||
Gfx::PVertexBuffer Graphics::createVertexBuffer(const BulkResourceData &bulkData)
|
||||
{
|
||||
PVertexBuffer vertexBuffer = new VertexBuffer(this, bulkData);
|
||||
return vertexBuffer;
|
||||
}
|
||||
|
||||
Gfx::PIndexBuffer Graphics::createIndexBuffer(const BulkResourceData &bulkData)
|
||||
{
|
||||
PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData);
|
||||
return indexBuffer;
|
||||
}
|
||||
|
||||
VkInstance Graphics::getInstance() const
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
VkDevice Graphics::getDevice() const
|
||||
@@ -84,6 +150,11 @@ PAllocator Graphics::getAllocator()
|
||||
return allocator;
|
||||
}
|
||||
|
||||
PStagingManager Graphics::getStagingManager()
|
||||
{
|
||||
return stagingManager;
|
||||
}
|
||||
|
||||
Array<const char *> Graphics::getRequiredExtensions()
|
||||
{
|
||||
Array<const char *> extensions;
|
||||
@@ -143,13 +214,13 @@ void Graphics::pickPhysicalDevice()
|
||||
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
|
||||
Array<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
|
||||
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
|
||||
VkPhysicalDevice bestDevice;
|
||||
VkPhysicalDevice bestDevice = VK_NULL_HANDLE;
|
||||
uint32 deviceRating = 0;
|
||||
for (auto physicalDevice : physicalDevices)
|
||||
for (auto dev : physicalDevices)
|
||||
{
|
||||
uint32 currentRating = 0;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
||||
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
|
||||
vkGetPhysicalDeviceProperties(dev, &props);
|
||||
vkGetPhysicalDeviceFeatures(dev, &features);
|
||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
{
|
||||
currentRating += 100;
|
||||
@@ -161,10 +232,12 @@ void Graphics::pickPhysicalDevice()
|
||||
if (currentRating > deviceRating)
|
||||
{
|
||||
deviceRating = currentRating;
|
||||
bestDevice = physicalDevice;
|
||||
bestDevice = dev;
|
||||
}
|
||||
}
|
||||
this->physicalDevice = bestDevice;
|
||||
physicalDevice = bestDevice;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
||||
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
|
||||
}
|
||||
|
||||
void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
@@ -180,11 +253,12 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
int32_t dedicatedTransferQueueFamilyIndex = -1;
|
||||
int32_t computeQueueFamilyIndex = -1;
|
||||
int32_t asyncComputeFamilyIndex = -1;
|
||||
for (int32_t familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
|
||||
uint32 numPriorities = 0;
|
||||
for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
|
||||
{
|
||||
uint32 numQueuesForFamily = 0;
|
||||
VkQueueFamilyProperties currProps = queueProperties[familyIndex];
|
||||
bool bSparse = currProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT;
|
||||
// bool bSparse = currProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT;
|
||||
currProps.queueFlags = currProps.queueFlags ^ VK_QUEUE_SPARSE_BINDING_BIT;
|
||||
if ((currProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
@@ -204,7 +278,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
{
|
||||
if (asyncComputeFamilyIndex == -1)
|
||||
{
|
||||
if (familyIndex == graphicsQueueFamilyIndex)
|
||||
if (familyIndex == (uint32)graphicsQueueFamilyIndex)
|
||||
{
|
||||
if (currProps.queueCount > 1)
|
||||
{
|
||||
@@ -232,13 +306,27 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
numQueuesForFamily++;
|
||||
}
|
||||
}
|
||||
if(numQueuesForFamily > 0)
|
||||
if (numQueuesForFamily > 0)
|
||||
{
|
||||
VkDeviceQueueCreateInfo info =
|
||||
init::DeviceQueueCreateInfo(familyIndex, numQueuesForFamily);
|
||||
numPriorities += numQueuesForFamily;
|
||||
queueInfos.add(info);
|
||||
}
|
||||
}
|
||||
Array<float> queuePriorities;
|
||||
queuePriorities.resize(numPriorities);
|
||||
float *currentPriority = queuePriorities.data();
|
||||
for (uint32 index = 0; index < queueInfos.size(); ++index)
|
||||
{
|
||||
VkDeviceQueueCreateInfo &currQueue = queueInfos[index];
|
||||
currQueue.pQueuePriorities = currentPriority;
|
||||
|
||||
for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex)
|
||||
{
|
||||
*currentPriority++ = 1.0f;
|
||||
}
|
||||
}
|
||||
VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo(
|
||||
queueInfos.data(),
|
||||
(uint32)queueInfos.size(),
|
||||
@@ -250,28 +338,32 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
|
||||
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
|
||||
|
||||
graphicsQueue = new Queue(this, QueueType::GRAPHICS, graphicsQueueFamilyIndex, 0);
|
||||
graphicsQueue = new Queue(this, Gfx::QueueType::GRAPHICS, graphicsQueueFamilyIndex, 0);
|
||||
if (Gfx::useAsyncCompute && asyncComputeFamilyIndex != -1)
|
||||
{
|
||||
if (asyncComputeFamilyIndex == graphicsQueueFamilyIndex)
|
||||
{
|
||||
// Same family as graphics, but different queue
|
||||
computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 1);
|
||||
computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeFamilyIndex, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Different family
|
||||
computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 0);
|
||||
computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeFamilyIndex, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
computeQueue = new Queue(this, QueueType::COMPUTE, computeQueueFamilyIndex, 0);
|
||||
computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, computeQueueFamilyIndex, 0);
|
||||
}
|
||||
transferQueue = new Queue(this, QueueType::TRANSFER, transferQueueFamilyIndex, 0);
|
||||
transferQueue = new Queue(this, Gfx::QueueType::TRANSFER, transferQueueFamilyIndex, 0);
|
||||
if (dedicatedTransferQueueFamilyIndex != -1)
|
||||
{
|
||||
dedicatedTransferQueue = new Queue(this, QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueFamilyIndex, 0);
|
||||
dedicatedTransferQueue = new Queue(this, Gfx::QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueFamilyIndex, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dedicatedTransferQueue = transferQueue;
|
||||
}
|
||||
queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex();
|
||||
queueMapping.computeFamily = computeQueue->getFamilyIndex();
|
||||
|
||||
@@ -1,62 +1,83 @@
|
||||
#pragma once
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(Allocator);
|
||||
DECLARE_REF(StagingManager);
|
||||
DECLARE_REF(CommandBufferManager);
|
||||
DECLARE_REF(Queue);
|
||||
DECLARE_REF(Framebuffer);
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
VkInstance getInstance() const;
|
||||
VkDevice getDevice() const;
|
||||
VkPhysicalDevice getPhysicalDevice() const;
|
||||
|
||||
PCommandBufferManager getGraphicsCommands();
|
||||
PCommandBufferManager getComputeCommands();
|
||||
PCommandBufferManager getTransferCommands();
|
||||
PCommandBufferManager getDedicatedTransferCommands();
|
||||
|
||||
const QueueFamilyMapping getFamilyMapping() const
|
||||
{
|
||||
DECLARE_REF(Allocator);
|
||||
DECLARE_REF(CommandBufferManager);
|
||||
DECLARE_REF(Queue);
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
VkDevice getDevice() const;
|
||||
VkPhysicalDevice getPhysicalDevice() const;
|
||||
|
||||
PCommandBufferManager getGraphicsCommands();
|
||||
PCommandBufferManager getComputeCommands();
|
||||
PCommandBufferManager getTransferCommands();
|
||||
PCommandBufferManager getDedicatedTransferCommands();
|
||||
|
||||
PAllocator getAllocator();
|
||||
|
||||
// Inherited via Graphics
|
||||
virtual void init(GraphicsInitializer initializer) override;
|
||||
virtual void beginFrame(void* windowHandle) override;
|
||||
virtual void endFrame(void* windowHandle) override;
|
||||
virtual void* createWindow(const WindowCreateInfo& createInfo) override;
|
||||
protected:
|
||||
Array<const char*> getRequiredExtensions();
|
||||
void initInstance(GraphicsInitializer initInfo);
|
||||
void setupDebugCallback();
|
||||
void pickPhysicalDevice();
|
||||
void createDevice(GraphicsInitializer initInfo);
|
||||
|
||||
VkDevice handle;
|
||||
VkPhysicalDevice physicalDevice;
|
||||
VkInstance instance;
|
||||
|
||||
PQueue graphicsQueue;
|
||||
PQueue computeQueue;
|
||||
PQueue transferQueue;
|
||||
PQueue dedicatedTransferQueue;
|
||||
QueueFamilyMapping queueMapping;
|
||||
PCommandBufferManager graphicsCommands;
|
||||
PCommandBufferManager computeCommands;
|
||||
PCommandBufferManager transferCommands;
|
||||
PCommandBufferManager dedicatedTransferCommands;
|
||||
VkPhysicalDeviceProperties props;
|
||||
VkPhysicalDeviceFeatures features;
|
||||
VkDebugReportCallbackEXT callback;
|
||||
Array<PViewport> viewports;
|
||||
PAllocator allocator;
|
||||
|
||||
friend class Window;
|
||||
};
|
||||
DEFINE_REF(Graphics);
|
||||
return queueMapping;
|
||||
}
|
||||
}
|
||||
|
||||
PAllocator getAllocator();
|
||||
PStagingManager getStagingManager();
|
||||
|
||||
// Inherited via Graphics
|
||||
virtual void init(GraphicsInitializer initializer) override;
|
||||
virtual Gfx::PWindow createWindow(const WindowCreateInfo &createInfo) override;
|
||||
virtual Gfx::PViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override;
|
||||
|
||||
virtual Gfx::PRenderPass createRenderPass(Gfx::PRenderTargetLayout layout) override;
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
|
||||
virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::PUniformBuffer createUniformBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PVertexBuffer createVertexBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PIndexBuffer createIndexBuffer(const BulkResourceData &bulkData) override;
|
||||
|
||||
protected:
|
||||
Array<const char *> getRequiredExtensions();
|
||||
void initInstance(GraphicsInitializer initInfo);
|
||||
void setupDebugCallback();
|
||||
void pickPhysicalDevice();
|
||||
void createDevice(GraphicsInitializer initInfo);
|
||||
|
||||
VkDevice handle;
|
||||
VkPhysicalDevice physicalDevice;
|
||||
VkInstance instance;
|
||||
|
||||
PQueue graphicsQueue;
|
||||
PQueue computeQueue;
|
||||
PQueue transferQueue;
|
||||
PQueue dedicatedTransferQueue;
|
||||
QueueFamilyMapping queueMapping;
|
||||
PCommandBufferManager graphicsCommands;
|
||||
PCommandBufferManager computeCommands;
|
||||
PCommandBufferManager transferCommands;
|
||||
PCommandBufferManager dedicatedTransferCommands;
|
||||
VkPhysicalDeviceProperties props;
|
||||
VkPhysicalDeviceFeatures features;
|
||||
VkDebugReportCallbackEXT callback;
|
||||
Array<PViewport> viewports;
|
||||
Map<uint32, PFramebuffer> allocatedFramebuffers;
|
||||
PAllocator allocator;
|
||||
PStagingManager stagingManager;
|
||||
|
||||
friend class Window;
|
||||
};
|
||||
DEFINE_REF(Graphics);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -3,7 +3,7 @@
|
||||
using namespace Seele::Vulkan;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descriptorType)
|
||||
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType &descriptorType)
|
||||
{
|
||||
switch (descriptorType)
|
||||
{
|
||||
@@ -41,7 +41,7 @@ VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descrip
|
||||
return VK_DESCRIPTOR_TYPE_MAX_ENUM;
|
||||
}
|
||||
|
||||
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descriptorType)
|
||||
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descriptorType)
|
||||
{
|
||||
switch (descriptorType)
|
||||
{
|
||||
@@ -80,7 +80,7 @@ Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descrip
|
||||
return SE_DESCRIPTOR_TYPE_MAX_ENUM;
|
||||
}
|
||||
|
||||
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits& stage)
|
||||
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits &stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
@@ -125,7 +125,7 @@ VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBit
|
||||
return VK_SHADER_STAGE_ALL;
|
||||
}
|
||||
|
||||
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits& stage)
|
||||
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits &stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
@@ -162,14 +162,14 @@ Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBit
|
||||
return SE_SHADER_STAGE_TASK_BIT_NV;
|
||||
case VK_SHADER_STAGE_MESH_BIT_NV:
|
||||
return SE_SHADER_STAGE_MESH_BIT_NV;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SE_SHADER_STAGE_ALL;
|
||||
}
|
||||
|
||||
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat& format)
|
||||
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
@@ -631,7 +631,7 @@ VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat& format)
|
||||
return VK_FORMAT_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat& format)
|
||||
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
@@ -1092,4 +1092,56 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat& format)
|
||||
default:
|
||||
return SE_FORMAT_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
|
||||
{
|
||||
switch (storeOp)
|
||||
{
|
||||
case SE_ATTACHMENT_STORE_OP_STORE:
|
||||
return VK_ATTACHMENT_STORE_OP_STORE;
|
||||
case SE_ATTACHMENT_STORE_OP_DONT_CARE:
|
||||
return VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
default:
|
||||
return VK_ATTACHMENT_STORE_OP_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp)
|
||||
{
|
||||
switch (storeOp)
|
||||
{
|
||||
case VK_ATTACHMENT_STORE_OP_STORE:
|
||||
return SE_ATTACHMENT_STORE_OP_STORE;
|
||||
case VK_ATTACHMENT_STORE_OP_DONT_CARE:
|
||||
return SE_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
default:
|
||||
return SE_ATTACHMENT_STORE_OP_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp)
|
||||
{
|
||||
switch (loadOp)
|
||||
{
|
||||
case SE_ATTACHMENT_LOAD_OP_LOAD:
|
||||
return VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
case SE_ATTACHMENT_LOAD_OP_CLEAR:
|
||||
return VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
case SE_ATTACHMENT_LOAD_OP_DONT_CARE:
|
||||
return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
default:
|
||||
return VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp)
|
||||
{
|
||||
switch (loadOp)
|
||||
{
|
||||
case VK_ATTACHMENT_LOAD_OP_LOAD:
|
||||
return SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
case VK_ATTACHMENT_LOAD_OP_CLEAR:
|
||||
return SE_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
|
||||
return SE_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
default:
|
||||
return SE_ATTACHMENT_LOAD_OP_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,25 +2,29 @@
|
||||
#include "Graphics/GraphicsEnums.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#define VK_CHECK(f) \
|
||||
{ \
|
||||
VkResult res = (f); \
|
||||
if (res != VK_SUCCESS) \
|
||||
{ \
|
||||
std::cout << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
|
||||
assert(res == VK_SUCCESS); \
|
||||
} \
|
||||
}
|
||||
#define VK_CHECK(f) \
|
||||
{ \
|
||||
VkResult res = (f); \
|
||||
if (res != VK_SUCCESS) \
|
||||
{ \
|
||||
std::cout << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
|
||||
assert(res == VK_SUCCESS); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType& descriptorType);
|
||||
Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType);
|
||||
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits& stage);
|
||||
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits& stage);
|
||||
VkFormat cast(const Gfx::SeFormat& format);
|
||||
Gfx::SeFormat cast(const VkFormat& format);
|
||||
}
|
||||
}
|
||||
namespace Vulkan
|
||||
{
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
||||
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
|
||||
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
||||
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
|
||||
VkFormat cast(const Gfx::SeFormat &format);
|
||||
Gfx::SeFormat cast(const VkFormat &format);
|
||||
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
|
||||
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
|
||||
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
|
||||
Gfx::SeAttachmentLoadOp cast(const VkAttachmentLoadOp &loadOp);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -2,10 +2,52 @@
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, Gfx::QueueType startQueueType)
|
||||
: graphics(graphics), currentOwner(startQueueType)
|
||||
{
|
||||
}
|
||||
|
||||
QueueOwnedResource::~QueueOwnedResource()
|
||||
{
|
||||
cachedCmdBufferManager = nullptr;
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
void QueueOwnedResource::transferOwnership(Gfx::QueueType newOwner)
|
||||
{
|
||||
if (graphics->getFamilyMapping().needsTransfer(currentOwner, newOwner))
|
||||
{
|
||||
executeOwnershipBarrier(newOwner);
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
}
|
||||
|
||||
PCommandBufferManager QueueOwnedResource::getCommands()
|
||||
{
|
||||
if (cachedCmdBufferManager != nullptr)
|
||||
{
|
||||
assert(cachedCmdBufferManager->getQueue()->getFamilyIndex() == graphics->getFamilyMapping().getQueueTypeFamilyIndex(currentOwner));
|
||||
return cachedCmdBufferManager;
|
||||
}
|
||||
switch (currentOwner)
|
||||
{
|
||||
case Gfx::QueueType::GRAPHICS:
|
||||
return graphics->getGraphicsCommands();
|
||||
case Gfx::QueueType::COMPUTE:
|
||||
return graphics->getComputeCommands();
|
||||
case Gfx::QueueType::TRANSFER:
|
||||
return graphics->getTransferCommands();
|
||||
case Gfx::QueueType::DEDICATED_TRANSFER:
|
||||
return graphics->getDedicatedTransferCommands();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Semaphore::Semaphore(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
@@ -16,5 +58,65 @@ Semaphore::Semaphore(PGraphics graphics)
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
graphics = nullptr;
|
||||
vkDestroySemaphore(graphics->getDevice(), handle, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
Fence::Fence(PGraphics graphics)
|
||||
: graphics(graphics), signaled(false)
|
||||
{
|
||||
VkFenceCreateInfo info =
|
||||
init::FenceCreateInfo(0);
|
||||
VK_CHECK(vkCreateFence(graphics->getDevice(), &info, nullptr, &fence));
|
||||
}
|
||||
|
||||
Fence::~Fence()
|
||||
{
|
||||
vkDestroyFence(graphics->getDevice(), fence, nullptr);
|
||||
}
|
||||
|
||||
bool Fence::isSignaled()
|
||||
{
|
||||
if (signaled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
VkResult res = vkGetFenceStatus(graphics->getDevice(), fence);
|
||||
switch (res)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
signaled = true;
|
||||
return true;
|
||||
case VK_NOT_READY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Fence::reset()
|
||||
{
|
||||
if (signaled)
|
||||
{
|
||||
vkResetFences(graphics->getDevice(), 1, &fence);
|
||||
signaled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Fence::wait(uint32 timeout)
|
||||
{
|
||||
VkFence fences[] = {fence};
|
||||
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout * 1000ull);
|
||||
switch (r)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
signaled = true;
|
||||
break;
|
||||
case VK_TIMEOUT:
|
||||
break;
|
||||
default:
|
||||
VK_CHECK(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Vulkan
|
||||
DECLARE_REF(DescriptorAllocator);
|
||||
DECLARE_REF(CommandBufferManager);
|
||||
DECLARE_REF(Graphics);
|
||||
DECLARE_REF(SubAllocation);
|
||||
class Semaphore
|
||||
{
|
||||
public:
|
||||
@@ -19,116 +20,32 @@ public:
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
private:
|
||||
VkSemaphore handle;
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(Semaphore);
|
||||
|
||||
class DescriptorLayout : public Gfx::DescriptorLayout
|
||||
class Fence
|
||||
{
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics)
|
||||
: graphics(graphics), layoutHandle(VK_NULL_HANDLE)
|
||||
Fence(PGraphics graphics);
|
||||
~Fence();
|
||||
bool isSignaled();
|
||||
void reset();
|
||||
inline VkFence getHandle() const
|
||||
{
|
||||
return fence;
|
||||
}
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create();
|
||||
inline VkDescriptorSetLayout getHandle() const
|
||||
{
|
||||
return layoutHandle;
|
||||
}
|
||||
void wait(uint32 timeout);
|
||||
|
||||
private:
|
||||
bool signaled;
|
||||
VkFence fence;
|
||||
PGraphics graphics;
|
||||
Array<VkDescriptorSetLayoutBinding> bindings;
|
||||
VkDescriptorSetLayout layoutHandle;
|
||||
friend class PipelineStateCacheManager;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout);
|
||||
class PipelineLayout : public Gfx::PipelineLayout
|
||||
{
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics)
|
||||
: graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE)
|
||||
{
|
||||
}
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create();
|
||||
inline VkPipelineLayout getHandle() const
|
||||
{
|
||||
return layoutHandle;
|
||||
}
|
||||
virtual uint32 getHash() const
|
||||
{
|
||||
return layoutHash;
|
||||
}
|
||||
|
||||
private:
|
||||
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
|
||||
uint32 layoutHash;
|
||||
VkPipelineLayout layoutHandle;
|
||||
PGraphics graphics;
|
||||
friend class PipelineStateCacheManager;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout);
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet
|
||||
{
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
|
||||
: graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE)
|
||||
{
|
||||
}
|
||||
virtual ~DescriptorSet();
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
|
||||
virtual bool operator<(Gfx::PDescriptorSet other);
|
||||
inline VkDescriptorSet getHandle() const
|
||||
{
|
||||
return setHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void writeChanges();
|
||||
Array<VkDescriptorImageInfo> imageInfos;
|
||||
Array<VkDescriptorBufferInfo> bufferInfos;
|
||||
Array<VkWriteDescriptorSet> writeDescriptors;
|
||||
VkDescriptorSet setHandle;
|
||||
PDescriptorAllocator owner;
|
||||
PGraphics graphics;
|
||||
friend class DescriptorAllocator;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet);
|
||||
|
||||
class DescriptorAllocator : public Gfx::DescriptorAllocator
|
||||
{
|
||||
public:
|
||||
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
|
||||
~DescriptorAllocator();
|
||||
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
|
||||
|
||||
inline VkDescriptorPool getHandle()
|
||||
{
|
||||
return poolHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
int maxSets = 512;
|
||||
VkDescriptorPool poolHandle;
|
||||
DescriptorLayout &layout;
|
||||
};
|
||||
DEFINE_REF(DescriptorAllocator);
|
||||
enum class QueueType
|
||||
{
|
||||
GRAPHICS = 1,
|
||||
COMPUTE = 2,
|
||||
TRANSFER = 3,
|
||||
DEDICATED_TRANSFER = 4
|
||||
};
|
||||
DEFINE_REF(Fence);
|
||||
|
||||
struct QueueFamilyMapping
|
||||
{
|
||||
@@ -136,23 +53,23 @@ struct QueueFamilyMapping
|
||||
uint32 computeFamily;
|
||||
uint32 transferFamily;
|
||||
uint32 dedicatedTransferFamily;
|
||||
uint32 getQueueTypeFamilyIndex(QueueType type)
|
||||
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case QueueType::GRAPHICS:
|
||||
case Gfx::QueueType::GRAPHICS:
|
||||
return graphicsFamily;
|
||||
case QueueType::COMPUTE:
|
||||
case Gfx::QueueType::COMPUTE:
|
||||
return computeFamily;
|
||||
case QueueType::TRANSFER:
|
||||
case Gfx::QueueType::TRANSFER:
|
||||
return transferFamily;
|
||||
case QueueType::DEDICATED_TRANSFER:
|
||||
case Gfx::QueueType::DEDICATED_TRANSFER:
|
||||
return dedicatedTransferFamily;
|
||||
default:
|
||||
return VK_QUEUE_FAMILY_IGNORED;
|
||||
}
|
||||
}
|
||||
bool needsTransfer(QueueType src, QueueType dst)
|
||||
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const
|
||||
{
|
||||
uint32 srcIndex = getQueueTypeFamilyIndex(src);
|
||||
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
|
||||
@@ -162,71 +79,179 @@ struct QueueFamilyMapping
|
||||
class QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
QueueOwnedResource(PGraphics graphics, QueueType startQueueType);
|
||||
~QueueOwnedResource();
|
||||
QueueOwnedResource(PGraphics graphics, Gfx::QueueType startQueueType);
|
||||
virtual ~QueueOwnedResource();
|
||||
PCommandBufferManager getCommands();
|
||||
//Preliminary checks to see if the barrier should be executed at all
|
||||
void transferOwnership(QueueType newOwner);
|
||||
void transferOwnership(Gfx::QueueType newOwner);
|
||||
|
||||
protected:
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
QueueType currentOwner;
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) = 0;
|
||||
Gfx::QueueType currentOwner;
|
||||
PGraphics graphics;
|
||||
CommandBufferManager *cachedCmdBufferManager;
|
||||
PCommandBufferManager cachedCmdBufferManager;
|
||||
};
|
||||
DEFINE_REF(QueueOwnedResource);
|
||||
|
||||
class Buffer : public QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType = QueueType::GRAPHICS);
|
||||
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
|
||||
virtual ~Buffer();
|
||||
VkBuffer getHandle() const
|
||||
{
|
||||
return buffers[currentBuffer].buffer;
|
||||
}
|
||||
void advanceBuffer()
|
||||
{
|
||||
currentBuffer = (currentBuffer + 1) % numBuffers;
|
||||
}
|
||||
void *lock(bool bWriteOnly = true);
|
||||
void unlock();
|
||||
|
||||
protected:
|
||||
struct BufferAllocation
|
||||
{
|
||||
VkBuffer buffer;
|
||||
PSubAllocation allocation;
|
||||
};
|
||||
BufferAllocation buffers[Gfx::numFramesBuffered];
|
||||
uint32 numBuffers;
|
||||
uint32 currentBuffer;
|
||||
uint32 size;
|
||||
|
||||
private:
|
||||
virtual VkAccessFlags getSourceAccessMask() = 0;
|
||||
virtual VkAccessFlags getDestAccessMask() = 0;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner);
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
};
|
||||
DEFINE_REF(Buffer);
|
||||
|
||||
class UniformBuffer : public Buffer, public Gfx::UniformBuffer
|
||||
{
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
virtual ~UniformBuffer();
|
||||
|
||||
protected:
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
virtual VkAccessFlags getDestAccessMask();
|
||||
};
|
||||
DEFINE_REF(UniformBuffer);
|
||||
|
||||
class StructuredBuffer : public Buffer, public Gfx::StructuredBuffer
|
||||
{
|
||||
public:
|
||||
StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
virtual ~StructuredBuffer();
|
||||
|
||||
protected:
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
virtual VkAccessFlags getDestAccessMask();
|
||||
};
|
||||
DEFINE_REF(StructuredBuffer);
|
||||
|
||||
class TextureBase
|
||||
class VertexBuffer : public Buffer, public Gfx::VertexBuffer
|
||||
{
|
||||
public:
|
||||
TextureBase(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
|
||||
uint32 samples, Gfx::SeImageUsageFlags usage);
|
||||
virtual ~TextureBase();
|
||||
VertexBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
protected:
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
virtual VkAccessFlags getDestAccessMask();
|
||||
};
|
||||
DEFINE_REF(VertexBuffer);
|
||||
|
||||
class IndexBuffer : public Buffer, public Gfx::IndexBuffer
|
||||
{
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
protected:
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
virtual VkAccessFlags getDestAccessMask();
|
||||
};
|
||||
DEFINE_REF(IndexBuffer);
|
||||
|
||||
class TextureHandle : public QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
TextureHandle(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
|
||||
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~TextureHandle();
|
||||
|
||||
inline VkImageView getView() const
|
||||
{
|
||||
return defaultView;
|
||||
}
|
||||
inline VkImageLayout getLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
inline VkImageAspectFlags getAspect() const
|
||||
{
|
||||
return aspect;
|
||||
}
|
||||
inline VkImageUsageFlags getUsage() const
|
||||
{
|
||||
return usage;
|
||||
}
|
||||
inline Gfx::SeFormat getFormat() const
|
||||
{
|
||||
return format;
|
||||
}
|
||||
inline bool isDepthStencil() const
|
||||
{
|
||||
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
}
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PSubAllocation allocation;
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 sizeZ;
|
||||
uint32 arrayCount;
|
||||
uint32 mipLevels;
|
||||
uint32 samples;
|
||||
Gfx::SeFormat format;
|
||||
Gfx::SeImageUsageFlags usage;
|
||||
VkImage image;
|
||||
VkImageView defaultView;
|
||||
VkImageAspectFlags aspect;
|
||||
VkImageLayout layout;
|
||||
friend class TextureBase;
|
||||
friend class Texture2D;
|
||||
};
|
||||
DEFINE_REF(TextureHandle);
|
||||
|
||||
DECLARE_REF(TextureBase);
|
||||
class TextureBase
|
||||
{
|
||||
public:
|
||||
static PTextureHandle cast(Gfx::PTexture texture)
|
||||
{
|
||||
PTextureBase base = texture.cast<TextureBase>();
|
||||
return base->textureHandle;
|
||||
}
|
||||
void changeLayout(VkImageLayout newLayout);
|
||||
|
||||
protected:
|
||||
PTextureHandle textureHandle;
|
||||
};
|
||||
DEFINE_REF(TextureBase);
|
||||
|
||||
class Texture2D : public Gfx::Texture2D
|
||||
class Texture2D : public TextureBase, public Gfx::Texture2D
|
||||
{
|
||||
public:
|
||||
Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevels,
|
||||
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage);
|
||||
Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
|
||||
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~Texture2D();
|
||||
inline uint32 getSizeX() const
|
||||
{
|
||||
@@ -248,8 +273,12 @@ public:
|
||||
{
|
||||
return textureHandle->defaultView;
|
||||
}
|
||||
inline bool isDepthStencil() const
|
||||
{
|
||||
return textureHandle->isDepthStencil();
|
||||
}
|
||||
|
||||
private:
|
||||
PTextureBase textureHandle;
|
||||
};
|
||||
DEFINE_REF(Texture2D);
|
||||
|
||||
@@ -260,16 +289,54 @@ public:
|
||||
};
|
||||
DEFINE_REF(SamplerState);
|
||||
|
||||
class Window : public Gfx::Window
|
||||
{
|
||||
public:
|
||||
Window(PGraphics graphics, const WindowCreateInfo &createInfo);
|
||||
virtual ~Window();
|
||||
virtual void beginFrame() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Gfx::PTexture2D getBackBuffer() override;
|
||||
virtual void onWindowCloseEvent() override;
|
||||
|
||||
protected:
|
||||
void advanceBackBuffer();
|
||||
void recreateSwapchain(const WindowCreateInfo &createInfo);
|
||||
void present();
|
||||
void destroySwapchain();
|
||||
void createSwapchain();
|
||||
void chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred);
|
||||
void choosePresentMode(const Array<VkPresentModeKHR> &modes);
|
||||
PTexture2D backBufferImages[Gfx::numFramesBuffered];
|
||||
PSemaphore renderFinished[Gfx::numFramesBuffered];
|
||||
PSemaphore imageAcquired[Gfx::numFramesBuffered];
|
||||
PSemaphore imageAcquiredSemaphore;
|
||||
|
||||
PGraphics graphics;
|
||||
VkFormat pixelFormat;
|
||||
VkPresentModeKHR presentMode;
|
||||
VkSwapchainKHR swapchain;
|
||||
VkSurfaceKHR surface;
|
||||
VkSurfaceFormatKHR surfaceFormat;
|
||||
void *windowHandle;
|
||||
int32 currentImageIndex;
|
||||
int32 acquiredImageIndex;
|
||||
int32 preAcquiredImageIndex;
|
||||
int32 semaphoreIndex;
|
||||
VkInstance instance;
|
||||
};
|
||||
DEFINE_REF(Window);
|
||||
|
||||
class Viewport : public Gfx::Viewport
|
||||
{
|
||||
public:
|
||||
Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
|
||||
virtual ~Viewport();
|
||||
|
||||
protected:
|
||||
private:
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
VkSwapchainKHR swapchain;
|
||||
void *windowHandle;
|
||||
PGraphics graphics;
|
||||
friend class Graphics;
|
||||
};
|
||||
DECLARE_REF(Viewport);
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
VkApplicationInfo init::ApplicationInfo(const char* appName, uint32_t appVersion, const char* engineName, uint32_t engineVersion, uint32_t apiVersion)
|
||||
VkApplicationInfo init::ApplicationInfo(const char *appName, uint32_t appVersion, const char *engineName, uint32_t engineVersion, uint32_t apiVersion)
|
||||
{
|
||||
VkApplicationInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
@@ -11,10 +11,11 @@ VkApplicationInfo init::ApplicationInfo(const char* appName, uint32_t appVersion
|
||||
info.applicationVersion = appVersion;
|
||||
info.pEngineName = engineName;
|
||||
info.engineVersion = engineVersion;
|
||||
info.apiVersion = apiVersion;
|
||||
return info;
|
||||
}
|
||||
|
||||
VkInstanceCreateInfo init::InstanceCreateInfo(VkApplicationInfo* appInfo, const Array<const char*>& extensions, const Array<const char*>& layers)
|
||||
VkInstanceCreateInfo init::InstanceCreateInfo(VkApplicationInfo *appInfo, const Array<const char *> &extensions, const Array<const char *> &layers)
|
||||
{
|
||||
VkInstanceCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
@@ -41,7 +42,7 @@ VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int qu
|
||||
return DeviceQueueCreateInfo(queueFamilyIndex, queueCount, &priority);
|
||||
}
|
||||
|
||||
VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount, float* queuePriority)
|
||||
VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount, float *queuePriority)
|
||||
{
|
||||
VkDeviceQueueCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
@@ -51,7 +52,7 @@ VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int qu
|
||||
return createInfo;
|
||||
}
|
||||
|
||||
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures* features)
|
||||
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo *queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures *features)
|
||||
{
|
||||
return DeviceCreateInfo(queueInfos, queueCount, features, nullptr, 0, nullptr, 0);
|
||||
}
|
||||
@@ -93,7 +94,7 @@ VkSwapchainCreateInfoKHR init::SwapchainCreateInfo(VkSurfaceKHR surface, uint32_
|
||||
return createInfo;
|
||||
}
|
||||
|
||||
VkFramebufferCreateInfo init::FramebufferCreateInfo(VkRenderPass renderPass, uint32_t attachmentCount, VkImageView* attachments, uint32_t width, uint32_t height, uint32_t layers)
|
||||
VkFramebufferCreateInfo init::FramebufferCreateInfo(VkRenderPass renderPass, uint32_t attachmentCount, VkImageView *attachments, uint32_t width, uint32_t height, uint32_t layers)
|
||||
{
|
||||
VkFramebufferCreateInfo frameBufferCreateInfo = {};
|
||||
frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
@@ -121,16 +122,26 @@ VkAttachmentDescription init::AttachmentDescription(VkFormat format, VkSampleCou
|
||||
return desc;
|
||||
}
|
||||
|
||||
VkSubpassDescription init::SubpassDescription(VkPipelineBindPoint bindPoint, uint32_t colorAttachmentCount, VkAttachmentReference* colorReference, uint32_t depthAttachmentCount, VkAttachmentReference* depthReference, uint32_t inputAttachmentCount, VkAttachmentReference* inputReference, uint32_t resolveAttachmentCount, VkAttachmentReference* resolveReference, uint32_t preserveAttachmentCount, VkAttachmentReference* preserveReference)
|
||||
VkSubpassDescription init::SubpassDescription(VkPipelineBindPoint bindPoint,
|
||||
uint32_t colorAttachmentCount, VkAttachmentReference *colorReference,
|
||||
VkAttachmentReference *depthReference,
|
||||
uint32_t inputAttachmentCount, VkAttachmentReference *inputReference,
|
||||
VkAttachmentReference *resolveReference, uint32_t preserveAttachmentCount, uint32_t *preserveReference)
|
||||
{
|
||||
VkSubpassDescription desc = {};
|
||||
desc.pipelineBindPoint = bindPoint;
|
||||
desc.colorAttachmentCount = colorAttachmentCount;
|
||||
desc.pColorAttachments = colorReference;
|
||||
desc.inputAttachmentCount = inputAttachmentCount;
|
||||
desc.pInputAttachments = inputReference;
|
||||
desc.pResolveAttachments = resolveReference;
|
||||
desc.preserveAttachmentCount = preserveAttachmentCount;
|
||||
desc.pPreserveAttachments = preserveReference;
|
||||
desc.pDepthStencilAttachment = depthReference;
|
||||
return desc;
|
||||
}
|
||||
|
||||
VkRenderPassCreateInfo init::RenderPassCreateInfo(uint32_t attachmentCount, const VkAttachmentDescription* attachments, uint32_t subpassCount, const VkSubpassDescription* subpasses, uint32_t dependencyCount, const VkSubpassDependency* subpassDependencies)
|
||||
VkRenderPassCreateInfo init::RenderPassCreateInfo(uint32_t attachmentCount, const VkAttachmentDescription *attachments, uint32_t subpassCount, const VkSubpassDescription *subpasses, uint32_t dependencyCount, const VkSubpassDependency *subpassDependencies)
|
||||
{
|
||||
VkRenderPassCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
@@ -143,7 +154,7 @@ VkRenderPassCreateInfo init::RenderPassCreateInfo(uint32_t attachmentCount, cons
|
||||
|
||||
return info;
|
||||
}
|
||||
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures* features, const char* const* deviceExtensions, uint32_t deviceExtensionCount, const char* const* layers, uint32_t layerCount)
|
||||
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo *queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures *features, const char *const *deviceExtensions, uint32_t deviceExtensionCount, const char *const *layers, uint32_t layerCount)
|
||||
{
|
||||
VkDeviceCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
@@ -160,6 +171,8 @@ VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, u
|
||||
createInfo.ppEnabledLayerNames = layers;
|
||||
#else
|
||||
createInfo.enabledLayerCount = 0;
|
||||
layerCount = 0;
|
||||
layers = nullptr;
|
||||
#endif // ENABLE_VALIDATION
|
||||
|
||||
return createInfo;
|
||||
@@ -230,33 +243,40 @@ VkImageMemoryBarrier init::ImageMemoryBarrier(VkImage image, VkImageLayout oldLa
|
||||
barrier.srcQueueFamilyIndex = srcQueue;
|
||||
barrier.dstQueueFamilyIndex = dstQueue;
|
||||
barrier.image = image;
|
||||
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||
{
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
}
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
|
||||
if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
|
||||
{
|
||||
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
}
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
|
||||
{
|
||||
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
}
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
{
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
}
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||
{
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
}
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
|
||||
{
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
}
|
||||
@@ -422,7 +442,7 @@ VkBufferCreateInfo init::BufferCreateInfo(
|
||||
|
||||
VkDescriptorPoolCreateInfo init::DescriptorPoolCreateInfo(
|
||||
uint32_t poolSizeCount,
|
||||
VkDescriptorPoolSize* pPoolSizes,
|
||||
VkDescriptorPoolSize *pPoolSizes,
|
||||
uint32_t maxSets)
|
||||
{
|
||||
VkDescriptorPoolCreateInfo descriptorPoolInfo = {};
|
||||
@@ -459,7 +479,7 @@ VkDescriptorSetLayoutBinding init::DescriptorSetLayoutBinding(
|
||||
}
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo init::DescriptorSetLayoutCreateInfo(
|
||||
const VkDescriptorSetLayoutBinding* pBindings,
|
||||
const VkDescriptorSetLayoutBinding *pBindings,
|
||||
uint32_t bindingCount)
|
||||
{
|
||||
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {};
|
||||
@@ -471,7 +491,7 @@ VkDescriptorSetLayoutCreateInfo init::DescriptorSetLayoutCreateInfo(
|
||||
}
|
||||
|
||||
VkPipelineLayoutCreateInfo init::PipelineLayoutCreateInfo(
|
||||
const VkDescriptorSetLayout* pSetLayouts,
|
||||
const VkDescriptorSetLayout *pSetLayouts,
|
||||
uint32_t setLayoutCount)
|
||||
{
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
|
||||
@@ -484,7 +504,7 @@ VkPipelineLayoutCreateInfo init::PipelineLayoutCreateInfo(
|
||||
|
||||
VkDescriptorSetAllocateInfo init::DescriptorSetAllocateInfo(
|
||||
VkDescriptorPool descriptorPool,
|
||||
const VkDescriptorSetLayout* pSetLayouts,
|
||||
const VkDescriptorSetLayout *pSetLayouts,
|
||||
uint32_t descriptorSetCount)
|
||||
{
|
||||
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {};
|
||||
@@ -522,7 +542,7 @@ VkWriteDescriptorSet init::WriteDescriptorSet(
|
||||
VkDescriptorSet dstSet,
|
||||
VkDescriptorType type,
|
||||
uint32_t binding,
|
||||
VkDescriptorBufferInfo* bufferInfo)
|
||||
VkDescriptorBufferInfo *bufferInfo)
|
||||
{
|
||||
VkWriteDescriptorSet writeDescriptorSet = {};
|
||||
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
@@ -540,7 +560,7 @@ VkWriteDescriptorSet init::WriteDescriptorSet(
|
||||
VkDescriptorSet dstSet,
|
||||
VkDescriptorType type,
|
||||
uint32_t binding,
|
||||
VkDescriptorImageInfo* bufferInfo)
|
||||
VkDescriptorImageInfo *bufferInfo)
|
||||
{
|
||||
VkWriteDescriptorSet writeDescriptorSet = {};
|
||||
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
@@ -630,7 +650,7 @@ VkPipelineColorBlendAttachmentState init::PipelineColorBlendAttachmentState(
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo init::PipelineColorBlendStateCreateInfo(
|
||||
uint32_t attachmentCount,
|
||||
const VkPipelineColorBlendAttachmentState* pAttachments)
|
||||
const VkPipelineColorBlendAttachmentState *pAttachments)
|
||||
{
|
||||
VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {};
|
||||
pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
@@ -674,17 +694,19 @@ VkPipelineMultisampleStateCreateInfo init::PipelineMultisampleStateCreateInfo(
|
||||
{
|
||||
VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {};
|
||||
pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
pipelineMultisampleStateCreateInfo.flags = flags;
|
||||
pipelineMultisampleStateCreateInfo.rasterizationSamples = rasterizationSamples;
|
||||
return pipelineMultisampleStateCreateInfo;
|
||||
}
|
||||
|
||||
VkPipelineDynamicStateCreateInfo init::PipelineDynamicStateCreateInfo(
|
||||
const VkDynamicState* pDynamicStates,
|
||||
const VkDynamicState *pDynamicStates,
|
||||
uint32_t dynamicStateCount,
|
||||
VkPipelineDynamicStateCreateFlags flags)
|
||||
{
|
||||
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {};
|
||||
pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
pipelineDynamicStateCreateInfo.flags = flags;
|
||||
pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates;
|
||||
pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount;
|
||||
return pipelineDynamicStateCreateInfo;
|
||||
@@ -733,7 +755,7 @@ VkPushConstantRange init::PushConstantRange(
|
||||
return pushConstantRange;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule module, const char* entryName)
|
||||
VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule module, const char *entryName)
|
||||
{
|
||||
VkPipelineShaderStageCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
@@ -743,25 +765,31 @@ VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStag
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userDataManager) {
|
||||
#pragma warning(disable : 4100)
|
||||
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userDataManager)
|
||||
{
|
||||
std::cerr << layerPrefix << ": " << msg << std::endl;
|
||||
return VK_FALSE;
|
||||
}
|
||||
VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
|
||||
#pragma warning(default : 4100)
|
||||
VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback)
|
||||
{
|
||||
auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
|
||||
if (func != nullptr) {
|
||||
if (func != nullptr)
|
||||
{
|
||||
return func(instance, pCreateInfo, pAllocator, pCallback);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback)
|
||||
void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback)
|
||||
{
|
||||
auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
|
||||
if (func != nullptr) {
|
||||
if (func != nullptr)
|
||||
{
|
||||
func(instance, pCallback, pAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,302 +4,299 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userData);
|
||||
namespace Vulkan
|
||||
{
|
||||
VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userData);
|
||||
|
||||
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);
|
||||
void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback);
|
||||
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback);
|
||||
void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback);
|
||||
|
||||
namespace init
|
||||
{
|
||||
VkApplicationInfo ApplicationInfo(
|
||||
const char* appName,
|
||||
uint32_t appVersion,
|
||||
const char* engineName,
|
||||
uint32_t engineVersion,
|
||||
uint32_t apiVersion);
|
||||
namespace init
|
||||
{
|
||||
VkApplicationInfo ApplicationInfo(
|
||||
const char *appName,
|
||||
uint32_t appVersion,
|
||||
const char *engineName,
|
||||
uint32_t engineVersion,
|
||||
uint32_t apiVersion);
|
||||
|
||||
VkInstanceCreateInfo InstanceCreateInfo(
|
||||
VkApplicationInfo* appInfo,
|
||||
const Array<const char*>& extensions,
|
||||
const Array<const char*>& layers);
|
||||
VkInstanceCreateInfo InstanceCreateInfo(
|
||||
VkApplicationInfo *appInfo,
|
||||
const Array<const char *> &extensions,
|
||||
const Array<const char *> &layers);
|
||||
|
||||
VkDebugReportCallbackCreateInfoEXT DebugReportCallbackCreateInfo(
|
||||
VkDebugReportFlagsEXT flags);
|
||||
VkDebugReportCallbackCreateInfoEXT DebugReportCallbackCreateInfo(
|
||||
VkDebugReportFlagsEXT flags);
|
||||
|
||||
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
|
||||
int queueFamilyIndex,
|
||||
int queueCount);
|
||||
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
|
||||
int queueFamilyIndex,
|
||||
int queueCount);
|
||||
|
||||
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
|
||||
int queueFamilyIndex,
|
||||
int queueCount,
|
||||
float* queuePriority);
|
||||
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
|
||||
int queueFamilyIndex,
|
||||
int queueCount,
|
||||
float *queuePriority);
|
||||
|
||||
VkDeviceCreateInfo DeviceCreateInfo(
|
||||
VkDeviceQueueCreateInfo* queueInfos,
|
||||
uint32_t queueCount,
|
||||
VkPhysicalDeviceFeatures* features,
|
||||
const char* const* deviceExtensions,
|
||||
uint32_t deviceExtensionCount,
|
||||
const char* const* layers,
|
||||
uint32_t layerCount);
|
||||
VkDeviceCreateInfo DeviceCreateInfo(
|
||||
VkDeviceQueueCreateInfo *queueInfos,
|
||||
uint32_t queueCount,
|
||||
VkPhysicalDeviceFeatures *features,
|
||||
const char *const *deviceExtensions,
|
||||
uint32_t deviceExtensionCount,
|
||||
const char *const *layers,
|
||||
uint32_t layerCount);
|
||||
|
||||
VkDeviceCreateInfo DeviceCreateInfo(
|
||||
VkDeviceQueueCreateInfo* queueInfos,
|
||||
uint32_t queueCount,
|
||||
VkPhysicalDeviceFeatures* features);
|
||||
VkDeviceCreateInfo DeviceCreateInfo(
|
||||
VkDeviceQueueCreateInfo *queueInfos,
|
||||
uint32_t queueCount,
|
||||
VkPhysicalDeviceFeatures *features);
|
||||
|
||||
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
|
||||
VkSurfaceKHR surface,
|
||||
uint32_t minImageCount,
|
||||
VkFormat imageFormat,
|
||||
VkColorSpaceKHR colorSpace,
|
||||
VkExtent2D extent,
|
||||
uint32_t arrayLayers,
|
||||
VkImageUsageFlags usage,
|
||||
VkSurfaceTransformFlagBitsKHR Transform,
|
||||
VkCompositeAlphaFlagBitsKHR alpha,
|
||||
VkPresentModeKHR presentMode,
|
||||
VkBool32 clipped);
|
||||
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
|
||||
VkSurfaceKHR surface,
|
||||
uint32_t minImageCount,
|
||||
VkFormat imageFormat,
|
||||
VkColorSpaceKHR colorSpace,
|
||||
VkExtent2D extent,
|
||||
uint32_t arrayLayers,
|
||||
VkImageUsageFlags usage,
|
||||
VkSurfaceTransformFlagBitsKHR Transform,
|
||||
VkCompositeAlphaFlagBitsKHR alpha,
|
||||
VkPresentModeKHR presentMode,
|
||||
VkBool32 clipped);
|
||||
|
||||
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
|
||||
VkSurfaceKHR surface,
|
||||
uint32_t minImageCount,
|
||||
VkFormat imageFormat,
|
||||
VkColorSpaceKHR colorSpace,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t arrayLayers,
|
||||
VkImageUsageFlags usage,
|
||||
VkSurfaceTransformFlagBitsKHR Transform,
|
||||
VkCompositeAlphaFlagBitsKHR alpha,
|
||||
VkPresentModeKHR presentMode,
|
||||
VkBool32 clipped);
|
||||
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
|
||||
VkSurfaceKHR surface,
|
||||
uint32_t minImageCount,
|
||||
VkFormat imageFormat,
|
||||
VkColorSpaceKHR colorSpace,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t arrayLayers,
|
||||
VkImageUsageFlags usage,
|
||||
VkSurfaceTransformFlagBitsKHR Transform,
|
||||
VkCompositeAlphaFlagBitsKHR alpha,
|
||||
VkPresentModeKHR presentMode,
|
||||
VkBool32 clipped);
|
||||
|
||||
VkFramebufferCreateInfo FramebufferCreateInfo(
|
||||
VkRenderPass renderPass,
|
||||
uint32_t attachmentCount,
|
||||
VkImageView* attachments,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t layers);
|
||||
VkFramebufferCreateInfo FramebufferCreateInfo(
|
||||
VkRenderPass renderPass,
|
||||
uint32_t attachmentCount,
|
||||
VkImageView *attachments,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t layers);
|
||||
|
||||
VkAttachmentDescription AttachmentDescription(
|
||||
VkFormat format,
|
||||
VkSampleCountFlagBits sample,
|
||||
VkAttachmentLoadOp loadOp,
|
||||
VkAttachmentStoreOp storeOp,
|
||||
VkAttachmentLoadOp stencilLoadOp,
|
||||
VkAttachmentStoreOp stencilStoreOp,
|
||||
VkImageLayout imageLayout,
|
||||
VkImageLayout finalLayout);
|
||||
VkAttachmentDescription AttachmentDescription(
|
||||
VkFormat format,
|
||||
VkSampleCountFlagBits sample,
|
||||
VkAttachmentLoadOp loadOp,
|
||||
VkAttachmentStoreOp storeOp,
|
||||
VkAttachmentLoadOp stencilLoadOp,
|
||||
VkAttachmentStoreOp stencilStoreOp,
|
||||
VkImageLayout imageLayout,
|
||||
VkImageLayout finalLayout);
|
||||
|
||||
VkSubpassDescription SubpassDescription(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
uint32_t colorAttachmentCount,
|
||||
VkAttachmentReference* colorReference,
|
||||
uint32_t depthAttachmentCount = 0,
|
||||
VkAttachmentReference* depthReference = nullptr,
|
||||
uint32_t inputAttachmentCount = 0,
|
||||
VkAttachmentReference* inputReference = nullptr,
|
||||
uint32_t resolveAttachmentCount = 0,
|
||||
VkAttachmentReference* resolveReference = nullptr,
|
||||
uint32_t preserveAttachmentCount = 0,
|
||||
VkAttachmentReference* preserveReference = nullptr);
|
||||
VkSubpassDescription SubpassDescription(
|
||||
VkPipelineBindPoint bindPoint,
|
||||
uint32_t colorAttachmentCount,
|
||||
VkAttachmentReference *colorReference,
|
||||
VkAttachmentReference *depthReference = nullptr,
|
||||
uint32_t inputAttachmentCount = 0,
|
||||
VkAttachmentReference *inputReference = nullptr,
|
||||
VkAttachmentReference *resolveReference = nullptr,
|
||||
uint32_t preserveAttachmentCount = 0,
|
||||
uint32_t *preserveReference = nullptr);
|
||||
|
||||
VkRenderPassCreateInfo RenderPassCreateInfo(
|
||||
uint32_t attachmentCount,
|
||||
const VkAttachmentDescription* attachments,
|
||||
uint32_t subpassCount,
|
||||
const VkSubpassDescription* subpasses,
|
||||
uint32_t dependencyCount,
|
||||
const VkSubpassDependency* subpassDependencies);
|
||||
VkRenderPassCreateInfo RenderPassCreateInfo(
|
||||
uint32_t attachmentCount,
|
||||
const VkAttachmentDescription *attachments,
|
||||
uint32_t subpassCount,
|
||||
const VkSubpassDescription *subpasses,
|
||||
uint32_t dependencyCount,
|
||||
const VkSubpassDependency *subpassDependencies);
|
||||
|
||||
VkMemoryAllocateInfo MemoryAllocateInfo();
|
||||
VkMemoryAllocateInfo MemoryAllocateInfo();
|
||||
|
||||
VkCommandBufferAllocateInfo CommandBufferAllocateInfo(
|
||||
VkCommandPool cmdPool,
|
||||
VkCommandBufferLevel level,
|
||||
uint32_t bufferCount);
|
||||
VkCommandBufferAllocateInfo CommandBufferAllocateInfo(
|
||||
VkCommandPool cmdPool,
|
||||
VkCommandBufferLevel level,
|
||||
uint32_t bufferCount);
|
||||
|
||||
VkCommandPoolCreateInfo CommandPoolCreateInfo();
|
||||
VkCommandPoolCreateInfo CommandPoolCreateInfo();
|
||||
|
||||
VkCommandBufferBeginInfo CommandBufferBeginInfo();
|
||||
VkCommandBufferBeginInfo CommandBufferBeginInfo();
|
||||
|
||||
VkCommandBufferInheritanceInfo CommandBufferInheritanceInfo();
|
||||
VkCommandBufferInheritanceInfo CommandBufferInheritanceInfo();
|
||||
|
||||
VkRenderPassBeginInfo RenderPassBeginInfo();
|
||||
VkRenderPassBeginInfo RenderPassBeginInfo();
|
||||
|
||||
VkRenderPassCreateInfo RenderPassCreateInfo();
|
||||
VkRenderPassCreateInfo RenderPassCreateInfo();
|
||||
|
||||
VkImageMemoryBarrier ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue = VK_QUEUE_FAMILY_IGNORED, uint32_t dstQueue = VK_QUEUE_FAMILY_IGNORED);
|
||||
VkImageMemoryBarrier ImageMemoryBarrier();
|
||||
VkImageMemoryBarrier ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue = VK_QUEUE_FAMILY_IGNORED, uint32_t dstQueue = VK_QUEUE_FAMILY_IGNORED);
|
||||
VkImageMemoryBarrier ImageMemoryBarrier();
|
||||
|
||||
VkBufferMemoryBarrier BufferMemoryBarrier();
|
||||
VkBufferMemoryBarrier BufferMemoryBarrier();
|
||||
|
||||
VkMemoryBarrier MemoryBarrier();
|
||||
VkMemoryBarrier MemoryBarrier();
|
||||
|
||||
VkImageCreateInfo ImageCreateInfo();
|
||||
VkImageCreateInfo ImageCreateInfo();
|
||||
|
||||
VkSamplerCreateInfo SamplerCreateInfo();
|
||||
VkSamplerCreateInfo SamplerCreateInfo();
|
||||
|
||||
VkImageViewCreateInfo ImageViewCreateInfo();
|
||||
VkImageViewCreateInfo ImageViewCreateInfo();
|
||||
|
||||
VkSemaphoreCreateInfo SemaphoreCreateInfo();
|
||||
VkSemaphoreCreateInfo SemaphoreCreateInfo();
|
||||
|
||||
VkFenceCreateInfo FenceCreateInfo(
|
||||
VkFenceCreateFlags flags);
|
||||
VkFenceCreateInfo FenceCreateInfo(
|
||||
VkFenceCreateFlags flags);
|
||||
|
||||
VkEventCreateInfo EventCreateInfo();
|
||||
VkEventCreateInfo EventCreateInfo();
|
||||
|
||||
VkSubmitInfo SubmitInfo();
|
||||
VkSubmitInfo SubmitInfo();
|
||||
|
||||
VkImageSubresourceRange ImageSubresourceRange(
|
||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
uint32_t startMip = 0);
|
||||
VkImageSubresourceRange ImageSubresourceRange(
|
||||
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
uint32_t startMip = 0);
|
||||
|
||||
VkViewport Viewport(
|
||||
float width,
|
||||
float height,
|
||||
float minDepth,
|
||||
float maxDepth);
|
||||
VkViewport Viewport(
|
||||
float width,
|
||||
float height,
|
||||
float minDepth,
|
||||
float maxDepth);
|
||||
|
||||
VkRect2D Rect2D(
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t offsetX,
|
||||
int32_t offsetY);
|
||||
VkRect2D Rect2D(
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t offsetX,
|
||||
int32_t offsetY);
|
||||
|
||||
VkBufferCreateInfo BufferCreateInfo();
|
||||
VkBufferCreateInfo BufferCreateInfo();
|
||||
|
||||
VkBufferCreateInfo BufferCreateInfo(
|
||||
VkBufferUsageFlags usage,
|
||||
VkDeviceSize size);
|
||||
VkBufferCreateInfo BufferCreateInfo(
|
||||
VkBufferUsageFlags usage,
|
||||
VkDeviceSize size);
|
||||
|
||||
VkDescriptorPoolCreateInfo DescriptorPoolCreateInfo(
|
||||
uint32_t poolSizeCount,
|
||||
VkDescriptorPoolSize* pPoolSizes,
|
||||
uint32_t maxSets);
|
||||
VkDescriptorPoolCreateInfo DescriptorPoolCreateInfo(
|
||||
uint32_t poolSizeCount,
|
||||
VkDescriptorPoolSize *pPoolSizes,
|
||||
uint32_t maxSets);
|
||||
|
||||
VkDescriptorPoolSize DescriptorPoolSize(
|
||||
VkDescriptorType type,
|
||||
uint32_t descriptorCount);
|
||||
VkDescriptorPoolSize DescriptorPoolSize(
|
||||
VkDescriptorType type,
|
||||
uint32_t descriptorCount);
|
||||
|
||||
VkDescriptorSetLayoutBinding DescriptorSetLayoutBinding(
|
||||
VkDescriptorType type,
|
||||
VkShaderStageFlags stageFlags,
|
||||
uint32_t binding,
|
||||
uint32_t count);
|
||||
VkDescriptorSetLayoutBinding DescriptorSetLayoutBinding(
|
||||
VkDescriptorType type,
|
||||
VkShaderStageFlags stageFlags,
|
||||
uint32_t binding,
|
||||
uint32_t count);
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo(
|
||||
const VkDescriptorSetLayoutBinding* pBindings,
|
||||
uint32_t bindingCount);
|
||||
VkDescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo(
|
||||
const VkDescriptorSetLayoutBinding *pBindings,
|
||||
uint32_t bindingCount);
|
||||
|
||||
VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo(
|
||||
const VkDescriptorSetLayout* pSetLayouts,
|
||||
uint32_t setLayoutCount);
|
||||
VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo(
|
||||
const VkDescriptorSetLayout *pSetLayouts,
|
||||
uint32_t setLayoutCount);
|
||||
|
||||
VkDescriptorSetAllocateInfo DescriptorSetAllocateInfo(
|
||||
VkDescriptorPool descriptorPool,
|
||||
const VkDescriptorSetLayout* pSetLayouts,
|
||||
uint32_t descriptorSetCount);
|
||||
VkDescriptorSetAllocateInfo DescriptorSetAllocateInfo(
|
||||
VkDescriptorPool descriptorPool,
|
||||
const VkDescriptorSetLayout *pSetLayouts,
|
||||
uint32_t descriptorSetCount);
|
||||
|
||||
VkDescriptorBufferInfo DescriptorBufferInfo(
|
||||
VkBuffer buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize range);
|
||||
VkDescriptorImageInfo DescriptorImageInfo(
|
||||
VkSampler sampler,
|
||||
VkImageView imageView,
|
||||
VkImageLayout imageLayout);
|
||||
VkDescriptorBufferInfo DescriptorBufferInfo(
|
||||
VkBuffer buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize range);
|
||||
VkDescriptorImageInfo DescriptorImageInfo(
|
||||
VkSampler sampler,
|
||||
VkImageView imageView,
|
||||
VkImageLayout imageLayout);
|
||||
|
||||
VkWriteDescriptorSet WriteDescriptorSet(
|
||||
VkDescriptorSet dstSet,
|
||||
VkDescriptorType type,
|
||||
uint32_t binding,
|
||||
VkDescriptorBufferInfo* bufferInfo);
|
||||
VkWriteDescriptorSet WriteDescriptorSet(
|
||||
VkDescriptorSet dstSet,
|
||||
VkDescriptorType type,
|
||||
uint32_t binding,
|
||||
VkDescriptorBufferInfo *bufferInfo);
|
||||
|
||||
VkWriteDescriptorSet WriteDescriptorSet(
|
||||
VkDescriptorSet dstSet,
|
||||
VkDescriptorType type,
|
||||
uint32_t binding,
|
||||
VkDescriptorImageInfo* bufferInfo);
|
||||
VkWriteDescriptorSet WriteDescriptorSet(
|
||||
VkDescriptorSet dstSet,
|
||||
VkDescriptorType type,
|
||||
uint32_t binding,
|
||||
VkDescriptorImageInfo *bufferInfo);
|
||||
|
||||
VkVertexInputBindingDescription VertexInputBindingDescription(
|
||||
uint32_t binding,
|
||||
uint32_t stride,
|
||||
VkVertexInputRate inputRate);
|
||||
|
||||
VkVertexInputBindingDescription VertexInputBindingDescription(
|
||||
uint32_t binding,
|
||||
uint32_t stride,
|
||||
VkVertexInputRate inputRate);
|
||||
VkVertexInputAttributeDescription VertexInputAttributeDescription(
|
||||
uint32_t binding,
|
||||
uint32_t location,
|
||||
VkFormat format,
|
||||
uint32_t offset);
|
||||
|
||||
VkVertexInputAttributeDescription VertexInputAttributeDescription(
|
||||
uint32_t binding,
|
||||
uint32_t location,
|
||||
VkFormat format,
|
||||
uint32_t offset);
|
||||
VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo();
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo();
|
||||
VkPipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo(
|
||||
VkPrimitiveTopology topology,
|
||||
VkPipelineInputAssemblyStateCreateFlags flags,
|
||||
VkBool32 primitiveRestartEnable);
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo(
|
||||
VkPrimitiveTopology topology,
|
||||
VkPipelineInputAssemblyStateCreateFlags flags,
|
||||
VkBool32 primitiveRestartEnable);
|
||||
VkPipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo(
|
||||
VkPolygonMode polygonMode,
|
||||
VkCullModeFlags cullMode,
|
||||
VkFrontFace frontFace,
|
||||
VkPipelineRasterizationStateCreateFlags flags);
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo(
|
||||
VkPolygonMode polygonMode,
|
||||
VkCullModeFlags cullMode,
|
||||
VkFrontFace frontFace,
|
||||
VkPipelineRasterizationStateCreateFlags flags);
|
||||
VkPipelineColorBlendAttachmentState PipelineColorBlendAttachmentState(
|
||||
VkColorComponentFlags colorWriteMask,
|
||||
VkBool32 blendEnable);
|
||||
|
||||
VkPipelineColorBlendAttachmentState PipelineColorBlendAttachmentState(
|
||||
VkColorComponentFlags colorWriteMask,
|
||||
VkBool32 blendEnable);
|
||||
VkPipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo(
|
||||
uint32_t attachmentCount,
|
||||
const VkPipelineColorBlendAttachmentState *pAttachments);
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo(
|
||||
uint32_t attachmentCount,
|
||||
const VkPipelineColorBlendAttachmentState* pAttachments);
|
||||
VkPipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo(
|
||||
VkBool32 depthTestEnable,
|
||||
VkBool32 depthWriteEnable,
|
||||
VkCompareOp depthCompareOp);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo(
|
||||
VkBool32 depthTestEnable,
|
||||
VkBool32 depthWriteEnable,
|
||||
VkCompareOp depthCompareOp);
|
||||
VkPipelineViewportStateCreateInfo PipelineViewportStateCreateInfo(
|
||||
uint32_t viewportCount,
|
||||
uint32_t scissorCount,
|
||||
VkPipelineViewportStateCreateFlags flags);
|
||||
|
||||
VkPipelineViewportStateCreateInfo PipelineViewportStateCreateInfo(
|
||||
uint32_t viewportCount,
|
||||
uint32_t scissorCount,
|
||||
VkPipelineViewportStateCreateFlags flags);
|
||||
VkPipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo(
|
||||
VkSampleCountFlagBits rasterizationSamples,
|
||||
VkPipelineMultisampleStateCreateFlags flags);
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo(
|
||||
VkSampleCountFlagBits rasterizationSamples,
|
||||
VkPipelineMultisampleStateCreateFlags flags);
|
||||
VkPipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo(
|
||||
const VkDynamicState *pDynamicStates,
|
||||
uint32_t dynamicStateCount,
|
||||
VkPipelineDynamicStateCreateFlags flags);
|
||||
|
||||
VkPipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo(
|
||||
const VkDynamicState* pDynamicStates,
|
||||
uint32_t dynamicStateCount,
|
||||
VkPipelineDynamicStateCreateFlags flags);
|
||||
VkPipelineTessellationStateCreateInfo PipelineTessellationStateCreateInfo(
|
||||
uint32_t patchControlPoints);
|
||||
|
||||
VkPipelineTessellationStateCreateInfo PipelineTessellationStateCreateInfo(
|
||||
uint32_t patchControlPoints);
|
||||
VkGraphicsPipelineCreateInfo PipelineCreateInfo(
|
||||
VkPipelineLayout layout,
|
||||
VkRenderPass renderPass,
|
||||
VkPipelineCreateFlags flags);
|
||||
|
||||
VkGraphicsPipelineCreateInfo PipelineCreateInfo(
|
||||
VkPipelineLayout layout,
|
||||
VkRenderPass renderPass,
|
||||
VkPipelineCreateFlags flags);
|
||||
VkComputePipelineCreateInfo ComputePipelineCreateInfo(
|
||||
VkPipelineLayout layout,
|
||||
VkPipelineCreateFlags flags);
|
||||
|
||||
VkComputePipelineCreateInfo ComputePipelineCreateInfo(
|
||||
VkPipelineLayout layout,
|
||||
VkPipelineCreateFlags flags);
|
||||
VkPushConstantRange PushConstantRange(
|
||||
VkShaderStageFlags stageFlags,
|
||||
uint32_t size,
|
||||
uint32_t offset);
|
||||
|
||||
VkPushConstantRange PushConstantRange(
|
||||
VkShaderStageFlags stageFlags,
|
||||
uint32_t size,
|
||||
uint32_t offset);
|
||||
|
||||
VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(
|
||||
VkShaderStageFlagBits stage,
|
||||
VkShaderModule module,
|
||||
const char* entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(
|
||||
VkShaderStageFlagBits stage,
|
||||
VkShaderModule module,
|
||||
const char *entryName);
|
||||
} // namespace init
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "VulkanQueue.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Queue::Queue(PGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex)
|
||||
Queue::Queue(PGraphics graphics, Gfx::QueueType queueType, uint32 familyIndex, uint32 queueIndex)
|
||||
: familyIndex(familyIndex)
|
||||
, graphics(graphics)
|
||||
, queueType(queueType)
|
||||
@@ -16,4 +19,47 @@ Queue::Queue(PGraphics graphics, QueueType queueType, uint32 familyIndex, uint32
|
||||
Queue::~Queue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore* signalSemaphores)
|
||||
{
|
||||
assert(cmdBuffer->state == CmdBuffer::State::Ended);
|
||||
|
||||
PFence fence = cmdBuffer->fence;
|
||||
assert(!fence->isSignaled());
|
||||
|
||||
const VkCommandBuffer cmdBuffers[] = {cmdBuffer->handle};
|
||||
|
||||
VkSubmitInfo submitInfo =
|
||||
init::SubmitInfo();
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = cmdBuffers;
|
||||
submitInfo.signalSemaphoreCount = static_cast<uint32>(numSignalSemaphores);
|
||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||
|
||||
Array<VkSemaphore> waitSemaphores;
|
||||
if(cmdBuffer->waitSemaphores.size() > 0)
|
||||
{
|
||||
for(PSemaphore semaphore : cmdBuffer->waitSemaphores)
|
||||
{
|
||||
waitSemaphores.add(semaphore->getHandle());
|
||||
}
|
||||
submitInfo.waitSemaphoreCount = static_cast<uint32>(cmdBuffer->waitSemaphores.size());
|
||||
submitInfo.pWaitSemaphores = waitSemaphores.data();
|
||||
submitInfo.pWaitDstStageMask = cmdBuffer->waitFlags.data();
|
||||
}
|
||||
|
||||
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
|
||||
|
||||
cmdBuffer->state = CmdBuffer::State::Submitted;
|
||||
cmdBuffer->waitFlags.clear();
|
||||
cmdBuffer->waitSemaphores.clear();
|
||||
|
||||
if(Gfx::waitIdleOnSubmit)
|
||||
{
|
||||
fence->wait(200 * 1000ull);
|
||||
}
|
||||
|
||||
cmdBuffer->refreshFence();
|
||||
graphics->getStagingManager()->clearPending();
|
||||
}
|
||||
@@ -3,34 +3,35 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(CmdBuffer);
|
||||
DECLARE_REF(Graphics);
|
||||
class Queue
|
||||
{
|
||||
public:
|
||||
Queue(PGraphics graphics, Gfx::QueueType queueType, uint32 familyIndex, uint32 queueIndex);
|
||||
virtual ~Queue();
|
||||
void submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores = 0, VkSemaphore *signalSemaphore = nullptr);
|
||||
inline void submitCommandBuffer(PCmdBuffer cmdBuffer, VkSemaphore signalSemaphore)
|
||||
{
|
||||
DECLARE_REF(CmdBuffer);
|
||||
DECLARE_REF(Graphics);
|
||||
class Queue
|
||||
{
|
||||
public:
|
||||
Queue(PGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex);
|
||||
virtual ~Queue();
|
||||
void submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores = 0, VkSemaphore* signalSemaphore = nullptr);
|
||||
inline void submitCommandBuffer(PCmdBuffer cmdBuffer, VkSemaphore signalSemaphore)
|
||||
{
|
||||
submitCommandBuffer(cmdBuffer, 1, &signalSemaphore);
|
||||
}
|
||||
uint32 getFamilyIndex() const
|
||||
{
|
||||
return familyIndex;
|
||||
}
|
||||
inline VkQueue getHandle() const
|
||||
{
|
||||
return queue;
|
||||
}
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkQueue queue;
|
||||
uint32 familyIndex;
|
||||
QueueType queueType;
|
||||
};
|
||||
DEFINE_REF(Queue)
|
||||
submitCommandBuffer(cmdBuffer, 1, &signalSemaphore);
|
||||
}
|
||||
}
|
||||
uint32 getFamilyIndex() const
|
||||
{
|
||||
return familyIndex;
|
||||
}
|
||||
inline VkQueue getHandle() const
|
||||
{
|
||||
return queue;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkQueue queue;
|
||||
uint32 familyIndex;
|
||||
Gfx::QueueType queueType;
|
||||
};
|
||||
DEFINE_REF(Queue)
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,127 @@
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout)
|
||||
: layout(layout), graphics(graphics)
|
||||
{
|
||||
Array<VkAttachmentDescription> attachments;
|
||||
Array<VkAttachmentReference> inputRefs;
|
||||
Array<VkAttachmentReference> colorRefs;
|
||||
VkAttachmentReference depthRef;
|
||||
uint32 attachmentCounter = 0;
|
||||
for (auto inputAttachment : layout->inputAttachments)
|
||||
{
|
||||
PTexture2D image = inputAttachment->getTexture().cast<Texture2D>();
|
||||
VkAttachmentDescription desc = attachments.add();
|
||||
desc.flags = 0;
|
||||
desc.format = cast(image->getFormat());
|
||||
desc.storeOp = cast(inputAttachment->getStoreOp());
|
||||
desc.loadOp = cast(inputAttachment->getLoadOp());
|
||||
desc.stencilStoreOp = cast(inputAttachment->getStencilStoreOp());
|
||||
desc.stencilLoadOp = cast(inputAttachment->getStencilLoadOp());
|
||||
desc.initialLayout = image->isDepthStencil() ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
desc.finalLayout = desc.initialLayout;
|
||||
|
||||
VkAttachmentReference &ref = inputRefs.add();
|
||||
ref.layout = desc.initialLayout;
|
||||
ref.attachment = attachmentCounter;
|
||||
attachmentCounter++;
|
||||
}
|
||||
for (auto colorAttachment : layout->colorAttachments)
|
||||
{
|
||||
PTexture2D image = colorAttachment->getTexture().cast<Texture2D>();
|
||||
VkAttachmentDescription desc = attachments.add();
|
||||
desc.flags = 0;
|
||||
desc.format = cast(image->getFormat());
|
||||
desc.storeOp = cast(colorAttachment->getStoreOp());
|
||||
desc.loadOp = cast(colorAttachment->getLoadOp());
|
||||
desc.stencilStoreOp = cast(colorAttachment->getStencilStoreOp());
|
||||
desc.stencilLoadOp = cast(colorAttachment->getStencilLoadOp());
|
||||
desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkAttachmentReference &ref = colorRefs.add();
|
||||
ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
ref.attachment = attachmentCounter;
|
||||
attachmentCounter++;
|
||||
}
|
||||
if (layout->depthAttachment != nullptr)
|
||||
{
|
||||
PTexture2D image = layout->depthAttachment->getTexture().cast<Texture2D>();
|
||||
VkAttachmentDescription desc = attachments.add();
|
||||
desc.flags = 0;
|
||||
desc.format = cast(image->getFormat());
|
||||
desc.storeOp = cast(layout->depthAttachment->getStoreOp());
|
||||
desc.loadOp = cast(layout->depthAttachment->getLoadOp());
|
||||
desc.stencilStoreOp = cast(layout->depthAttachment->getStencilStoreOp());
|
||||
desc.stencilLoadOp = cast(layout->depthAttachment->getStencilLoadOp());
|
||||
desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkAttachmentReference &ref = depthRef;
|
||||
ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
ref.attachment = attachmentCounter;
|
||||
attachmentCounter++;
|
||||
}
|
||||
VkSubpassDescription subPassDesc =
|
||||
init::SubpassDescription(
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
colorRefs.size(),
|
||||
colorRefs.data(),
|
||||
&depthRef,
|
||||
inputRefs.size(),
|
||||
inputRefs.data());
|
||||
VkSubpassDependency dependency = {};
|
||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependency.dstSubpass = 0;
|
||||
|
||||
dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
VkRenderPassCreateInfo info =
|
||||
init::RenderPassCreateInfo(
|
||||
attachments.size(),
|
||||
attachments.data(),
|
||||
1,
|
||||
&subPassDesc,
|
||||
1,
|
||||
&dependency);
|
||||
|
||||
VK_CHECK(vkCreateRenderPass(graphics->getDevice(), &info, nullptr, &renderPass));
|
||||
}
|
||||
|
||||
RenderPass::~RenderPass()
|
||||
{
|
||||
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
|
||||
}
|
||||
|
||||
uint32 RenderPass::getFramebufferHash()
|
||||
{
|
||||
FramebufferDescription description;
|
||||
std::memset(&description, 0, sizeof(FramebufferDescription));
|
||||
for(auto inputAttachment : layout->inputAttachments)
|
||||
{
|
||||
PTexture2D tex = inputAttachment->getTexture().cast<Texture2D>();
|
||||
description.inputAttachments[description.numInputAttachments++] = tex->getView();
|
||||
}
|
||||
for(auto colorAttachment : layout->colorAttachments)
|
||||
{
|
||||
PTexture2D tex = colorAttachment->getTexture().cast<Texture2D>();
|
||||
description.colorAttachments[description.numColorAttachments++] = tex->getView();
|
||||
}
|
||||
if(layout->depthAttachment != nullptr)
|
||||
{
|
||||
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
|
||||
description.depthAttachment = tex->getView();
|
||||
}
|
||||
return memCrc32(&description, sizeof(FramebufferDescription));
|
||||
}
|
||||
@@ -2,39 +2,46 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
namespace Vulkan
|
||||
{
|
||||
class RenderPass : public Gfx::RenderPass
|
||||
{
|
||||
public:
|
||||
RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout);
|
||||
virtual ~RenderPass();
|
||||
uint32 getFramebufferHash();
|
||||
inline VkRenderPass getHandle() const
|
||||
{
|
||||
class RenderPass
|
||||
{
|
||||
public:
|
||||
RenderPass();
|
||||
virtual ~RenderPass();
|
||||
inline VkRenderPass getHandle() const
|
||||
{
|
||||
return renderPass;
|
||||
}
|
||||
inline uint32 getClearValueCount() const
|
||||
{
|
||||
return clearValues.size();
|
||||
}
|
||||
inline VkClearValue* getClearValues() const
|
||||
{
|
||||
return clearValues.data();
|
||||
}
|
||||
inline VkRect2D getRenderArea() const
|
||||
{
|
||||
return renderArea;
|
||||
}
|
||||
inline VkSubpassContents getSubpassContents() const
|
||||
{
|
||||
return subpassContents;
|
||||
}
|
||||
private:
|
||||
VkRenderPass renderPass;
|
||||
Array<VkClearValue> clearValues;
|
||||
VkRect2D renderArea;
|
||||
VkSubpassContents subpassContents;
|
||||
};
|
||||
DEFINE_REF(RenderPass);
|
||||
return renderPass;
|
||||
}
|
||||
}
|
||||
inline uint32 getClearValueCount() const
|
||||
{
|
||||
return clearValues.size();
|
||||
}
|
||||
inline VkClearValue *getClearValues() const
|
||||
{
|
||||
return clearValues.data();
|
||||
}
|
||||
inline VkRect2D getRenderArea() const
|
||||
{
|
||||
return renderArea;
|
||||
}
|
||||
inline VkSubpassContents getSubpassContents() const
|
||||
{
|
||||
return subpassContents;
|
||||
}
|
||||
inline Gfx::PRenderTargetLayout getLayout()
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Gfx::PRenderTargetLayout layout;
|
||||
VkRenderPass renderPass;
|
||||
Array<VkClearValue> clearValues;
|
||||
VkRect2D renderArea;
|
||||
VkSubpassContents subpassContents;
|
||||
};
|
||||
DEFINE_REF(RenderPass);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -2,90 +2,196 @@
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include <math.h>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevel,
|
||||
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage)
|
||||
: graphics(graphics)
|
||||
, sizeX(sizeX)
|
||||
, sizeY(sizeY)
|
||||
, sizeZ(sizeZ)
|
||||
, mipLevels(mipLevel)
|
||||
, format(format)
|
||||
, arrayCount(bArray ? arraySize : 1)
|
||||
VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
|
||||
{
|
||||
PAllocator allocator = graphics->getAllocator();
|
||||
VkImageCreateInfo info =
|
||||
init::ImageCreateInfo();
|
||||
info.extent.width = sizeX;
|
||||
info.extent.height = sizeY;
|
||||
info.extent.depth = sizeZ;
|
||||
info.arrayLayers = arraySize;
|
||||
info.format = cast(format);
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case Gfx::SE_FORMAT_D16_UNORM:
|
||||
return VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
case Gfx::SE_FORMAT_D32_SFLOAT:
|
||||
return VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
case Gfx::SE_FORMAT_S8_UINT:
|
||||
return VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
case Gfx::SE_FORMAT_D16_UNORM_S8_UINT:
|
||||
case Gfx::SE_FORMAT_D24_UNORM_S8_UINT:
|
||||
case Gfx::SE_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
case Gfx::SE_FORMAT_X8_D24_UNORM_PACK32:
|
||||
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
default:
|
||||
return VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevel,
|
||||
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner, VkImage existingImage)
|
||||
: QueueOwnedResource(graphics, owner), graphics(graphics), sizeX(sizeX), sizeY(sizeY), sizeZ(sizeZ), mipLevels(mipLevel), format(format), samples(samples), usage(usage), arrayCount(bArray ? arraySize : 1), aspect(getAspectFromFormat(format))
|
||||
{
|
||||
if (existingImage == VK_NULL_HANDLE)
|
||||
{
|
||||
PAllocator allocator = graphics->getAllocator();
|
||||
VkImageCreateInfo info =
|
||||
init::ImageCreateInfo();
|
||||
info.extent.width = sizeX;
|
||||
info.extent.height = sizeY;
|
||||
info.extent.depth = sizeZ;
|
||||
info.arrayLayers = arraySize;
|
||||
info.format = cast(format);
|
||||
|
||||
uint32 layerCount = 1;
|
||||
switch (viewType)
|
||||
{
|
||||
case VK_IMAGE_VIEW_TYPE_1D:
|
||||
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
|
||||
info.imageType = VK_IMAGE_TYPE_1D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_2D:
|
||||
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_3D:
|
||||
info.imageType = VK_IMAGE_TYPE_3D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_CUBE:
|
||||
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
layerCount = 6 * arrayCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
info.mipLevels = mipLevel;
|
||||
info.arrayLayers = arrayCount * layerCount;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.samples = (VkSampleCountFlagBits)samples;
|
||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
info.usage = usage;
|
||||
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
|
||||
|
||||
VkMemoryDedicatedRequirements memDedicatedRequirements;
|
||||
memDedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
||||
memDedicatedRequirements.pNext = nullptr;
|
||||
VkImageMemoryRequirementsInfo2 reqInfo;
|
||||
reqInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
|
||||
reqInfo.pNext = nullptr;
|
||||
reqInfo.image = image;
|
||||
VkMemoryRequirements2 requirements;
|
||||
requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
requirements.pNext = &memDedicatedRequirements;
|
||||
vkGetImageMemoryRequirements2(graphics->getDevice(), &reqInfo, &requirements);
|
||||
|
||||
allocation = allocator->allocate(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image);
|
||||
vkBindImageMemory(graphics->getDevice(), image, allocation->getHandle(), allocation->getOffset());
|
||||
}
|
||||
VkImageViewCreateInfo viewInfo =
|
||||
init::ImageViewCreateInfo();
|
||||
viewInfo.subresourceRange = init::ImageSubresourceRange(aspect);
|
||||
viewInfo.viewType = viewType;
|
||||
|
||||
uint32 layerCount = 1;
|
||||
switch (viewType)
|
||||
{
|
||||
case VK_IMAGE_VIEW_TYPE_1D:
|
||||
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
|
||||
info.imageType = VK_IMAGE_TYPE_1D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_2D:
|
||||
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_3D:
|
||||
info.imageType = VK_IMAGE_TYPE_3D;
|
||||
break;
|
||||
case VK_IMAGE_VIEW_TYPE_CUBE:
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
layerCount = 6 * arrayCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
info.mipLevels = mipLevel;
|
||||
info.arrayLayers = arrayCount * layerCount;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.samples = (VkSampleCountFlagBits)samples;
|
||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
info.usage = usage;
|
||||
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
|
||||
|
||||
viewInfo.image = image;
|
||||
viewInfo.format = cast(format);
|
||||
viewInfo.subresourceRange.layerCount = layerCount;
|
||||
viewInfo.subresourceRange.layerCount = (viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY || viewType == VK_IMAGE_VIEW_TYPE_CUBE) ? 6 : 1;
|
||||
viewInfo.subresourceRange.levelCount = mipLevels;
|
||||
|
||||
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &defaultView));
|
||||
}
|
||||
|
||||
TextureBase::~TextureBase()
|
||||
TextureHandle::~TextureHandle()
|
||||
{
|
||||
vkDestroyImageView(graphics->getDevice(), defaultView, nullptr);
|
||||
vkDestroyImage(graphics->getDevice(), image, nullptr);
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevels,
|
||||
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage)
|
||||
{
|
||||
textureHandle = new TextureBase(graphics, bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
|
||||
sizeX, sizeY, 1, bArray, arraySize, mipLevels, format, samples, usage);
|
||||
void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
VkImageMemoryBarrier imageBarrier =
|
||||
init::ImageMemoryBarrier();
|
||||
imageBarrier.image = image;
|
||||
imageBarrier.oldLayout = layout;
|
||||
imageBarrier.newLayout = layout;
|
||||
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
|
||||
PCommandBufferManager sourceManager = getCommands();
|
||||
PCommandBufferManager dstManager = nullptr;
|
||||
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
||||
imageBarrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
|
||||
imageBarrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
|
||||
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
{
|
||||
imageBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
else if (currentOwner == Gfx::QueueType::COMPUTE)
|
||||
{
|
||||
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
}
|
||||
else if (currentOwner == Gfx::QueueType::GRAPHICS)
|
||||
{
|
||||
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
}
|
||||
if (newOwner == Gfx::QueueType::TRANSFER)
|
||||
{
|
||||
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstManager = graphics->getTransferCommands();
|
||||
}
|
||||
else if(currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
{
|
||||
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstManager = graphics->getDedicatedTransferCommands();
|
||||
}
|
||||
else if (newOwner == Gfx::QueueType::COMPUTE)
|
||||
{
|
||||
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
dstManager = graphics->getComputeCommands();
|
||||
}
|
||||
else if (newOwner == Gfx::QueueType::GRAPHICS)
|
||||
{
|
||||
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
dstManager = graphics->getGraphicsCommands();
|
||||
}
|
||||
VkCommandBuffer sourceCmd = sourceManager->getCommands()->getHandle();
|
||||
VkCommandBuffer destCmd = dstManager->getCommands()->getHandle();
|
||||
vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||
vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
|
||||
sourceManager->submitCommands();
|
||||
cachedCmdBufferManager = dstManager;
|
||||
}
|
||||
|
||||
void TextureBase::changeLayout(VkImageLayout newLayout)
|
||||
{
|
||||
VkImageMemoryBarrier barrier =
|
||||
init::ImageMemoryBarrier(
|
||||
textureHandle->image,
|
||||
textureHandle->layout,
|
||||
newLayout);
|
||||
vkCmdPipelineBarrier(textureHandle->getCommands()->getCommands()->getHandle(),
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
textureHandle->layout = newLayout;
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
|
||||
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner, VkImage existingImage)
|
||||
{
|
||||
textureHandle = new TextureHandle(graphics, bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
|
||||
sizeX, sizeY, 1, bArray, arraySize, mipLevels, format, samples, usage, owner, existingImage);
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include <glfw/glfw3.h>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
: Gfx::Window(createInfo), graphics(graphics), instance(graphics->getInstance())
|
||||
{
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow *handle = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
|
||||
windowHandle = handle;
|
||||
|
||||
//TODO: callbacks
|
||||
|
||||
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
|
||||
|
||||
createSwapchain();
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
|
||||
}
|
||||
|
||||
void Window::beginFrame()
|
||||
{
|
||||
advanceBackBuffer();
|
||||
}
|
||||
|
||||
void Window::endFrame()
|
||||
{
|
||||
present();
|
||||
}
|
||||
|
||||
void Window::onWindowCloseEvent()
|
||||
{
|
||||
}
|
||||
|
||||
Gfx::PTexture2D Window::getBackBuffer()
|
||||
{
|
||||
return backBufferImages[currentImageIndex];
|
||||
}
|
||||
|
||||
void Window::advanceBackBuffer()
|
||||
{
|
||||
VkResult res = VK_ERROR_OUT_OF_DATE_KHR;
|
||||
uint32 imageIndex = 0;
|
||||
const int32 prevSemaphoreIndex = semaphoreIndex;
|
||||
semaphoreIndex = (semaphoreIndex + 1) % Gfx::numFramesBuffered;
|
||||
|
||||
while (res != VK_SUCCESS)
|
||||
{
|
||||
res = vkAcquireNextImageKHR(
|
||||
graphics->getDevice(),
|
||||
swapchain,
|
||||
UINT64_MAX,
|
||||
imageAcquired[semaphoreIndex]->getHandle(),
|
||||
VK_NULL_HANDLE,
|
||||
&imageIndex);
|
||||
if (res == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
{
|
||||
semaphoreIndex = prevSemaphoreIndex;
|
||||
}
|
||||
if (res == VK_ERROR_SURFACE_LOST_KHR)
|
||||
{
|
||||
semaphoreIndex = prevSemaphoreIndex;
|
||||
}
|
||||
}
|
||||
imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
|
||||
currentImageIndex = imageIndex;
|
||||
|
||||
VkImageMemoryBarrier barrier =
|
||||
init::ImageMemoryBarrier(
|
||||
backBufferImages[currentImageIndex]->getHandle(),
|
||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||
vkCmdPipelineBarrier(cmdBuffer->getHandle(),
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
cmdBuffer->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
}
|
||||
|
||||
void Window::recreateSwapchain(const WindowCreateInfo &windowInfo)
|
||||
{
|
||||
destroySwapchain();
|
||||
sizeX = windowInfo.width;
|
||||
sizeY = windowInfo.height;
|
||||
pixelFormat = cast(windowInfo.pixelFormat);
|
||||
bFullscreen = windowInfo.bFullscreen;
|
||||
|
||||
uint32_t numFormats;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, nullptr));
|
||||
Array<VkSurfaceFormatKHR> formats(numFormats);
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, formats.data()));
|
||||
|
||||
uint32_t numPresentModes;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, nullptr));
|
||||
Array<VkPresentModeKHR> modes(numPresentModes);
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, modes.data()));
|
||||
|
||||
chooseSurfaceFormat(formats, windowInfo.pixelFormat);
|
||||
choosePresentMode(modes);
|
||||
createSwapchain();
|
||||
}
|
||||
|
||||
void Window::present()
|
||||
{
|
||||
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
|
||||
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
|
||||
VkPresentInfoKHR info;
|
||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
info.pNext = nullptr;
|
||||
info.swapchainCount = 1;
|
||||
info.pSwapchains = &swapchain;
|
||||
info.pImageIndices = (uint32 *)¤tImageIndex;
|
||||
info.pResults = 0;
|
||||
info.waitSemaphoreCount = 1;
|
||||
info.pWaitSemaphores = &renderFinishedHandle;
|
||||
|
||||
VkResult presentResult = VK_ERROR_OUT_OF_DATE_KHR;
|
||||
// Trial and error
|
||||
while (presentResult != VK_SUCCESS)
|
||||
{
|
||||
presentResult = vkQueuePresentKHR(graphics->getGraphicsCommands()->getQueue()->getHandle(), &info);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::createSwapchain()
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR surfProperties;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(graphics->getPhysicalDevice(), surface, &surfProperties));
|
||||
|
||||
uint32 desiredNumBuffers = Gfx::numFramesBuffered;
|
||||
|
||||
VkExtent2D extent;
|
||||
extent.width = sizeX;
|
||||
extent.height = sizeY;
|
||||
VkSwapchainCreateInfoKHR swapchainInfo =
|
||||
init::SwapchainCreateInfo(
|
||||
surface,
|
||||
desiredNumBuffers,
|
||||
surfaceFormat.format,
|
||||
surfaceFormat.colorSpace,
|
||||
extent,
|
||||
1,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
|
||||
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
presentMode,
|
||||
VK_TRUE);
|
||||
VK_CHECK(vkCreateSwapchainKHR(graphics->getDevice(), &swapchainInfo, nullptr, &swapchain));
|
||||
|
||||
uint32 numSwapchainImages;
|
||||
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, nullptr));
|
||||
Array<VkImage> swapchainImages(numSwapchainImages);
|
||||
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
|
||||
|
||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||
|
||||
for (uint32 i = 0; i < numSwapchainImages; ++i)
|
||||
{
|
||||
imageAcquired[i] = new Semaphore(graphics);
|
||||
renderFinished[i] = new Semaphore(graphics);
|
||||
backBufferImages[i] = new Texture2D(graphics, sizeX, sizeY, false, 1, 1,
|
||||
cast(surfaceFormat.format), 1, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
Gfx::QueueType::GRAPHICS, swapchainImages[i]);
|
||||
|
||||
VkClearColorValue clearColor;
|
||||
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
|
||||
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
|
||||
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
currentImageIndex = -1;
|
||||
}
|
||||
|
||||
void Window::destroySwapchain()
|
||||
{
|
||||
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
|
||||
for (uint32 i = 0; i < Gfx::numFramesBuffered; ++i)
|
||||
{
|
||||
imageAcquired[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred)
|
||||
{
|
||||
VkFormat preferredFormat = cast(preferred);
|
||||
for (auto availabeFormat : available)
|
||||
{
|
||||
if (availabeFormat.format == preferredFormat)
|
||||
{
|
||||
surfaceFormat = availabeFormat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (available.size() == 1 && available[0].format == VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
surfaceFormat = {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
||||
return;
|
||||
}
|
||||
for (const auto &availableFormat : available)
|
||||
{
|
||||
if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||
{
|
||||
surfaceFormat = availableFormat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
surfaceFormat = available[0];
|
||||
}
|
||||
void Window::choosePresentMode(const Array<VkPresentModeKHR> &modes)
|
||||
{
|
||||
for (auto mode : modes)
|
||||
{
|
||||
if (mode == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||
{
|
||||
presentMode = mode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
}
|
||||
|
||||
Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &viewportInfo)
|
||||
: Gfx::Viewport(owner, viewportInfo), graphics(graphics)
|
||||
{
|
||||
}
|
||||
|
||||
Viewport::~Viewport()
|
||||
{
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#include "Window.h"
|
||||
#include "SceneView.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Window::Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphics)
|
||||
: width(createInfo.width)
|
||||
, height(createInfo.height)
|
||||
, graphics(graphics)
|
||||
{
|
||||
center = new Section();
|
||||
center->resizeArea(Rect(1, 1, 0, 0));
|
||||
center->addView(new SceneView(graphics));
|
||||
windowHandle = graphics->createWindow(createInfo);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
}
|
||||
|
||||
void Window::onWindowCloseEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Window::beginFrame()
|
||||
{
|
||||
graphics->beginFrame(windowHandle);
|
||||
center->beginFrame();
|
||||
}
|
||||
|
||||
void Window::endFrame()
|
||||
{
|
||||
graphics->endFrame(windowHandle);
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
#pragma once
|
||||
#include "GraphicsResources.h"
|
||||
#include "View.h"
|
||||
namespace Seele {
|
||||
|
||||
// A window is divided into 5 sections, using a border layout
|
||||
// +--------------TOP------------------+
|
||||
// | |
|
||||
// L R
|
||||
// E I
|
||||
// F CENTER G
|
||||
// T H
|
||||
// | T
|
||||
// +-------------BOTTOM----------------+
|
||||
// In every section, there can be any number
|
||||
// of views, when there are multiple, they stack to tabs
|
||||
class Section
|
||||
{
|
||||
public:
|
||||
Section()
|
||||
{}
|
||||
void resizeArea(Rect area)
|
||||
{
|
||||
this->area = area;
|
||||
}
|
||||
void beginFrame()
|
||||
{
|
||||
views[0]->beginFrame();
|
||||
}
|
||||
void endFrame()
|
||||
{
|
||||
views[0]->endFrame();
|
||||
}
|
||||
void addView(PView view)
|
||||
{
|
||||
view->applyArea(area);
|
||||
views.add(view);
|
||||
}
|
||||
void clearViews(PView view)
|
||||
{
|
||||
views.clear();
|
||||
}
|
||||
void removeView(PView view)
|
||||
{
|
||||
views.remove(views.find(view));
|
||||
}
|
||||
private:
|
||||
Rect area;
|
||||
Array<PView> views;
|
||||
};
|
||||
DEFINE_REF(Section)
|
||||
class Gfx::Graphics;
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphics);
|
||||
~Window();
|
||||
void onWindowCloseEvent();
|
||||
void beginFrame();
|
||||
void endFrame();
|
||||
private:
|
||||
void* windowHandle;
|
||||
PSection center;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(Window)
|
||||
}
|
||||
@@ -6,15 +6,27 @@ Seele::WindowManager::WindowManager()
|
||||
graphics = new Vulkan::Graphics();
|
||||
GraphicsInitializer initializer;
|
||||
graphics->init(initializer);
|
||||
TextureCreateInfo info;
|
||||
info.width = 4096;
|
||||
info.height = 4096;
|
||||
Gfx::PTexture2D testTexture = graphics->createTexture2D(info);
|
||||
BulkResourceData resourceData;
|
||||
resourceData.size = 4096;
|
||||
resourceData.data = new uint8[4096];
|
||||
for (int i = 0; i < 4096; ++i)
|
||||
{
|
||||
resourceData.data[i] = (uint8)i;
|
||||
}
|
||||
Gfx::PUniformBuffer testUniform = graphics->createUniformBuffer(resourceData);
|
||||
}
|
||||
|
||||
Seele::WindowManager::~WindowManager()
|
||||
{
|
||||
}
|
||||
|
||||
void Seele::WindowManager::addWindow(const WindowCreateInfo& createInfo)
|
||||
void Seele::WindowManager::addWindow(const WindowCreateInfo &createInfo)
|
||||
{
|
||||
PWindow window = new Window(createInfo, graphics);
|
||||
Gfx::PWindow window = graphics->createWindow(createInfo);
|
||||
windows.add(window);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
#pragma once
|
||||
#include "GraphicsResources.h"
|
||||
#include "Window.h"
|
||||
#include "Graphics.h"
|
||||
#include "Containers/Array.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class WindowManager
|
||||
class WindowManager
|
||||
{
|
||||
public:
|
||||
WindowManager();
|
||||
~WindowManager();
|
||||
void addWindow(const WindowCreateInfo &createInfo);
|
||||
void beginFrame();
|
||||
void endFrame();
|
||||
inline bool isActive() const
|
||||
{
|
||||
public:
|
||||
WindowManager();
|
||||
~WindowManager();
|
||||
void addWindow(const WindowCreateInfo& createInfo);
|
||||
void beginFrame();
|
||||
void endFrame();
|
||||
inline bool isActive() const
|
||||
{
|
||||
return windows.size();
|
||||
}
|
||||
private:
|
||||
Array<PWindow> windows;
|
||||
Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(WindowManager);
|
||||
}
|
||||
return windows.size();
|
||||
}
|
||||
|
||||
private:
|
||||
Array<Gfx::PWindow> windows;
|
||||
Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(WindowManager);
|
||||
} // namespace Seele
|
||||
+25
-25
@@ -3,30 +3,30 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct Rect
|
||||
struct Rect
|
||||
{
|
||||
Rect()
|
||||
: size(0, 0), offset(0, 0)
|
||||
{
|
||||
Rect()
|
||||
: size(0, 0)
|
||||
, offset(0, 0)
|
||||
{}
|
||||
Rect(float sizeX, float sizeY, float offsetX, float offsetY)
|
||||
: size(sizeX, sizeY)
|
||||
, offset(offsetX, offsetY)
|
||||
{}
|
||||
Rect(Vector2 size, Vector2 offset)
|
||||
: size(size)
|
||||
, offset(offset)
|
||||
{}
|
||||
bool isEmpty() const
|
||||
{
|
||||
return size.x == 0 || size.y == 0;
|
||||
}
|
||||
Vector2 size;
|
||||
Vector2 offset;
|
||||
};
|
||||
struct Rect3D
|
||||
}
|
||||
Rect(float sizeX, float sizeY, float offsetX, float offsetY)
|
||||
: size(sizeX, sizeY), offset(offsetX, offsetY)
|
||||
{
|
||||
Vector3 size;
|
||||
Vector3 offset;
|
||||
};
|
||||
}
|
||||
}
|
||||
Rect(Vector2 size, Vector2 offset)
|
||||
: size(size), offset(offset)
|
||||
{
|
||||
}
|
||||
bool isEmpty() const
|
||||
{
|
||||
return size.x == 0 || size.y == 0;
|
||||
}
|
||||
Vector2 size;
|
||||
Vector2 offset;
|
||||
};
|
||||
struct Rect3D
|
||||
{
|
||||
Vector3 size;
|
||||
Vector3 offset;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -3,8 +3,9 @@
|
||||
#include <glm/mat2x2.hpp>
|
||||
#include <glm/mat3x3.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
namespace Seele {
|
||||
typedef glm::mat2 Matrix2;
|
||||
typedef glm::mat3 Matrix3;
|
||||
typedef glm::mat4 Matrix4;
|
||||
}
|
||||
namespace Seele
|
||||
{
|
||||
typedef glm::mat2 Matrix2;
|
||||
typedef glm::mat3 Matrix3;
|
||||
typedef glm::mat4 Matrix4;
|
||||
} // namespace Seele
|
||||
+177
-194
@@ -2,205 +2,188 @@
|
||||
#include <stdint.h>
|
||||
namespace Seele
|
||||
{
|
||||
static uint32_t CRCTablesSB8[8][256] = {
|
||||
{
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
},
|
||||
{
|
||||
0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
|
||||
0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
|
||||
0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
|
||||
0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
|
||||
0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
|
||||
0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
|
||||
0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
|
||||
0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
|
||||
0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
|
||||
0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
|
||||
0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
|
||||
0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
|
||||
0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
|
||||
0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
|
||||
0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
|
||||
0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72
|
||||
},
|
||||
{
|
||||
0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
|
||||
0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
|
||||
0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
|
||||
0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
|
||||
0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
|
||||
0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
|
||||
0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
|
||||
0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
|
||||
0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
|
||||
0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
|
||||
0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
|
||||
0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
|
||||
0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
|
||||
0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
|
||||
0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
|
||||
0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed
|
||||
},
|
||||
{
|
||||
0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
|
||||
0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
|
||||
0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
|
||||
0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
|
||||
0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
|
||||
0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
|
||||
0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
|
||||
0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
|
||||
0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
|
||||
0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
|
||||
0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
|
||||
0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
|
||||
0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
|
||||
0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
|
||||
0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
|
||||
0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1
|
||||
},
|
||||
{
|
||||
0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, 0x825097d1,
|
||||
0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, 0xdfd029e3, 0xe2b00053,
|
||||
0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5,
|
||||
0xa121b886, 0x9c419136, 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57,
|
||||
0x58f35849, 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
|
||||
0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a,
|
||||
0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, 0x2602c92c, 0x1b62e09c,
|
||||
0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, 0x0142247e, 0x46e25eae, 0x7b82771e,
|
||||
0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743,
|
||||
0xd1062710, 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
|
||||
0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, 0xf2770847,
|
||||
0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5,
|
||||
0xe915e8db, 0xd475c16b, 0x93d5bbbb, 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, 0x11852c6a, 0x562556ba, 0x6b457f0a,
|
||||
0x89f57f59, 0xb49556e9, 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888,
|
||||
0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
|
||||
0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, 0xca64c78c
|
||||
},
|
||||
{
|
||||
0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, 0xf156b2d5,
|
||||
0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, 0x39dc63eb, 0xf280b04e,
|
||||
0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3,
|
||||
0x047a07ad, 0xcf26d408, 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578,
|
||||
0x0f580a6c, 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
|
||||
0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22,
|
||||
0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f,
|
||||
0x0b220dc1, 0xc07ede64, 0x46eaacca, 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14,
|
||||
0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d,
|
||||
0x1d661643, 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
|
||||
0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, 0xe84aa33b,
|
||||
0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0,
|
||||
0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, 0xad760d6a, 0x2be27fc4, 0xe0beac61,
|
||||
0x123e1c2f, 0xd962cf8a, 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa,
|
||||
0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
|
||||
0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, 0xe4c4abcc
|
||||
},
|
||||
{
|
||||
0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, 0xf64870e9,
|
||||
0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, 0x37e1e793, 0x9196ec27,
|
||||
0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975,
|
||||
0xa863a552, 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb,
|
||||
0x440b7579, 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
|
||||
0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e,
|
||||
0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, 0xdb8937b8, 0x7dfe3c0c,
|
||||
0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2,
|
||||
0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b,
|
||||
0xefc8763c, 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
|
||||
0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, 0xb1e3a387,
|
||||
0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49,
|
||||
0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62,
|
||||
0xabc30345, 0x0db408f1, 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac,
|
||||
0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
|
||||
0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, 0x92364a30
|
||||
},
|
||||
{
|
||||
0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, 0xd92012ac,
|
||||
0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, 0x69312319, 0xa59b2387,
|
||||
0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa,
|
||||
0x85cd537d, 0x496753e3, 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1,
|
||||
0x299dc2ed, 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
|
||||
0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a,
|
||||
0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, 0xc561b289, 0x09cbb217,
|
||||
0xac509190, 0x60fa910e, 0xee7596ed, 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, 0x37558441, 0xb9da83a2, 0x7570833c,
|
||||
0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776,
|
||||
0x2f80b4f1, 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
|
||||
0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, 0x736df520,
|
||||
0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b,
|
||||
0x7aa64737, 0xb60c47a9, 0x3883404a, 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, 0xe1a352e6, 0x6f2c5505, 0xa386559b,
|
||||
0x061d761c, 0xcab77682, 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0,
|
||||
0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
|
||||
0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, 0x264b06e6
|
||||
}
|
||||
};
|
||||
static uint32_t CRCTablesSB8[8][256] = {
|
||||
{0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d},
|
||||
{0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
|
||||
0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
|
||||
0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
|
||||
0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
|
||||
0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
|
||||
0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
|
||||
0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
|
||||
0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
|
||||
0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
|
||||
0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
|
||||
0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
|
||||
0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
|
||||
0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
|
||||
0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
|
||||
0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
|
||||
0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72},
|
||||
{0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
|
||||
0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
|
||||
0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
|
||||
0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
|
||||
0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
|
||||
0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
|
||||
0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
|
||||
0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
|
||||
0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
|
||||
0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
|
||||
0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
|
||||
0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
|
||||
0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
|
||||
0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
|
||||
0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
|
||||
0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed},
|
||||
{0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
|
||||
0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
|
||||
0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
|
||||
0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
|
||||
0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
|
||||
0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
|
||||
0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
|
||||
0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
|
||||
0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
|
||||
0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
|
||||
0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
|
||||
0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
|
||||
0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
|
||||
0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
|
||||
0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
|
||||
0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1},
|
||||
{0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, 0x825097d1,
|
||||
0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, 0xdfd029e3, 0xe2b00053,
|
||||
0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5,
|
||||
0xa121b886, 0x9c419136, 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57,
|
||||
0x58f35849, 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
|
||||
0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a,
|
||||
0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, 0x2602c92c, 0x1b62e09c,
|
||||
0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, 0x0142247e, 0x46e25eae, 0x7b82771e,
|
||||
0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743,
|
||||
0xd1062710, 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
|
||||
0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, 0xf2770847,
|
||||
0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5,
|
||||
0xe915e8db, 0xd475c16b, 0x93d5bbbb, 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, 0x11852c6a, 0x562556ba, 0x6b457f0a,
|
||||
0x89f57f59, 0xb49556e9, 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888,
|
||||
0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
|
||||
0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, 0xca64c78c},
|
||||
{0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, 0xf156b2d5,
|
||||
0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, 0x39dc63eb, 0xf280b04e,
|
||||
0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3,
|
||||
0x047a07ad, 0xcf26d408, 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578,
|
||||
0x0f580a6c, 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
|
||||
0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22,
|
||||
0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f,
|
||||
0x0b220dc1, 0xc07ede64, 0x46eaacca, 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14,
|
||||
0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d,
|
||||
0x1d661643, 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
|
||||
0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, 0xe84aa33b,
|
||||
0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0,
|
||||
0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, 0xad760d6a, 0x2be27fc4, 0xe0beac61,
|
||||
0x123e1c2f, 0xd962cf8a, 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa,
|
||||
0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
|
||||
0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, 0xe4c4abcc},
|
||||
{0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, 0xf64870e9,
|
||||
0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, 0x37e1e793, 0x9196ec27,
|
||||
0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975,
|
||||
0xa863a552, 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb,
|
||||
0x440b7579, 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
|
||||
0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e,
|
||||
0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, 0xdb8937b8, 0x7dfe3c0c,
|
||||
0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2,
|
||||
0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b,
|
||||
0xefc8763c, 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
|
||||
0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, 0xb1e3a387,
|
||||
0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49,
|
||||
0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62,
|
||||
0xabc30345, 0x0db408f1, 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac,
|
||||
0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
|
||||
0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, 0x92364a30},
|
||||
{0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, 0xd92012ac,
|
||||
0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, 0x69312319, 0xa59b2387,
|
||||
0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa,
|
||||
0x85cd537d, 0x496753e3, 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1,
|
||||
0x299dc2ed, 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
|
||||
0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a,
|
||||
0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, 0xc561b289, 0x09cbb217,
|
||||
0xac509190, 0x60fa910e, 0xee7596ed, 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, 0x37558441, 0xb9da83a2, 0x7570833c,
|
||||
0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776,
|
||||
0x2f80b4f1, 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
|
||||
0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, 0x736df520,
|
||||
0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b,
|
||||
0x7aa64737, 0xb60c47a9, 0x3883404a, 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, 0xe1a352e6, 0x6f2c5505, 0xa386559b,
|
||||
0x061d761c, 0xcab77682, 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0,
|
||||
0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
|
||||
0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, 0x264b06e6}};
|
||||
|
||||
template<typename T>
|
||||
inline constexpr T align(const T ptr, int64_t alignment)
|
||||
template <typename T>
|
||||
inline constexpr T align(const T ptr, int64_t alignment)
|
||||
{
|
||||
return (T)(((uint64_t)ptr + alignment - 1) & ~(alignment - 1));
|
||||
}
|
||||
|
||||
inline uint32_t memCrc32(const void *InData, int32_t Length, uint32_t CRC = 0)
|
||||
{
|
||||
// Based on the Slicing-by-8 implementation found here:
|
||||
// http://slicing-by-8.sourceforge.net/
|
||||
|
||||
CRC = ~CRC;
|
||||
|
||||
const uint8_t *__restrict Data = (uint8_t *)InData;
|
||||
|
||||
// First we need to align to 32-bits
|
||||
int32_t InitBytes = (int32_t)(align(Data, 4) - Data);
|
||||
|
||||
if (Length > InitBytes)
|
||||
{
|
||||
return (T)(((uint64_t)ptr + alignment - 1) & ~(alignment - 1));
|
||||
}
|
||||
Length -= InitBytes;
|
||||
|
||||
inline uint32_t memCrc32(const void* InData, int32_t Length, uint32_t CRC = 0)
|
||||
{
|
||||
// Based on the Slicing-by-8 implementation found here:
|
||||
// http://slicing-by-8.sourceforge.net/
|
||||
|
||||
CRC = ~CRC;
|
||||
|
||||
const uint8_t* __restrict Data = (uint8_t*)InData;
|
||||
|
||||
// First we need to align to 32-bits
|
||||
int32_t InitBytes = (int32_t)(align(Data, 4) - Data);
|
||||
|
||||
if (Length > InitBytes)
|
||||
{
|
||||
Length -= InitBytes;
|
||||
|
||||
for (; InitBytes; --InitBytes)
|
||||
{
|
||||
CRC = (CRC >> 8) ^ CRCTablesSB8[0][(CRC & 0xFF) ^ *Data++];
|
||||
}
|
||||
|
||||
auto Data4 = (const uint32_t*)Data;
|
||||
for (uint32_t Repeat = Length / 8; Repeat; --Repeat)
|
||||
{
|
||||
uint32_t V1 = *Data4++ ^ CRC;
|
||||
uint32_t V2 = *Data4++;
|
||||
CRC =
|
||||
CRCTablesSB8[7][V1 & 0xFF] ^
|
||||
CRCTablesSB8[6][(V1 >> 8) & 0xFF] ^
|
||||
CRCTablesSB8[5][(V1 >> 16) & 0xFF] ^
|
||||
CRCTablesSB8[4][V1 >> 24] ^
|
||||
CRCTablesSB8[3][V2 & 0xFF] ^
|
||||
CRCTablesSB8[2][(V2 >> 8) & 0xFF] ^
|
||||
CRCTablesSB8[1][(V2 >> 16) & 0xFF] ^
|
||||
CRCTablesSB8[0][V2 >> 24];
|
||||
}
|
||||
Data = (const uint8_t*)Data4;
|
||||
|
||||
Length %= 8;
|
||||
}
|
||||
|
||||
for (; Length; --Length)
|
||||
for (; InitBytes; --InitBytes)
|
||||
{
|
||||
CRC = (CRC >> 8) ^ CRCTablesSB8[0][(CRC & 0xFF) ^ *Data++];
|
||||
}
|
||||
|
||||
return ~CRC;
|
||||
auto Data4 = (const uint32_t *)Data;
|
||||
for (uint32_t Repeat = Length / 8; Repeat; --Repeat)
|
||||
{
|
||||
uint32_t V1 = *Data4++ ^ CRC;
|
||||
uint32_t V2 = *Data4++;
|
||||
CRC =
|
||||
CRCTablesSB8[7][V1 & 0xFF] ^
|
||||
CRCTablesSB8[6][(V1 >> 8) & 0xFF] ^
|
||||
CRCTablesSB8[5][(V1 >> 16) & 0xFF] ^
|
||||
CRCTablesSB8[4][V1 >> 24] ^
|
||||
CRCTablesSB8[3][V2 & 0xFF] ^
|
||||
CRCTablesSB8[2][(V2 >> 8) & 0xFF] ^
|
||||
CRCTablesSB8[1][(V2 >> 16) & 0xFF] ^
|
||||
CRCTablesSB8[0][V2 >> 24];
|
||||
}
|
||||
Data = (const uint8_t *)Data4;
|
||||
|
||||
Length %= 8;
|
||||
}
|
||||
}
|
||||
|
||||
for (; Length; --Length)
|
||||
{
|
||||
CRC = (CRC >> 8) ^ CRCTablesSB8[0][(CRC & 0xFF) ^ *Data++];
|
||||
}
|
||||
|
||||
return ~CRC;
|
||||
}
|
||||
} // namespace Seele
|
||||
+12
-11
@@ -2,16 +2,17 @@
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
namespace Seele {
|
||||
typedef glm::vec2 Vector2;
|
||||
typedef glm::vec3 Vector3;
|
||||
typedef glm::vec4 Vector4;
|
||||
namespace Seele
|
||||
{
|
||||
typedef glm::vec2 Vector2;
|
||||
typedef glm::vec3 Vector3;
|
||||
typedef glm::vec4 Vector4;
|
||||
|
||||
typedef glm::uvec2 UVector2;
|
||||
typedef glm::uvec3 UVector3;
|
||||
typedef glm::uvec4 UVector4;
|
||||
typedef glm::uvec2 UVector2;
|
||||
typedef glm::uvec3 UVector3;
|
||||
typedef glm::uvec4 UVector4;
|
||||
|
||||
typedef glm::ivec2 IVector2;
|
||||
typedef glm::ivec3 IVector3;
|
||||
typedef glm::ivec4 IVector4;
|
||||
}
|
||||
typedef glm::ivec2 IVector2;
|
||||
typedef glm::ivec3 IVector3;
|
||||
typedef glm::ivec4 IVector4;
|
||||
} // namespace Seele
|
||||
@@ -35,15 +35,43 @@ namespace Seele
|
||||
, refCount(rhs.refCount)
|
||||
{
|
||||
}
|
||||
RefObject(RefObject&& rhs)
|
||||
: handle(std::move(rhs.handle))
|
||||
, refCount(std::move(rhs.refCount))
|
||||
{}
|
||||
~RefObject()
|
||||
{
|
||||
registeredObjects.erase(handle);
|
||||
delete handle;
|
||||
}
|
||||
RefObject& operator=(const RefObject& rhs)
|
||||
{
|
||||
if(*this != rhs)
|
||||
{
|
||||
handle = rhs.handle;
|
||||
refCount = rhs.refCount;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
RefObject& operator=(RefObject&& rhs)
|
||||
{
|
||||
if(*this != rhs)
|
||||
{
|
||||
handle = std::move(rhs.handle);
|
||||
refCount = std::move(rhs.refCount);
|
||||
rhs.handle = nullptr;
|
||||
rhs.refCount = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const RefObject& other) const
|
||||
{
|
||||
return handle == other.handle;
|
||||
}
|
||||
bool operator!=(const RefObject& other) const
|
||||
{
|
||||
return handle != other.handle;
|
||||
}
|
||||
bool operator<(const RefObject& other) const
|
||||
{
|
||||
return handle < other.handle;
|
||||
@@ -55,7 +83,7 @@ namespace Seele
|
||||
void removeRef()
|
||||
{
|
||||
refCount--;
|
||||
if (refCount.load() <= 0)
|
||||
if (refCount.load() == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
@@ -102,13 +130,22 @@ namespace Seele
|
||||
RefPtr(const RefPtr& other)
|
||||
: object(other.object)
|
||||
{
|
||||
object->addRef();
|
||||
if(object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
RefPtr(RefPtr&& rhs)
|
||||
: object(std::move(rhs.object))
|
||||
{
|
||||
rhs.object = nullptr;
|
||||
//Dont change references, they stay the same
|
||||
}
|
||||
template<typename F>
|
||||
RefPtr(const RefPtr<F>& other)
|
||||
{
|
||||
F* f = other.getObject()->getHandle();
|
||||
T* t = static_cast<T*>(f);
|
||||
static_cast<T*>(f);
|
||||
object = (RefObject<T>*)other.getObject();
|
||||
object->addRef();
|
||||
}
|
||||
@@ -123,26 +160,57 @@ namespace Seele
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F>* newObject = (RefObject<F>*)object;
|
||||
RefPtr<F> result(newObject);
|
||||
return result;
|
||||
return RefPtr<F>(newObject);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
const RefPtr<F> cast() const
|
||||
{
|
||||
T* t = object->getHandle();
|
||||
F* f = dynamic_cast<F*>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F>* newObject = (RefObject<F>*)object;
|
||||
return RefPtr<F>(newObject);
|
||||
}
|
||||
|
||||
RefPtr& operator=(const RefPtr& other)
|
||||
{
|
||||
if (this != &other)
|
||||
if (*this != other)
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = other.object;
|
||||
object->addRef();
|
||||
if(object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(RefPtr&& rhs)
|
||||
{
|
||||
if(*this != rhs)
|
||||
{
|
||||
if(object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = std::move(rhs.object);
|
||||
rhs.object = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~RefPtr()
|
||||
{
|
||||
object->removeRef();
|
||||
if(object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
}
|
||||
bool operator==(const RefPtr& other) const
|
||||
{
|
||||
@@ -166,6 +234,14 @@ namespace Seele
|
||||
{
|
||||
return object;
|
||||
}
|
||||
T* getHandle()
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
const T* getHandle() const
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
private:
|
||||
RefObject<T>* object;
|
||||
};
|
||||
|
||||
@@ -54,6 +54,8 @@ BOOST_AUTO_TEST_CASE(inheritance_cast)
|
||||
Seele::RefPtr<TestStruct> base = derived;
|
||||
BOOST_REQUIRE_EQUAL(base->data, 10);
|
||||
backCast = base.cast<DerivedStruct>();
|
||||
BOOST_REQUIRE_EQUAL(backCast->data, 10);
|
||||
BOOST_REQUIRE_EQUAL(backCast->data2, 20);
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(backCast->data, 10);
|
||||
BOOST_REQUIRE_EQUAL(backCast->data2, 20);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include "EngineTest.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Vulkan/VulkanGraphics.h"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(DescriptorSets)
|
||||
BOOST_AUTO_TEST_SUITE(Vulkan)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(descriptor_set_merge)
|
||||
BOOST_AUTO_TEST_CASE(init)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user