Basic mutability framework
This commit is contained in:
Vendored
+1
-1
@@ -77,7 +77,7 @@
|
|||||||
"type": "cppvsdbg",
|
"type": "cppvsdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/bin/Debug/Seele_unit_tests.exe",
|
"program": "${workspaceRoot}/bin/Debug/Seele_unit_tests.exe",
|
||||||
"args": [],
|
"args": ["--detect_memory_leaks=15533"],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"console": "internalConsole",
|
"console": "internalConsole",
|
||||||
"cwd": "${workspaceRoot}/bin/Debug",
|
"cwd": "${workspaceRoot}/bin/Debug",
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ add_subdirectory(src/)
|
|||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
set(_CRT_SECURE_NO_WARNINGS)
|
set(_CRT_SECURE_NO_WARNINGS)
|
||||||
target_compile_options(SeeleEngine PRIVATE /DEBUG:FASTLINK /Zi)
|
target_compile_options(SeeleEngine PRIVATE /Zi)
|
||||||
else()
|
else()
|
||||||
target_compile_options(SeeleEngine PRIVATE -g -Wall -Wextra -Wno-delete-incomplete -pedantic -fcoroutines)
|
target_compile_options(SeeleEngine PRIVATE -g -Wall -Wextra -Wno-delete-incomplete -pedantic -fcoroutines)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
"cmakeCommandArgs": "-DUSE_SUPERBUILD=OFF",
|
"cmakeCommandArgs": "-DUSE_SUPERBUILD=OFF",
|
||||||
"buildCommandArgs": "",
|
"buildCommandArgs": "",
|
||||||
"ctestCommandArgs": "",
|
"ctestCommandArgs": "",
|
||||||
"variables": []
|
"inheritEnvironments": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
@@ -9,6 +9,7 @@ Asset::Asset()
|
|||||||
, parentDir("")
|
, parentDir("")
|
||||||
, extension("")
|
, extension("")
|
||||||
, status(Status::Uninitialized)
|
, status(Status::Uninitialized)
|
||||||
|
, byteSize(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Asset::Asset(const std::filesystem::path& path)
|
Asset::Asset(const std::filesystem::path& path)
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ public:
|
|||||||
std::string getExtension() const;
|
std::string getExtension() const;
|
||||||
inline Status getStatus()
|
inline Status getStatus()
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
inline void setStatus(Status status)
|
inline void setStatus(Status status)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
this->status = status;
|
this->status = status;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -25,24 +25,20 @@ MeshAsset::~MeshAsset()
|
|||||||
}
|
}
|
||||||
void MeshAsset::save()
|
void MeshAsset::save()
|
||||||
{
|
{
|
||||||
boost::archive::text_oarchive archive(getWriteStream());
|
|
||||||
archive << meshes;
|
|
||||||
}
|
}
|
||||||
void MeshAsset::load()
|
void MeshAsset::load()
|
||||||
{
|
{
|
||||||
boost::archive::text_iarchive archive(getReadStream());
|
|
||||||
archive >> meshes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshAsset::addMesh(PMesh mesh)
|
void MeshAsset::addMesh(PMesh mesh)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
meshes.add(mesh);
|
meshes.push_back(mesh);
|
||||||
referencedMaterials.add(mesh->referencedMaterial);
|
referencedMaterials.push_back(mesh->referencedMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array<PMesh> MeshAsset::getMeshes()
|
const std::vector<PMesh> MeshAsset::getMeshes()
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
return meshes;
|
return meshes;
|
||||||
}
|
}
|
||||||
@@ -15,11 +15,11 @@ public:
|
|||||||
virtual void save() override;
|
virtual void save() override;
|
||||||
virtual void load() override;
|
virtual void load() override;
|
||||||
void addMesh(PMesh mesh);
|
void addMesh(PMesh mesh);
|
||||||
const Array<PMesh> getMeshes();
|
const std::vector<PMesh> getMeshes();
|
||||||
//Workaround while no editor
|
//Workaround while no editor
|
||||||
Array<PMaterialAsset> referencedMaterials;
|
std::vector<PMaterialAsset> referencedMaterials;
|
||||||
private:
|
private:
|
||||||
Array<PMesh> meshes;
|
std::vector<PMesh> meshes;
|
||||||
};
|
};
|
||||||
DEFINE_REF(MeshAsset)
|
DEFINE_REF(MeshAsset)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -122,7 +122,9 @@ VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gf
|
|||||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||||
vbInfo.resourceData.size = sizeof(Vector) * (uint32)buffer.size();
|
vbInfo.resourceData.size = sizeof(Vector) * (uint32)buffer.size();
|
||||||
return VertexStreamComponent(graphics->createVertexBuffer(vbInfo), 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
|
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||||
|
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
|
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
|
||||||
}
|
}
|
||||||
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
|
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
|
||||||
{
|
{
|
||||||
@@ -137,7 +139,9 @@ VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gf
|
|||||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||||
vbInfo.resourceData.size = sizeof(Vector2) * (uint32)buffer.size();
|
vbInfo.resourceData.size = sizeof(Vector2) * (uint32)buffer.size();
|
||||||
return VertexStreamComponent(graphics->createVertexBuffer(vbInfo), 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||||
|
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
|
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
||||||
}
|
}
|
||||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics)
|
void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ public:
|
|||||||
virtual void load() override;
|
virtual void load() override;
|
||||||
void setTexture(Gfx::PTexture texture)
|
void setTexture(Gfx::PTexture texture)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
this->texture = texture;
|
this->texture = texture;
|
||||||
}
|
}
|
||||||
Gfx::PTexture getTexture()
|
Gfx::PTexture getTexture()
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|||||||
+602
-599
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||||
|
<Type Name="Seele::Array<*>">
|
||||||
|
<DisplayString>{{ size={arraySize} }}</DisplayString>
|
||||||
|
<Expand>
|
||||||
|
<Item Name="[size]" ExcludeView="simple">arraySize</Item>
|
||||||
|
<Item Name="[allocated]" ExcludeView="simple">allocated</Item>
|
||||||
|
<ArrayItems>
|
||||||
|
<Size>arraySize</Size>
|
||||||
|
<ValuePointer>_data</ValuePointer>
|
||||||
|
</ArrayItems>
|
||||||
|
</Type>
|
||||||
|
</AutoVisualizer>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
target_sources(SeeleEngine
|
target_sources(SeeleEngine
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
Array.natvis
|
||||||
Array.h
|
Array.h
|
||||||
Map.h
|
Map.h
|
||||||
List.h)
|
List.h)
|
||||||
@@ -152,15 +152,7 @@ public:
|
|||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
if(root != nullptr)
|
clear();
|
||||||
{
|
|
||||||
delete root;
|
|
||||||
}
|
|
||||||
if(tail != nullptr)
|
|
||||||
{
|
|
||||||
delete tail;
|
|
||||||
}
|
|
||||||
_size = 0;
|
|
||||||
for(const auto& it : other)
|
for(const auto& it : other)
|
||||||
{
|
{
|
||||||
add(it);
|
add(it);
|
||||||
@@ -173,10 +165,7 @@ public:
|
|||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
if(root != nullptr)
|
clear();
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
root = other.root;
|
root = other.root;
|
||||||
tail = other.tail;
|
tail = other.tail;
|
||||||
beginIt = other.beginIt;
|
beginIt = other.beginIt;
|
||||||
@@ -205,6 +194,7 @@ public:
|
|||||||
for (Node *tmp = root; tmp != tail;)
|
for (Node *tmp = root; tmp != tail;)
|
||||||
{
|
{
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
|
destroyNode(tmp->prev);
|
||||||
deallocateNode(tmp->prev);
|
deallocateNode(tmp->prev);
|
||||||
}
|
}
|
||||||
deallocateNode(tail);
|
deallocateNode(tail);
|
||||||
@@ -216,43 +206,16 @@ public:
|
|||||||
//Insert at the end
|
//Insert at the end
|
||||||
iterator add(const T &value)
|
iterator add(const T &value)
|
||||||
{
|
{
|
||||||
if (root == nullptr)
|
return addInternal(value);
|
||||||
{
|
|
||||||
root = allocateNode();
|
|
||||||
tail = root;
|
|
||||||
}
|
|
||||||
initializeNode(tail, value);
|
|
||||||
Node *newTail = allocateNode();
|
|
||||||
newTail->prev = tail;
|
|
||||||
newTail->next = nullptr;
|
|
||||||
tail->next = newTail;
|
|
||||||
iterator insertedElement(tail);
|
|
||||||
tail = newTail;
|
|
||||||
markIteratorDirty();
|
|
||||||
_size++;
|
|
||||||
return insertedElement;
|
|
||||||
}
|
}
|
||||||
iterator add(T&& value)
|
iterator add(T&& value)
|
||||||
{
|
{
|
||||||
if (root == nullptr)
|
return addInternal(std::move(value));
|
||||||
{
|
|
||||||
root = allocateNode();
|
|
||||||
tail = root;
|
|
||||||
}
|
|
||||||
initializeNode(tail, std::move(value));
|
|
||||||
Node *newTail = allocateNode();
|
|
||||||
newTail->prev = tail;
|
|
||||||
newTail->next = nullptr;
|
|
||||||
tail->next = newTail;
|
|
||||||
Iterator insertedElement(tail);
|
|
||||||
tail = newTail;
|
|
||||||
markIteratorDirty();
|
|
||||||
_size++;
|
|
||||||
return insertedElement;
|
|
||||||
}
|
}
|
||||||
// takes all elements from other and move-inserts them into
|
// takes all elements from other and move-inserts them into
|
||||||
// this, clearing other in the process
|
// this, clearing other in the process
|
||||||
void moveElements(List& other){
|
void moveElements(List& other)
|
||||||
|
{
|
||||||
tail->prev->next = other.root;
|
tail->prev->next = other.root;
|
||||||
other.root->prev = tail->prev;
|
other.root->prev = tail->prev;
|
||||||
_size += other._size;
|
_size += other._size;
|
||||||
@@ -309,12 +272,13 @@ public:
|
|||||||
}
|
}
|
||||||
if(next == nullptr)
|
if(next == nullptr)
|
||||||
{
|
{
|
||||||
root = prev;
|
tail = prev;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
next->prev = prev;
|
next->prev = prev;
|
||||||
}
|
}
|
||||||
|
destroyNode(pos.node);
|
||||||
deallocateNode(pos.node);
|
deallocateNode(pos.node);
|
||||||
markIteratorDirty();
|
markIteratorDirty();
|
||||||
return Iterator(next);
|
return Iterator(next);
|
||||||
@@ -408,10 +372,33 @@ private:
|
|||||||
node->next,
|
node->next,
|
||||||
std::forward<Type>(data));
|
std::forward<Type>(data));
|
||||||
}
|
}
|
||||||
|
void destroyNode(Node* node)
|
||||||
|
{
|
||||||
|
std::allocator_traits<NodeAllocator>::destroy(allocator, node);
|
||||||
|
}
|
||||||
void deallocateNode(Node* node)
|
void deallocateNode(Node* node)
|
||||||
{
|
{
|
||||||
allocator.deallocate(node, 1);
|
allocator.deallocate(node, 1);
|
||||||
}
|
}
|
||||||
|
template<typename ValueType>
|
||||||
|
iterator addInternal(ValueType&& value)
|
||||||
|
{
|
||||||
|
if (root == nullptr)
|
||||||
|
{
|
||||||
|
root = allocateNode();
|
||||||
|
tail = root;
|
||||||
|
}
|
||||||
|
initializeNode(tail, std::forward<ValueType>(value));
|
||||||
|
Node* newTail = allocateNode();
|
||||||
|
newTail->prev = tail;
|
||||||
|
newTail->next = nullptr;
|
||||||
|
tail->next = newTail;
|
||||||
|
Iterator insertedElement(tail);
|
||||||
|
tail = newTail;
|
||||||
|
markIteratorDirty();
|
||||||
|
_size++;
|
||||||
|
return insertedElement;
|
||||||
|
}
|
||||||
void markIteratorDirty()
|
void markIteratorDirty()
|
||||||
{
|
{
|
||||||
beginIt = Iterator(root);
|
beginIt = Iterator(root);
|
||||||
@@ -421,10 +408,10 @@ private:
|
|||||||
}
|
}
|
||||||
Node *root;
|
Node *root;
|
||||||
Node *tail;
|
Node *tail;
|
||||||
Iterator beginIt;
|
iterator beginIt;
|
||||||
Iterator endIt;
|
iterator endIt;
|
||||||
ConstIterator cbeginIt;
|
const_iterator cbeginIt;
|
||||||
ConstIterator cendIt;
|
const_iterator cendIt;
|
||||||
size_type _size;
|
size_type _size;
|
||||||
NodeAllocator allocator;
|
NodeAllocator allocator;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
|
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
|
||||||
|
|
||||||
virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
||||||
virtual PPipelineLayout createPipelineLayout() = 0;
|
virtual PPipelineLayout createPipelineLayout(PPipelineLayout baseLayout = nullptr) = 0;
|
||||||
|
|
||||||
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) = 0;
|
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -22,20 +22,13 @@ struct GraphicsInitializer
|
|||||||
GraphicsInitializer()
|
GraphicsInitializer()
|
||||||
: applicationName("SeeleEngine")
|
: applicationName("SeeleEngine")
|
||||||
, engineName("SeeleEngine")
|
, engineName("SeeleEngine")
|
||||||
|
, windowLayoutFile(nullptr)
|
||||||
, layers{"VK_LAYER_KHRONOS_validation", "VK_LAYER_LUNARG_monitor"}
|
, layers{"VK_LAYER_KHRONOS_validation", "VK_LAYER_LUNARG_monitor"}
|
||||||
, instanceExtensions{}
|
, instanceExtensions{}
|
||||||
, deviceExtensions{"VK_KHR_swapchain"}
|
, deviceExtensions{"VK_KHR_swapchain"}
|
||||||
, windowHandle(nullptr)
|
, windowHandle(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
GraphicsInitializer(const GraphicsInitializer &other)
|
|
||||||
: applicationName(other.applicationName)
|
|
||||||
, engineName(other.engineName)
|
|
||||||
, layers(other.layers)
|
|
||||||
, instanceExtensions(other.instanceExtensions)
|
|
||||||
, deviceExtensions(other.deviceExtensions)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct WindowCreateInfo
|
struct WindowCreateInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ ShaderCollection& ShaderMap::createShaders(
|
|||||||
VertexInputType* vertexInput,
|
VertexInputType* vertexInput,
|
||||||
bool /*bPositionOnly*/)
|
bool /*bPositionOnly*/)
|
||||||
{
|
{
|
||||||
|
std::scoped_lock lock(shadersLock);
|
||||||
ShaderCollection& collection = shaders.add();
|
ShaderCollection& collection = shaders.add();
|
||||||
//collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
|
//collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
|
||||||
|
|
||||||
@@ -107,7 +108,7 @@ void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorTyp
|
|||||||
|
|
||||||
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
|
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(allocatorLock);
|
std::scoped_lock lock(allocatorLock);
|
||||||
PDescriptorSet result;
|
PDescriptorSet result;
|
||||||
allocator->allocateDescriptorSet(result);
|
allocator->allocateDescriptorSet(result);
|
||||||
return result;
|
return result;
|
||||||
@@ -115,7 +116,7 @@ PDescriptorSet DescriptorLayout::allocateDescriptorSet()
|
|||||||
|
|
||||||
void DescriptorLayout::reset()
|
void DescriptorLayout::reset()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(allocatorLock);
|
std::scoped_lock lock(allocatorLock);
|
||||||
allocator->reset();
|
allocator->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +271,7 @@ static Map<uint32, PVertexDeclaration> vertexDeclarationCache;
|
|||||||
|
|
||||||
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList)
|
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(vertexDeclarationLock);
|
std::scoped_lock lock(vertexDeclarationLock);
|
||||||
boost::crc_32_type result;
|
boost::crc_32_type result;
|
||||||
result.process_bytes(&elementList, sizeof(VertexElement) * elementList.size());
|
result.process_bytes(&elementList, sizeof(VertexElement) * elementList.size());
|
||||||
uint32 key = result.checksum();
|
uint32 key = result.checksum();
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ public:
|
|||||||
VertexInputType* vertexInput,
|
VertexInputType* vertexInput,
|
||||||
bool bPositionOnly);
|
bool bPositionOnly);
|
||||||
private:
|
private:
|
||||||
|
std::mutex shadersLock;
|
||||||
Array<ShaderCollection> shaders;
|
Array<ShaderCollection> shaders;
|
||||||
};
|
};
|
||||||
DEFINE_REF(ShaderMap)
|
DEFINE_REF(ShaderMap)
|
||||||
@@ -242,7 +243,14 @@ DEFINE_REF(DescriptorLayout)
|
|||||||
class PipelineLayout
|
class PipelineLayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PipelineLayout() {}
|
PipelineLayout(PPipelineLayout baseLayout)
|
||||||
|
{
|
||||||
|
if(baseLayout != nullptr)
|
||||||
|
{
|
||||||
|
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
|
||||||
|
pushConstants = baseLayout->pushConstants;
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual ~PipelineLayout() {}
|
virtual ~PipelineLayout() {}
|
||||||
virtual void create() = 0;
|
virtual void create() = 0;
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
|
|||||||
@@ -15,11 +15,6 @@ public:
|
|||||||
PVertexShaderInput vertexInput;
|
PVertexShaderInput vertexInput;
|
||||||
PMaterialAsset referencedMaterial;
|
PMaterialAsset referencedMaterial;
|
||||||
private:
|
private:
|
||||||
friend class boost::serialization::access;
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive&, const unsigned int)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
DEFINE_REF(Mesh)
|
DEFINE_REF(Mesh)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -24,5 +24,6 @@ MeshBatch::MeshBatch()
|
|||||||
, topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
, topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
||||||
, vertexInput(nullptr)
|
, vertexInput(nullptr)
|
||||||
, material(nullptr)
|
, material(nullptr)
|
||||||
|
, elements()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
};
|
};
|
||||||
struct MeshBatch
|
struct MeshBatch
|
||||||
{
|
{
|
||||||
Array<MeshBatchElement> elements;
|
std::vector<MeshBatchElement> elements;
|
||||||
|
|
||||||
uint8 useReverseCulling : 1;
|
uint8 useReverseCulling : 1;
|
||||||
uint8 isBackfaceCullingDisabled : 1;
|
uint8 isBackfaceCullingDisabled : 1;
|
||||||
@@ -68,6 +68,10 @@ struct MeshBatch
|
|||||||
}
|
}
|
||||||
|
|
||||||
MeshBatch();
|
MeshBatch();
|
||||||
|
MeshBatch(const MeshBatch& other) = default;
|
||||||
|
MeshBatch(MeshBatch&& other) = default;
|
||||||
|
MeshBatch& operator=(const MeshBatch& other) = default;
|
||||||
|
MeshBatch& operator=(MeshBatch&& other) = default;
|
||||||
};
|
};
|
||||||
DECLARE_REF(PrimitiveComponent)
|
DECLARE_REF(PrimitiveComponent)
|
||||||
struct StaticMeshBatch : public MeshBatch
|
struct StaticMeshBatch : public MeshBatch
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ BasePassMeshProcessor::~BasePassMeshProcessor()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePassMeshProcessor::processMeshBatch(
|
Job BasePassMeshProcessor::processMeshBatch(
|
||||||
const MeshBatch& batch,
|
const MeshBatch& batch,
|
||||||
// const PPrimitiveComponent primitiveComponent,
|
// const PPrimitiveComponent primitiveComponent,
|
||||||
const Gfx::PRenderPass& renderPass,
|
const Gfx::PRenderPass& renderPass,
|
||||||
Gfx::PPipelineLayout pipelineLayout,
|
Gfx::PPipelineLayout baseLayout,
|
||||||
Gfx::PDescriptorLayout primitiveLayout,
|
Gfx::PDescriptorLayout primitiveLayout,
|
||||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||||
int32 /*staticMeshId*/)
|
int32 /*staticMeshId*/)
|
||||||
@@ -40,6 +40,7 @@ void BasePassMeshProcessor::processMeshBatch(
|
|||||||
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
|
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
|
||||||
renderCommand->setViewport(target);
|
renderCommand->setViewport(target);
|
||||||
|
|
||||||
|
Gfx::PPipelineLayout pipelineLayout = graphics->createPipelineLayout(baseLayout);
|
||||||
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout());
|
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout());
|
||||||
pipelineLayout->create();
|
pipelineLayout->create();
|
||||||
Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
|
Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
|
||||||
@@ -63,9 +64,9 @@ void BasePassMeshProcessor::processMeshBatch(
|
|||||||
collection->fragmentShader,
|
collection->fragmentShader,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
std::unique_lock lock(commandLock);
|
std::scoped_lock lock(commandLock);
|
||||||
renderCommands.add(renderCommand);
|
renderCommands.add(renderCommand);
|
||||||
//co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
|
BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
|
||||||
@@ -157,7 +158,7 @@ MainJob BasePass::render()
|
|||||||
for (auto &&meshBatch : passData.staticDrawList)
|
for (auto &&meshBatch : passData.staticDrawList)
|
||||||
{
|
{
|
||||||
//jobs.add(
|
//jobs.add(
|
||||||
processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets);
|
co_await processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets);
|
||||||
}
|
}
|
||||||
//co_await Job::all(jobs);
|
//co_await Job::all(jobs);
|
||||||
graphics->executeCommands(processor->getRenderCommands());
|
graphics->executeCommands(processor->getRenderCommands());
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public:
|
|||||||
BasePassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass);
|
BasePassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass);
|
||||||
virtual ~BasePassMeshProcessor();
|
virtual ~BasePassMeshProcessor();
|
||||||
|
|
||||||
virtual void processMeshBatch(
|
virtual Job processMeshBatch(
|
||||||
const MeshBatch& batch,
|
const MeshBatch& batch,
|
||||||
// const PPrimitiveComponent primitiveComponent,
|
// const PPrimitiveComponent primitiveComponent,
|
||||||
const Gfx::PRenderPass& renderPass,
|
const Gfx::PRenderPass& renderPass,
|
||||||
@@ -30,7 +30,7 @@ DECLARE_REF(CameraActor)
|
|||||||
DECLARE_REF(CameraComponent)
|
DECLARE_REF(CameraComponent)
|
||||||
struct BasePassData
|
struct BasePassData
|
||||||
{
|
{
|
||||||
Array<StaticMeshBatch> staticDrawList;
|
std::vector<StaticMeshBatch> staticDrawList;
|
||||||
};
|
};
|
||||||
class BasePass : public RenderPass<BasePassData>
|
class BasePass : public RenderPass<BasePassData>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ DepthPrepassMeshProcessor::~DepthPrepassMeshProcessor()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepassMeshProcessor::processMeshBatch(
|
Job DepthPrepassMeshProcessor::processMeshBatch(
|
||||||
const MeshBatch& batch,
|
const MeshBatch& batch,
|
||||||
// const PPrimitiveComponent primitiveComponent,
|
// const PPrimitiveComponent primitiveComponent,
|
||||||
const Gfx::PRenderPass& renderPass,
|
const Gfx::PRenderPass& renderPass,
|
||||||
Gfx::PPipelineLayout pipelineLayout,
|
Gfx::PPipelineLayout baseLayout,
|
||||||
Gfx::PDescriptorLayout primitiveLayout,
|
Gfx::PDescriptorLayout primitiveLayout,
|
||||||
Array<Gfx::PDescriptorSet> descriptorSets,
|
Array<Gfx::PDescriptorSet> descriptorSets,
|
||||||
int32 /*staticMeshId*/)
|
int32 /*staticMeshId*/)
|
||||||
@@ -38,6 +38,7 @@ void DepthPrepassMeshProcessor::processMeshBatch(
|
|||||||
|
|
||||||
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
|
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
|
||||||
renderCommand->setViewport(target);
|
renderCommand->setViewport(target);
|
||||||
|
Gfx::PPipelineLayout pipelineLayout = graphics->createPipelineLayout(baseLayout);
|
||||||
pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getDescriptorLayout());
|
pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getDescriptorLayout());
|
||||||
pipelineLayout->create();
|
pipelineLayout->create();
|
||||||
Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
|
Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
|
||||||
@@ -61,10 +62,10 @@ void DepthPrepassMeshProcessor::processMeshBatch(
|
|||||||
collection->fragmentShader,
|
collection->fragmentShader,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
std::unique_lock lock(commandLock);
|
std::scoped_lock lock(commandLock);
|
||||||
renderCommands.add(renderCommand);
|
renderCommands.add(renderCommand);
|
||||||
//std::cout << "Finished depth job" << std::endl;
|
//std::cout << "Finished depth job" << std::endl;
|
||||||
//co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
|
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
|
||||||
@@ -128,10 +129,9 @@ MainJob DepthPrepass::render()
|
|||||||
for (auto &&meshBatch : passData.staticDrawList)
|
for (auto &&meshBatch : passData.staticDrawList)
|
||||||
{
|
{
|
||||||
//jobs.add(
|
//jobs.add(
|
||||||
processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets);
|
co_await processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets);
|
||||||
}
|
}
|
||||||
//co_await Job::all(jobs);
|
//co_await Job::all(jobs);
|
||||||
//std::cout << "Finished waiting depth jobs " << std::endl;
|
|
||||||
graphics->executeCommands(processor->getRenderCommands());
|
graphics->executeCommands(processor->getRenderCommands());
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
co_return;
|
co_return;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public:
|
|||||||
DepthPrepassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics);
|
DepthPrepassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics);
|
||||||
virtual ~DepthPrepassMeshProcessor();
|
virtual ~DepthPrepassMeshProcessor();
|
||||||
|
|
||||||
virtual void processMeshBatch(
|
virtual Job processMeshBatch(
|
||||||
const MeshBatch& batch,
|
const MeshBatch& batch,
|
||||||
const Gfx::PRenderPass& renderPass,
|
const Gfx::PRenderPass& renderPass,
|
||||||
Gfx::PPipelineLayout pipelineLayout,
|
Gfx::PPipelineLayout pipelineLayout,
|
||||||
@@ -27,7 +27,7 @@ DECLARE_REF(CameraActor)
|
|||||||
DECLARE_REF(CameraComponent)
|
DECLARE_REF(CameraComponent)
|
||||||
struct DepthPrepassData
|
struct DepthPrepassData
|
||||||
{
|
{
|
||||||
Array<StaticMeshBatch> staticDrawList;
|
std::vector<StaticMeshBatch> staticDrawList;
|
||||||
};
|
};
|
||||||
class DepthPrepass : public RenderPass<DepthPrepassData>
|
class DepthPrepass : public RenderPass<DepthPrepassData>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "MeshProcessor.h"
|
#include "MeshProcessor.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Graphics/VertexShaderInput.h"
|
#include "Graphics/VertexShaderInput.h"
|
||||||
|
#include "Graphics/Vulkan/VulkanGraphicsResources.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -32,8 +33,6 @@ void MeshProcessor::buildMeshDrawCommand(
|
|||||||
|
|
||||||
GraphicsPipelineCreateInfo pipelineInitializer;
|
GraphicsPipelineCreateInfo pipelineInitializer;
|
||||||
pipelineInitializer.topology = meshBatch.topology;
|
pipelineInitializer.topology = meshBatch.topology;
|
||||||
Gfx::PVertexDeclaration vertexDecl = positionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
|
|
||||||
pipelineInitializer.vertexDeclaration = vertexDecl;
|
|
||||||
pipelineInitializer.vertexShader = vertexShader;
|
pipelineInitializer.vertexShader = vertexShader;
|
||||||
pipelineInitializer.controlShader = controlShader;
|
pipelineInitializer.controlShader = controlShader;
|
||||||
pipelineInitializer.evalShader = evaluationShader;
|
pipelineInitializer.evalShader = evaluationShader;
|
||||||
@@ -46,10 +45,12 @@ void MeshProcessor::buildMeshDrawCommand(
|
|||||||
if(positionOnly)
|
if(positionOnly)
|
||||||
{
|
{
|
||||||
vertexInput->getPositionOnlyStream(vertexStreams);
|
vertexInput->getPositionOnlyStream(vertexStreams);
|
||||||
|
pipelineInitializer.vertexDeclaration = vertexInput->getPositionDeclaration();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vertexInput->getStreams(vertexStreams);
|
vertexInput->getStreams(vertexStreams);
|
||||||
|
pipelineInitializer.vertexDeclaration = vertexInput->getDeclaration();
|
||||||
}
|
}
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInitializer);
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInitializer);
|
||||||
drawCommand->bindPipeline(pipeline);
|
drawCommand->bindPipeline(pipeline);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
PScene scene;
|
PScene scene;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
virtual void processMeshBatch(
|
virtual Job processMeshBatch(
|
||||||
const MeshBatch& batch,
|
const MeshBatch& batch,
|
||||||
// const PPrimitiveComponent primitiveComponent,
|
// const PPrimitiveComponent primitiveComponent,
|
||||||
const Gfx::PRenderPass& renderPass,
|
const Gfx::PRenderPass& renderPass,
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void GpuCrashTracker::Initialize()
|
|||||||
void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize)
|
void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize)
|
||||||
{
|
{
|
||||||
// Make sure only one thread at a time...
|
// Make sure only one thread at a time...
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::scoped_lock<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
// Write to file for later in-depth analysis with Nsight Graphics.
|
// Write to file for later in-depth analysis with Nsight Graphics.
|
||||||
WriteGpuCrashDumpToFile(pGpuCrashDump, gpuCrashDumpSize);
|
WriteGpuCrashDumpToFile(pGpuCrashDump, gpuCrashDumpSize);
|
||||||
@@ -87,7 +87,7 @@ void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuC
|
|||||||
void GpuCrashTracker::OnShaderDebugInfo(const void* pShaderDebugInfo, const uint32_t shaderDebugInfoSize)
|
void GpuCrashTracker::OnShaderDebugInfo(const void* pShaderDebugInfo, const uint32_t shaderDebugInfoSize)
|
||||||
{
|
{
|
||||||
// Make sure only one thread at a time...
|
// Make sure only one thread at a time...
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::scoped_lock<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
// Get shader debug information identifier
|
// Get shader debug information identifier
|
||||||
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {};
|
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {};
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ Allocation::~Allocation()
|
|||||||
|
|
||||||
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
|
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
if (isDedicated)
|
if (isDedicated)
|
||||||
{
|
{
|
||||||
if (activeAllocations.empty() && requestedSize == bytesAllocated)
|
if (activeAllocations.empty() && requestedSize == bytesAllocated)
|
||||||
@@ -134,7 +134,7 @@ void Allocation::markFree(SubAllocation *allocation)
|
|||||||
PSubAllocation freeRangeToDelete;
|
PSubAllocation freeRangeToDelete;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
//Join lower bound
|
//Join lower bound
|
||||||
for (auto freeRange : freeRanges)
|
for (auto freeRange : freeRanges)
|
||||||
{
|
{
|
||||||
@@ -204,7 +204,7 @@ Allocator::Allocator(PGraphics graphics)
|
|||||||
|
|
||||||
Allocator::~Allocator()
|
Allocator::~Allocator()
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
for (auto heap : heaps)
|
for (auto heap : heaps)
|
||||||
{
|
{
|
||||||
for (auto alloc : heap.allocations)
|
for (auto alloc : heap.allocations)
|
||||||
@@ -219,7 +219,7 @@ Allocator::~Allocator()
|
|||||||
|
|
||||||
PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
|
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
|
||||||
uint8 memoryTypeIndex;
|
uint8 memoryTypeIndex;
|
||||||
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
|
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
|
||||||
@@ -252,7 +252,7 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
|
|||||||
|
|
||||||
void Allocator::free(Allocation *allocation)
|
void Allocator::free(Allocation *allocation)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(lock);
|
std::scoped_lock lck(lock);
|
||||||
for (auto heap : heaps)
|
for (auto heap : heaps)
|
||||||
{
|
{
|
||||||
for (uint32 i = 0; i < heap.allocations.size(); ++i)
|
for (uint32 i = 0; i < heap.allocations.size(); ++i)
|
||||||
@@ -307,7 +307,7 @@ void StagingManager::clearPending()
|
|||||||
|
|
||||||
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
|
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
|
||||||
{
|
{
|
||||||
std::unique_lock l(lock);
|
std::scoped_lock l(lock);
|
||||||
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||||
{
|
{
|
||||||
auto freeBuffer = *it;
|
auto freeBuffer = *it;
|
||||||
@@ -323,6 +323,9 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
|
|||||||
PStagingBuffer stagingBuffer = new StagingBuffer();
|
PStagingBuffer stagingBuffer = new StagingBuffer();
|
||||||
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
|
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
|
||||||
stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||||
|
stagingBufferCreateInfo.queueFamilyIndexCount = 1;
|
||||||
|
stagingBufferCreateInfo.pQueueFamilyIndices = &queueIndex;
|
||||||
VkDevice vulkanDevice = graphics->getDevice();
|
VkDevice vulkanDevice = graphics->getDevice();
|
||||||
|
|
||||||
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer));
|
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer));
|
||||||
@@ -355,7 +358,7 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
|
|||||||
|
|
||||||
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
|
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
|
||||||
{
|
{
|
||||||
std::unique_lock l(lock);
|
std::scoped_lock l(lock);
|
||||||
freeBuffers.add(buffer);
|
freeBuffers.add(buffer);
|
||||||
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
|
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
|
||||||
}
|
}
|
||||||
@@ -10,277 +10,277 @@ using namespace Seele::Vulkan;
|
|||||||
|
|
||||||
struct PendingBuffer
|
struct PendingBuffer
|
||||||
{
|
{
|
||||||
PStagingBuffer stagingBuffer;
|
PStagingBuffer stagingBuffer;
|
||||||
Gfx::QueueType prevQueue;
|
Gfx::QueueType prevQueue;
|
||||||
bool bWriteOnly;
|
bool bWriteOnly;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
||||||
|
|
||||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
|
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
|
||||||
: graphics(graphics)
|
: graphics(graphics)
|
||||||
, currentBuffer(0)
|
, currentBuffer(0)
|
||||||
, size(size)
|
, size(size)
|
||||||
, owner(queueType)
|
, owner(queueType)
|
||||||
{
|
{
|
||||||
if(bDynamic)
|
if(bDynamic)
|
||||||
{
|
{
|
||||||
numBuffers = Gfx::numFramesBuffered;
|
numBuffers = Gfx::numFramesBuffered;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
numBuffers = 1;
|
numBuffers = 1;
|
||||||
}
|
}
|
||||||
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||||
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
VkBufferCreateInfo info =
|
VkBufferCreateInfo info =
|
||||||
init::BufferCreateInfo(
|
init::BufferCreateInfo(
|
||||||
usage,
|
usage,
|
||||||
size);
|
size);
|
||||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
uint32 queueFamilyIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(queueType);
|
uint32 queueFamilyIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(queueType);
|
||||||
info.pQueueFamilyIndices = &queueFamilyIndex;
|
info.pQueueFamilyIndices = &queueFamilyIndex;
|
||||||
info.queueFamilyIndexCount = 0;
|
info.queueFamilyIndexCount = 1;
|
||||||
VkBufferMemoryRequirementsInfo2 bufferReqInfo;
|
VkBufferMemoryRequirementsInfo2 bufferReqInfo;
|
||||||
bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
||||||
bufferReqInfo.pNext = nullptr;
|
bufferReqInfo.pNext = nullptr;
|
||||||
VkMemoryDedicatedRequirements dedicatedRequirements;
|
VkMemoryDedicatedRequirements dedicatedRequirements;
|
||||||
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
||||||
dedicatedRequirements.pNext = nullptr;
|
dedicatedRequirements.pNext = nullptr;
|
||||||
VkMemoryRequirements2 memRequirements;
|
VkMemoryRequirements2 memRequirements;
|
||||||
memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||||
memRequirements.pNext = &dedicatedRequirements;
|
memRequirements.pNext = &dedicatedRequirements;
|
||||||
for (uint32 i = 0; i < numBuffers; ++i)
|
for (uint32 i = 0; i < numBuffers; ++i)
|
||||||
{
|
{
|
||||||
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer));
|
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer));
|
||||||
bufferReqInfo.buffer = buffers[i].buffer;
|
bufferReqInfo.buffer = buffers[i].buffer;
|
||||||
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
|
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
|
||||||
auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
|
auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
|
||||||
buffers[i].allocation = temp;
|
buffers[i].allocation = temp;
|
||||||
vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset());
|
vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderBuffer::~ShaderBuffer()
|
ShaderBuffer::~ShaderBuffer()
|
||||||
{
|
{
|
||||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||||
VkDevice device = graphics->getDevice();
|
VkDevice device = graphics->getDevice();
|
||||||
auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> Job
|
auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> Job
|
||||||
{
|
{
|
||||||
//co_await cmdBuffer->asyncWait();
|
//co_await cmdBuffer->asyncWait();
|
||||||
//vkDestroyBuffer(device, buffer, nullptr);
|
//vkDestroyBuffer(device, buffer, nullptr);
|
||||||
co_return;
|
co_return;
|
||||||
};
|
};
|
||||||
for (uint32 i = 0; i < numBuffers; ++i)
|
for (uint32 i = 0; i < numBuffers; ++i)
|
||||||
{
|
{
|
||||||
deletionLambda(buffers[i].buffer);
|
deletionLambda(buffers[i].buffer);
|
||||||
buffers[i].allocation = nullptr;
|
buffers[i].allocation = nullptr;
|
||||||
}
|
}
|
||||||
graphics = nullptr;
|
graphics = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDeviceSize ShaderBuffer::getOffset() const
|
VkDeviceSize ShaderBuffer::getOffset() const
|
||||||
{
|
{
|
||||||
return buffers[currentBuffer].allocation->getOffset();
|
return buffers[currentBuffer].allocation->getOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
VkBufferMemoryBarrier barrier =
|
VkBufferMemoryBarrier barrier =
|
||||||
init::BufferMemoryBarrier();
|
init::BufferMemoryBarrier();
|
||||||
PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
|
PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
|
||||||
PCommandBufferManager dstManager = nullptr;
|
PCommandBufferManager dstManager = nullptr;
|
||||||
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||||
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||||
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
||||||
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
|
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
|
||||||
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
|
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
|
||||||
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
||||||
if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
|
if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||||
{
|
{
|
||||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
}
|
}
|
||||||
else if (owner == Gfx::QueueType::COMPUTE)
|
else if (owner == Gfx::QueueType::COMPUTE)
|
||||||
{
|
{
|
||||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
}
|
}
|
||||||
else if (owner == Gfx::QueueType::GRAPHICS)
|
else if (owner == Gfx::QueueType::GRAPHICS)
|
||||||
{
|
{
|
||||||
barrier.srcAccessMask = getSourceAccessMask();
|
barrier.srcAccessMask = getSourceAccessMask();
|
||||||
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||||
}
|
}
|
||||||
if (newOwner == Gfx::QueueType::TRANSFER)
|
if (newOwner == Gfx::QueueType::TRANSFER)
|
||||||
{
|
{
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
dstManager = graphics->getTransferCommands();
|
dstManager = graphics->getTransferCommands();
|
||||||
}
|
}
|
||||||
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||||
{
|
{
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
dstManager = graphics->getDedicatedTransferCommands();
|
dstManager = graphics->getDedicatedTransferCommands();
|
||||||
}
|
}
|
||||||
else if (newOwner == Gfx::QueueType::COMPUTE)
|
else if (newOwner == Gfx::QueueType::COMPUTE)
|
||||||
{
|
{
|
||||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
dstManager = graphics->getComputeCommands();
|
dstManager = graphics->getComputeCommands();
|
||||||
}
|
}
|
||||||
else if (newOwner == Gfx::QueueType::GRAPHICS)
|
else if (newOwner == Gfx::QueueType::GRAPHICS)
|
||||||
{
|
{
|
||||||
barrier.dstAccessMask = getDestAccessMask();
|
barrier.dstAccessMask = getDestAccessMask();
|
||||||
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||||
dstManager = graphics->getGraphicsCommands();
|
dstManager = graphics->getGraphicsCommands();
|
||||||
}
|
}
|
||||||
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
|
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
|
||||||
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
|
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
|
||||||
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
||||||
barrier.offset = 0;
|
barrier.offset = 0;
|
||||||
barrier.size = size;
|
barrier.size = size;
|
||||||
for (uint32 i = 0; i < numBuffers; ++i)
|
for (uint32 i = 0; i < numBuffers; ++i)
|
||||||
{
|
{
|
||||||
dynamicBarriers[i] = barrier;
|
dynamicBarriers[i] = barrier;
|
||||||
dynamicBarriers[i].buffer = buffers[i].buffer;
|
dynamicBarriers[i].buffer = buffers[i].buffer;
|
||||||
}
|
}
|
||||||
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||||
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||||
sourceManager->submitCommands();
|
sourceManager->submitCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
|
||||||
{
|
{
|
||||||
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
|
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||||
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
|
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
|
||||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.dstAccessMask = dstAccess;
|
barrier.dstAccessMask = dstAccess;
|
||||||
barrier.srcAccessMask = srcAccess;
|
barrier.srcAccessMask = srcAccess;
|
||||||
barrier.offset = 0;
|
barrier.offset = 0;
|
||||||
barrier.size = size;
|
barrier.size = size;
|
||||||
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
|
||||||
for(uint32 i = 0; i < numBuffers; ++i)
|
for(uint32 i = 0; i < numBuffers; ++i)
|
||||||
{
|
{
|
||||||
dynamicBarriers[i] = barrier;
|
dynamicBarriers[i] = barrier;
|
||||||
dynamicBarriers[i].buffer = buffers[i].buffer;
|
dynamicBarriers[i].buffer = buffers[i].buffer;
|
||||||
}
|
}
|
||||||
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ShaderBuffer::lock(bool bWriteOnly)
|
void *ShaderBuffer::lock(bool bWriteOnly)
|
||||||
{
|
{
|
||||||
void *data = nullptr;
|
void *data = nullptr;
|
||||||
|
|
||||||
/*if (bVolatile)
|
/*if (bVolatile)
|
||||||
{
|
{
|
||||||
if (lockMode == RLM_ReadOnly)
|
if (lockMode == RLM_ReadOnly)
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new std::logic_error("TODO implement volatile buffers");
|
throw new std::logic_error("TODO implement volatile buffers");
|
||||||
//device->getRHIDevice()->getTemp
|
//device->getRHIDevice()->getTemp
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
//assert(bStatic || bDynamic || bUAV);
|
//assert(bStatic || bDynamic || bUAV);
|
||||||
|
|
||||||
PendingBuffer pending;
|
PendingBuffer pending;
|
||||||
pending.bWriteOnly = bWriteOnly;
|
pending.bWriteOnly = bWriteOnly;
|
||||||
pending.prevQueue = owner;
|
pending.prevQueue = owner;
|
||||||
if (bWriteOnly)
|
if (bWriteOnly)
|
||||||
{
|
{
|
||||||
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||||
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||||
data = stagingBuffer->getMappedPointer();
|
data = stagingBuffer->getMappedPointer();
|
||||||
pending.stagingBuffer = stagingBuffer;
|
pending.stagingBuffer = stagingBuffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
|
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
|
||||||
graphics->getQueueCommands(owner)->submitCommands();
|
graphics->getQueueCommands(owner)->submitCommands();
|
||||||
current->waitForCommand();
|
current->waitForCommand();
|
||||||
|
|
||||||
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||||
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
|
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
|
||||||
|
|
||||||
VkBufferMemoryBarrier barrier =
|
VkBufferMemoryBarrier barrier =
|
||||||
init::BufferMemoryBarrier();
|
init::BufferMemoryBarrier();
|
||||||
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
|
||||||
barrier.buffer = buffers[currentBuffer].buffer;
|
barrier.buffer = buffers[currentBuffer].buffer;
|
||||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
barrier.offset = 0;
|
barrier.offset = 0;
|
||||||
barrier.size = size;
|
barrier.size = size;
|
||||||
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
|
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);
|
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||||
|
|
||||||
VkBufferCopy regions;
|
VkBufferCopy regions;
|
||||||
regions.size = size;
|
regions.size = size;
|
||||||
regions.srcOffset = 0;
|
regions.srcOffset = 0;
|
||||||
regions.dstOffset = 0;
|
regions.dstOffset = 0;
|
||||||
|
|
||||||
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, ®ions);
|
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, ®ions);
|
||||||
|
|
||||||
graphics->getQueueCommands(owner)->submitCommands();
|
graphics->getQueueCommands(owner)->submitCommands();
|
||||||
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
|
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
|
||||||
|
|
||||||
stagingBuffer->flushMappedMemory();
|
stagingBuffer->flushMappedMemory();
|
||||||
pending.stagingBuffer = stagingBuffer;
|
pending.stagingBuffer = stagingBuffer;
|
||||||
|
|
||||||
data = stagingBuffer->getMappedPointer();
|
data = stagingBuffer->getMappedPointer();
|
||||||
}
|
}
|
||||||
pendingBuffers[this] = pending;
|
pendingBuffers[this] = pending;
|
||||||
|
|
||||||
assert(data);
|
assert(data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderBuffer::unlock()
|
void ShaderBuffer::unlock()
|
||||||
{
|
{
|
||||||
auto found = pendingBuffers.find(this);
|
auto found = pendingBuffers.find(this);
|
||||||
if (found != pendingBuffers.end())
|
if (found != pendingBuffers.end())
|
||||||
{
|
{
|
||||||
PendingBuffer pending = found->value;
|
PendingBuffer pending = found->value;
|
||||||
pending.stagingBuffer->flushMappedMemory();
|
pending.stagingBuffer->flushMappedMemory();
|
||||||
pendingBuffers.erase(this);
|
pendingBuffers.erase(this);
|
||||||
if (pending.bWriteOnly)
|
if (pending.bWriteOnly)
|
||||||
{
|
{
|
||||||
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
||||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||||
|
|
||||||
VkBufferCopy region;
|
VkBufferCopy region;
|
||||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||||
region.size = size;
|
region.size = size;
|
||||||
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||||
graphics->getQueueCommands(owner)->submitCommands();
|
graphics->getQueueCommands(owner)->submitCommands();
|
||||||
}
|
}
|
||||||
//requestOwnershipTransfer(pending.prevQueue);
|
//requestOwnershipTransfer(pending.prevQueue);
|
||||||
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
|
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
|
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
|
||||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
|
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
|
||||||
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
|
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
|
||||||
, dedicatedStagingBuffer(nullptr)
|
, dedicatedStagingBuffer(nullptr)
|
||||||
{
|
{
|
||||||
if(createInfo.bDynamic)
|
if(createInfo.bDynamic)
|
||||||
{
|
{
|
||||||
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||||
}
|
}
|
||||||
if (createInfo.resourceData.data != nullptr)
|
if (createInfo.resourceData.data != nullptr)
|
||||||
{
|
{
|
||||||
void *data = lock();
|
void *data = lock();
|
||||||
std::memcpy(data, createInfo.resourceData.data, createInfo.resourceData.size);
|
std::memcpy(data, createInfo.resourceData.data, createInfo.resourceData.size);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformBuffer::~UniformBuffer()
|
UniformBuffer::~UniformBuffer()
|
||||||
@@ -290,52 +290,52 @@ UniformBuffer::~UniformBuffer()
|
|||||||
bool UniformBuffer::updateContents(const BulkResourceData &resourceData)
|
bool UniformBuffer::updateContents(const BulkResourceData &resourceData)
|
||||||
{
|
{
|
||||||
if(!Gfx::UniformBuffer::updateContents(resourceData))
|
if(!Gfx::UniformBuffer::updateContents(resourceData))
|
||||||
{
|
{
|
||||||
// no update was performed, skip
|
// no update was performed, skip
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void* data = lock();
|
void* data = lock();
|
||||||
std::memcpy(data, resourceData.data, resourceData.size);
|
std::memcpy(data, resourceData.data, resourceData.size);
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void* UniformBuffer::lock(bool bWriteOnly)
|
void* UniformBuffer::lock(bool bWriteOnly)
|
||||||
{
|
{
|
||||||
if(dedicatedStagingBuffer != nullptr)
|
if(dedicatedStagingBuffer != nullptr)
|
||||||
{
|
{
|
||||||
return dedicatedStagingBuffer->getMappedPointer();
|
return dedicatedStagingBuffer->getMappedPointer();
|
||||||
}
|
}
|
||||||
return ShaderBuffer::lock(bWriteOnly);
|
return ShaderBuffer::lock(bWriteOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniformBuffer::unlock()
|
void UniformBuffer::unlock()
|
||||||
{
|
{
|
||||||
if(dedicatedStagingBuffer != nullptr)
|
if(dedicatedStagingBuffer != nullptr)
|
||||||
{
|
{
|
||||||
dedicatedStagingBuffer->flushMappedMemory();
|
dedicatedStagingBuffer->flushMappedMemory();
|
||||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||||
|
|
||||||
VkBufferCopy region;
|
VkBufferCopy region;
|
||||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||||
region.size = ShaderBuffer::size;
|
region.size = ShaderBuffer::size;
|
||||||
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
graphics->getQueueCommands(currentOwner)->submitCommands();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShaderBuffer::unlock();
|
ShaderBuffer::unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
@@ -346,24 +346,24 @@ void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineSt
|
|||||||
|
|
||||||
VkAccessFlags UniformBuffer::getSourceAccessMask()
|
VkAccessFlags UniformBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkAccessFlags UniformBuffer::getDestAccessMask()
|
VkAccessFlags UniformBuffer::getDestAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_UNIFORM_READ_BIT;
|
return VK_ACCESS_UNIFORM_READ_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredBuffer::StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData)
|
StructuredBuffer::StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData)
|
||||||
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.resourceData)
|
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.resourceData)
|
||||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, resourceData.bDynamic)
|
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, resourceData.bDynamic)
|
||||||
{
|
{
|
||||||
if (resourceData.resourceData.data != nullptr)
|
if (resourceData.resourceData.data != nullptr)
|
||||||
{
|
{
|
||||||
void *data = lock();
|
void *data = lock();
|
||||||
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredBuffer::~StructuredBuffer()
|
StructuredBuffer::~StructuredBuffer()
|
||||||
@@ -373,49 +373,49 @@ StructuredBuffer::~StructuredBuffer()
|
|||||||
bool StructuredBuffer::updateContents(const BulkResourceData &resourceData)
|
bool StructuredBuffer::updateContents(const BulkResourceData &resourceData)
|
||||||
{
|
{
|
||||||
Gfx::StructuredBuffer::updateContents(resourceData);
|
Gfx::StructuredBuffer::updateContents(resourceData);
|
||||||
//We always want to update, as the contents could be different on the GPU
|
//We always want to update, as the contents could be different on the GPU
|
||||||
void* data = lock();
|
void* data = lock();
|
||||||
std::memcpy(data, resourceData.data, resourceData.size);
|
std::memcpy(data, resourceData.data, resourceData.size);
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void* StructuredBuffer::lock(bool bWriteOnly)
|
void* StructuredBuffer::lock(bool bWriteOnly)
|
||||||
{
|
{
|
||||||
if(dedicatedStagingBuffer != nullptr)
|
if(dedicatedStagingBuffer != nullptr)
|
||||||
{
|
{
|
||||||
return dedicatedStagingBuffer->getMappedPointer();
|
return dedicatedStagingBuffer->getMappedPointer();
|
||||||
}
|
}
|
||||||
return ShaderBuffer::lock(bWriteOnly);
|
return ShaderBuffer::lock(bWriteOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructuredBuffer::unlock()
|
void StructuredBuffer::unlock()
|
||||||
{
|
{
|
||||||
if(dedicatedStagingBuffer != nullptr)
|
if(dedicatedStagingBuffer != nullptr)
|
||||||
{
|
{
|
||||||
dedicatedStagingBuffer->flushMappedMemory();
|
dedicatedStagingBuffer->flushMappedMemory();
|
||||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||||
|
|
||||||
VkBufferCopy region;
|
VkBufferCopy region;
|
||||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||||
region.size = ShaderBuffer::size;
|
region.size = ShaderBuffer::size;
|
||||||
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||||
graphics->getQueueCommands(currentOwner)->submitCommands();
|
graphics->getQueueCommands(currentOwner)->submitCommands();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShaderBuffer::unlock();
|
ShaderBuffer::unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructuredBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
void StructuredBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
@@ -426,24 +426,24 @@ void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelin
|
|||||||
|
|
||||||
VkAccessFlags StructuredBuffer::getSourceAccessMask()
|
VkAccessFlags StructuredBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkAccessFlags StructuredBuffer::getDestAccessMask()
|
VkAccessFlags StructuredBuffer::getDestAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_READ_BIT;
|
return VK_ACCESS_MEMORY_READ_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
|
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
|
||||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
|
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
|
||||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
|
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
|
||||||
{
|
{
|
||||||
if (resourceData.resourceData.data != nullptr)
|
if (resourceData.resourceData.data != nullptr)
|
||||||
{
|
{
|
||||||
void *data = lock();
|
void *data = lock();
|
||||||
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexBuffer::~VertexBuffer()
|
VertexBuffer::~VertexBuffer()
|
||||||
@@ -452,12 +452,12 @@ VertexBuffer::~VertexBuffer()
|
|||||||
|
|
||||||
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
@@ -468,24 +468,24 @@ void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineSta
|
|||||||
|
|
||||||
VkAccessFlags VertexBuffer::getSourceAccessMask()
|
VkAccessFlags VertexBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkAccessFlags VertexBuffer::getDestAccessMask()
|
VkAccessFlags VertexBuffer::getDestAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
|
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
|
||||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
|
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
|
||||||
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
|
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
|
||||||
{
|
{
|
||||||
if (resourceData.resourceData.data != nullptr)
|
if (resourceData.resourceData.data != nullptr)
|
||||||
{
|
{
|
||||||
void *data = lock();
|
void *data = lock();
|
||||||
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexBuffer::~IndexBuffer()
|
IndexBuffer::~IndexBuffer()
|
||||||
@@ -494,12 +494,12 @@ IndexBuffer::~IndexBuffer()
|
|||||||
|
|
||||||
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||||
{
|
{
|
||||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
@@ -510,10 +510,10 @@ void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStag
|
|||||||
|
|
||||||
VkAccessFlags IndexBuffer::getSourceAccessMask()
|
VkAccessFlags IndexBuffer::getSourceAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkAccessFlags IndexBuffer::getDestAccessMask()
|
VkAccessFlags IndexBuffer::getDestAccessMask()
|
||||||
{
|
{
|
||||||
return VK_ACCESS_INDEX_READ_BIT;
|
return VK_ACCESS_INDEX_READ_BIT;
|
||||||
}
|
}
|
||||||
@@ -16,16 +16,13 @@ using namespace Seele::Vulkan;
|
|||||||
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
|
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
|
||||||
: graphics(graphics)
|
: graphics(graphics)
|
||||||
, manager(manager)
|
, manager(manager)
|
||||||
, renderPass(nullptr)
|
|
||||||
, framebuffer(nullptr)
|
|
||||||
, subpassIndex(0)
|
|
||||||
, owner(cmdPool)
|
, owner(cmdPool)
|
||||||
{
|
{
|
||||||
VkCommandBufferAllocateInfo allocInfo =
|
VkCommandBufferAllocateInfo allocInfo =
|
||||||
init::CommandBufferAllocateInfo(cmdPool,
|
init::CommandBufferAllocateInfo(cmdPool,
|
||||||
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||||
1);
|
1);
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle))
|
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle))
|
||||||
|
|
||||||
fence = new Fence(graphics);
|
fence = new Fence(graphics);
|
||||||
@@ -34,10 +31,8 @@ CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferMa
|
|||||||
|
|
||||||
CmdBuffer::~CmdBuffer()
|
CmdBuffer::~CmdBuffer()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||||
renderPass = nullptr;
|
|
||||||
framebuffer = nullptr;
|
|
||||||
waitSemaphores.clear();
|
waitSemaphores.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,24 +41,22 @@ void CmdBuffer::begin()
|
|||||||
VkCommandBufferBeginInfo beginInfo =
|
VkCommandBufferBeginInfo beginInfo =
|
||||||
init::CommandBufferBeginInfo();
|
init::CommandBufferBeginInfo();
|
||||||
beginInfo.pInheritanceInfo = nullptr;
|
beginInfo.pInheritanceInfo = nullptr;
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||||
state = State::InsideBegin;
|
state = State::InsideBegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBuffer::end()
|
void CmdBuffer::end()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
VK_CHECK(vkEndCommandBuffer(handle));
|
VK_CHECK(vkEndCommandBuffer(handle));
|
||||||
state = State::Ended;
|
state = State::Ended;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFramebuffer)
|
void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||||
{
|
{
|
||||||
assert(state == State::InsideBegin);
|
assert(state == State::InsideBegin);
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
renderPass = newRenderPass;
|
|
||||||
framebuffer = newFramebuffer;
|
|
||||||
|
|
||||||
VkRenderPassBeginInfo beginInfo =
|
VkRenderPassBeginInfo beginInfo =
|
||||||
init::RenderPassBeginInfo();
|
init::RenderPassBeginInfo();
|
||||||
@@ -74,15 +67,13 @@ void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFrame
|
|||||||
beginInfo.framebuffer = framebuffer->getHandle();
|
beginInfo.framebuffer = framebuffer->getHandle();
|
||||||
vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents());
|
vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents());
|
||||||
state = State::RenderPassActive;
|
state = State::RenderPassActive;
|
||||||
//std::cout << "Beginning renderPass" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBuffer::endRenderPass()
|
void CmdBuffer::endRenderPass()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
vkCmdEndRenderPass(handle);
|
vkCmdEndRenderPass(handle);
|
||||||
state = State::InsideBegin;
|
state = State::InsideBegin;
|
||||||
//std::cout << "Ending renderPass" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||||
@@ -90,9 +81,10 @@ void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
|||||||
assert(state == State::RenderPassActive);
|
assert(state == State::RenderPassActive);
|
||||||
if(commands.size() == 0)
|
if(commands.size() == 0)
|
||||||
{
|
{
|
||||||
|
std::cout << "No commands provided" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||||
for (uint32 i = 0; i < commands.size(); ++i)
|
for (uint32 i = 0; i < commands.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -111,7 +103,7 @@ void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
|||||||
|
|
||||||
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
if(commands.size() == 0)
|
if(commands.size() == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -134,14 +126,14 @@ void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
|||||||
|
|
||||||
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
waitSemaphores.add(semaphore);
|
waitSemaphores.add(semaphore);
|
||||||
waitFlags.add(flags);
|
waitFlags.add(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBuffer::refreshFence()
|
void CmdBuffer::refreshFence()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
if (state == State::Submitted)
|
if (state == State::Submitted)
|
||||||
{
|
{
|
||||||
if (fence->isSignaled())
|
if (fence->isSignaled())
|
||||||
@@ -174,7 +166,7 @@ void CmdBuffer::refreshFence()
|
|||||||
|
|
||||||
void CmdBuffer::waitForCommand(uint32 timeout)
|
void CmdBuffer::waitForCommand(uint32 timeout)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(handleLock);
|
std::scoped_lock lock(handleLock);
|
||||||
fence->wait(timeout);
|
fence->wait(timeout);
|
||||||
refreshFence();
|
refreshFence();
|
||||||
}
|
}
|
||||||
@@ -212,7 +204,7 @@ RenderCommand::~RenderCommand()
|
|||||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::begin(PCmdBuffer parent)
|
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||||
{
|
{
|
||||||
threadId = std::this_thread::get_id();
|
threadId = std::this_thread::get_id();
|
||||||
ready = false;
|
ready = false;
|
||||||
@@ -220,9 +212,9 @@ void RenderCommand::begin(PCmdBuffer parent)
|
|||||||
init::CommandBufferBeginInfo();
|
init::CommandBufferBeginInfo();
|
||||||
VkCommandBufferInheritanceInfo inheritanceInfo =
|
VkCommandBufferInheritanceInfo inheritanceInfo =
|
||||||
init::CommandBufferInheritanceInfo();
|
init::CommandBufferInheritanceInfo();
|
||||||
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
|
inheritanceInfo.framebuffer = framebuffer->getHandle();
|
||||||
inheritanceInfo.renderPass = parent->renderPass->getHandle();
|
inheritanceInfo.renderPass = renderPass->getHandle();
|
||||||
inheritanceInfo.subpass = parent->subpassIndex;
|
inheritanceInfo.subpass = 0;
|
||||||
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
beginInfo.pInheritanceInfo = &inheritanceInfo;
|
||||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
|
||||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||||
@@ -230,13 +222,11 @@ void RenderCommand::begin(PCmdBuffer parent)
|
|||||||
|
|
||||||
void RenderCommand::end()
|
void RenderCommand::end()
|
||||||
{
|
{
|
||||||
assert(threadId == std::this_thread::get_id());
|
|
||||||
VK_CHECK(vkEndCommandBuffer(handle));
|
VK_CHECK(vkEndCommandBuffer(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::reset()
|
void RenderCommand::reset()
|
||||||
{
|
{
|
||||||
assert(threadId == std::this_thread::get_id());
|
|
||||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||||
boundDescriptors.clear();
|
boundDescriptors.clear();
|
||||||
ready = true;
|
ready = true;
|
||||||
@@ -420,7 +410,7 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
|||||||
|
|
||||||
activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
|
activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
|
||||||
activeCmdBuffer->begin();
|
activeCmdBuffer->begin();
|
||||||
std::unique_lock lock(allocatedBufferLock);
|
std::scoped_lock lock(allocatedBufferLock);
|
||||||
allocatedBuffers.add(activeCmdBuffer);
|
allocatedBuffers.add(activeCmdBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,29 +426,29 @@ PCmdBuffer CommandBufferManager::getCommands()
|
|||||||
return activeCmdBuffer;
|
return activeCmdBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRenderCommand CommandBufferManager::createRenderCommand(const std::string& name)
|
PRenderCommand CommandBufferManager::createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(allocatedRenderLock);
|
std::scoped_lock lck(allocatedRenderLock);
|
||||||
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
|
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
|
||||||
{
|
{
|
||||||
PRenderCommand cmdBuffer = allocatedRenderCommands[i];
|
PRenderCommand cmdBuffer = allocatedRenderCommands[i];
|
||||||
if (cmdBuffer->isReady())
|
if (cmdBuffer->isReady())
|
||||||
{
|
{
|
||||||
cmdBuffer->name = name;
|
cmdBuffer->name = name;
|
||||||
cmdBuffer->begin(activeCmdBuffer);
|
cmdBuffer->begin(renderPass, framebuffer);
|
||||||
return cmdBuffer;
|
return cmdBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PRenderCommand result = new RenderCommand(graphics, commandPool);
|
PRenderCommand result = new RenderCommand(graphics, commandPool);
|
||||||
result->name = name;
|
result->name = name;
|
||||||
result->begin(activeCmdBuffer);
|
result->begin(renderPass, framebuffer);
|
||||||
allocatedRenderCommands.add(result);
|
allocatedRenderCommands.add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name)
|
PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(allocatedComputeLock);
|
std::scoped_lock lck(allocatedComputeLock);
|
||||||
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
|
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
|
||||||
{
|
{
|
||||||
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
|
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
|
||||||
@@ -495,7 +485,7 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
|||||||
queue->submitCommandBuffer(activeCmdBuffer);
|
queue->submitCommandBuffer(activeCmdBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::unique_lock lock(allocatedBufferLock);
|
std::scoped_lock lock(allocatedBufferLock);
|
||||||
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
|
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
|
||||||
{
|
{
|
||||||
PCmdBuffer cmdBuffer = allocatedBuffers[i];
|
PCmdBuffer cmdBuffer = allocatedBuffers[i];
|
||||||
|
|||||||
@@ -47,10 +47,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
PCommandBufferManager manager;
|
PCommandBufferManager manager;
|
||||||
PRenderPass renderPass;
|
|
||||||
PFramebuffer framebuffer;
|
|
||||||
PFence fence;
|
PFence fence;
|
||||||
uint32 subpassIndex;
|
|
||||||
State state;
|
State state;
|
||||||
VkViewport currentViewport;
|
VkViewport currentViewport;
|
||||||
VkRect2D currentScissor;
|
VkRect2D currentScissor;
|
||||||
@@ -79,7 +76,7 @@ public:
|
|||||||
{
|
{
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
void begin(PCmdBuffer parent);
|
void begin(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||||
void end();
|
void end();
|
||||||
void reset();
|
void reset();
|
||||||
virtual bool isReady() override;
|
virtual bool isReady() override;
|
||||||
@@ -145,7 +142,7 @@ public:
|
|||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
PCmdBuffer getCommands();
|
PCmdBuffer getCommands();
|
||||||
PRenderCommand createRenderCommand(const std::string& name);
|
PRenderCommand createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name);
|
||||||
PComputeCommand createComputeCommand(const std::string& name);
|
PComputeCommand createComputeCommand(const std::string& name);
|
||||||
VkCommandPool getPoolHandle() const
|
VkCommandPool getPoolHandle() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ PipelineLayout::~PipelineLayout()
|
|||||||
{
|
{
|
||||||
if (layoutHandle != VK_NULL_HANDLE)
|
if (layoutHandle != VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
|
//vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ DEFINE_REF(DescriptorLayout)
|
|||||||
class PipelineLayout : public Gfx::PipelineLayout
|
class PipelineLayout : public Gfx::PipelineLayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PipelineLayout(PGraphics graphics)
|
PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout)
|
||||||
: graphics(graphics)
|
: Gfx::PipelineLayout(baseLayout)
|
||||||
|
, graphics(graphics)
|
||||||
, layoutHash(0)
|
, layoutHash(0)
|
||||||
, layoutHandle(VK_NULL_HANDLE)
|
, layoutHandle(VK_NULL_HANDLE)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
virtual ~PipelineLayout();
|
virtual ~PipelineLayout();
|
||||||
virtual void create();
|
virtual void create();
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|||||||
@@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
|
|
||||||
|
thread_local PCommandBufferManager Seele::Vulkan::Graphics::graphicsCommands = nullptr;
|
||||||
|
thread_local PCommandBufferManager Seele::Vulkan::Graphics::computeCommands = nullptr;
|
||||||
|
thread_local PCommandBufferManager Seele::Vulkan::Graphics::transferCommands = nullptr;
|
||||||
|
thread_local PCommandBufferManager Seele::Vulkan::Graphics::dedicatedTransferCommands = nullptr;
|
||||||
|
|
||||||
Graphics::Graphics()
|
Graphics::Graphics()
|
||||||
: instance(VK_NULL_HANDLE)
|
: instance(VK_NULL_HANDLE)
|
||||||
, handle(VK_NULL_HANDLE)
|
, handle(VK_NULL_HANDLE)
|
||||||
@@ -52,7 +57,7 @@ Gfx::PWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
|||||||
Gfx::PViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
|
Gfx::PViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
|
||||||
{
|
{
|
||||||
PViewport result = new Viewport(this, owner, viewportInfo);
|
PViewport result = new Viewport(this, owner, viewportInfo);
|
||||||
std::unique_lock lock(viewportLock);
|
std::scoped_lock lock(viewportLock);
|
||||||
viewports.add(result);
|
viewports.add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -67,7 +72,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
|||||||
uint32 framebufferHash = rp->getFramebufferHash();
|
uint32 framebufferHash = rp->getFramebufferHash();
|
||||||
PFramebuffer framebuffer;
|
PFramebuffer framebuffer;
|
||||||
{
|
{
|
||||||
std::unique_lock lock(allocatedFrameBufferLock);
|
std::scoped_lock lock(allocatedFrameBufferLock);
|
||||||
auto found = allocatedFramebuffers.find(framebufferHash);
|
auto found = allocatedFramebuffers.find(framebufferHash);
|
||||||
if (found == allocatedFramebuffers.end())
|
if (found == allocatedFramebuffers.end())
|
||||||
{
|
{
|
||||||
@@ -80,12 +85,18 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
|
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
|
||||||
|
std::scoped_lock lock(renderPassLock);
|
||||||
|
activeRenderPass = rp;
|
||||||
|
activeFramebuffer = framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::endRenderPass()
|
void Graphics::endRenderPass()
|
||||||
{
|
{
|
||||||
getGraphicsCommands()->getCommands()->endRenderPass();
|
getGraphicsCommands()->getCommands()->endRenderPass();
|
||||||
getGraphicsCommands()->submitCommands();
|
getGraphicsCommands()->submitCommands();
|
||||||
|
std::scoped_lock lock(renderPassLock);
|
||||||
|
activeRenderPass = nullptr;
|
||||||
|
activeFramebuffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
void Graphics::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||||
@@ -128,7 +139,7 @@ Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
|
|||||||
}
|
}
|
||||||
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
|
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
|
||||||
{
|
{
|
||||||
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(name);
|
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name);
|
||||||
return cmdBuffer;
|
return cmdBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +217,9 @@ Gfx::PDescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
|||||||
PDescriptorLayout layout = new DescriptorLayout(this, name);
|
PDescriptorLayout layout = new DescriptorLayout(this, name);
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
Gfx::PPipelineLayout Graphics::createPipelineLayout()
|
Gfx::PPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
|
||||||
{
|
{
|
||||||
PPipelineLayout layout = new PipelineLayout(this);
|
PPipelineLayout layout = new PipelineLayout(this, baseLayout);
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,49 +306,37 @@ PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
|
|||||||
throw new std::logic_error("invalid queue type");
|
throw new std::logic_error("invalid queue type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::mutex graphicsCommandLock;
|
|
||||||
PCommandBufferManager Graphics::getGraphicsCommands()
|
PCommandBufferManager Graphics::getGraphicsCommands()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(graphicsCommandLock);
|
if(graphicsCommands == nullptr)
|
||||||
auto id = std::this_thread::get_id();
|
|
||||||
if(graphicsCommands.find(id) == graphicsCommands.end())
|
|
||||||
{
|
{
|
||||||
graphicsCommands[id] = new CommandBufferManager(this, graphicsQueue);
|
graphicsCommands = new CommandBufferManager(this, graphicsQueue);
|
||||||
}
|
}
|
||||||
return graphicsCommands[id];
|
return graphicsCommands;
|
||||||
}
|
}
|
||||||
std::mutex computeCommandLock;
|
|
||||||
PCommandBufferManager Graphics::getComputeCommands()
|
PCommandBufferManager Graphics::getComputeCommands()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(computeCommandLock);
|
if(computeCommands == nullptr)
|
||||||
auto id = std::this_thread::get_id();
|
|
||||||
if(computeCommands.find(id) == computeCommands.end())
|
|
||||||
{
|
{
|
||||||
computeCommands[id] = new CommandBufferManager(this, computeQueue);
|
computeCommands = new CommandBufferManager(this, computeQueue);
|
||||||
}
|
}
|
||||||
return computeCommands[id];
|
return computeCommands;
|
||||||
}
|
}
|
||||||
std::mutex transferCommandLock;
|
|
||||||
PCommandBufferManager Graphics::getTransferCommands()
|
PCommandBufferManager Graphics::getTransferCommands()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(transferCommandLock);
|
if(transferCommands == nullptr)
|
||||||
auto id = std::this_thread::get_id();
|
|
||||||
if(transferCommands.find(id) == transferCommands.end())
|
|
||||||
{
|
{
|
||||||
transferCommands[id] = new CommandBufferManager(this, transferQueue);
|
transferCommands = new CommandBufferManager(this, transferQueue);
|
||||||
}
|
}
|
||||||
return transferCommands[id];
|
return transferCommands;
|
||||||
}
|
}
|
||||||
std::mutex dedicatedCommandLock;
|
|
||||||
PCommandBufferManager Graphics::getDedicatedTransferCommands()
|
PCommandBufferManager Graphics::getDedicatedTransferCommands()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(dedicatedCommandLock);
|
if(dedicatedTransferCommands == dedicatedTransferCommands)
|
||||||
auto id = std::this_thread::get_id();
|
|
||||||
if(dedicatedTransferCommands.find(id) == dedicatedTransferCommands.end())
|
|
||||||
{
|
{
|
||||||
dedicatedTransferCommands[id] = new CommandBufferManager(this, dedicatedTransferQueue);
|
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
|
||||||
}
|
}
|
||||||
return dedicatedTransferCommands[id];
|
return dedicatedTransferCommands;
|
||||||
}
|
}
|
||||||
PAllocator Graphics::getAllocator()
|
PAllocator Graphics::getAllocator()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ DECLARE_REF(Allocator)
|
|||||||
DECLARE_REF(StagingManager)
|
DECLARE_REF(StagingManager)
|
||||||
DECLARE_REF(CommandBufferManager)
|
DECLARE_REF(CommandBufferManager)
|
||||||
DECLARE_REF(Queue)
|
DECLARE_REF(Queue)
|
||||||
|
DECLARE_REF(RenderPass)
|
||||||
DECLARE_REF(Framebuffer)
|
DECLARE_REF(Framebuffer)
|
||||||
DECLARE_REF(RenderCommand)
|
DECLARE_REF(RenderCommand)
|
||||||
DECLARE_REF(PipelineCache)
|
DECLARE_REF(PipelineCache)
|
||||||
@@ -63,7 +64,7 @@ public:
|
|||||||
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
|
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
|
||||||
|
|
||||||
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||||
virtual Gfx::PPipelineLayout createPipelineLayout() override;
|
virtual Gfx::PPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
|
||||||
|
|
||||||
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
|
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
|
||||||
protected:
|
protected:
|
||||||
@@ -82,10 +83,13 @@ protected:
|
|||||||
PQueue transferQueue;
|
PQueue transferQueue;
|
||||||
PQueue dedicatedTransferQueue;
|
PQueue dedicatedTransferQueue;
|
||||||
PPipelineCache pipelineCache;
|
PPipelineCache pipelineCache;
|
||||||
Map<std::thread::id, PCommandBufferManager> graphicsCommands;
|
std::mutex renderPassLock;
|
||||||
Map<std::thread::id, PCommandBufferManager> computeCommands;
|
PRenderPass activeRenderPass;
|
||||||
Map<std::thread::id, PCommandBufferManager> transferCommands;
|
PFramebuffer activeFramebuffer;
|
||||||
Map<std::thread::id, PCommandBufferManager> dedicatedTransferCommands;
|
thread_local static PCommandBufferManager graphicsCommands;
|
||||||
|
thread_local static PCommandBufferManager computeCommands;
|
||||||
|
thread_local static PCommandBufferManager transferCommands;
|
||||||
|
thread_local static PCommandBufferManager dedicatedTransferCommands;
|
||||||
VkPhysicalDeviceProperties props;
|
VkPhysicalDeviceProperties props;
|
||||||
VkPhysicalDeviceFeatures features;
|
VkPhysicalDeviceFeatures features;
|
||||||
VkDebugReportCallbackEXT callback;
|
VkDebugReportCallbackEXT callback;
|
||||||
|
|||||||
@@ -296,6 +296,8 @@ VkBufferMemoryBarrier init::BufferMemoryBarrier()
|
|||||||
VkBufferMemoryBarrier bufferMemoryBarrier = {};
|
VkBufferMemoryBarrier bufferMemoryBarrier = {};
|
||||||
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||||
bufferMemoryBarrier.pNext = NULL;
|
bufferMemoryBarrier.pNext = NULL;
|
||||||
|
bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
return bufferMemoryBarrier;
|
return bufferMemoryBarrier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
|
|||||||
uint32 hash = crc.checksum();
|
uint32 hash = crc.checksum();
|
||||||
VkPipeline pipelineHandle;
|
VkPipeline pipelineHandle;
|
||||||
|
|
||||||
std::unique_lock lock(createdPipelinesLock);
|
std::scoped_lock lock(createdPipelinesLock);
|
||||||
auto foundPipeline = createdPipelines.find(hash);
|
auto foundPipeline = createdPipelines.find(hash);
|
||||||
if (foundPipeline != createdPipelines.end())
|
if (foundPipeline != createdPipelines.end())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Queue::~Queue()
|
|||||||
|
|
||||||
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
|
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(queueLock);
|
std::scoped_lock lck(queueLock);
|
||||||
assert(cmdBuffer->state == CmdBuffer::State::Ended);
|
assert(cmdBuffer->state == CmdBuffer::State::Ended);
|
||||||
|
|
||||||
PFence fence = cmdBuffer->fence;
|
PFence fence = cmdBuffer->fence;
|
||||||
|
|||||||
@@ -185,6 +185,6 @@ const Gfx::ShaderCollection* MaterialAsset::getShaders(Gfx::RenderPassType rende
|
|||||||
|
|
||||||
Gfx::ShaderCollection& MaterialAsset::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput)
|
Gfx::ShaderCollection& MaterialAsset::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(shaderMapLock);
|
std::scoped_lock lock(shaderMapLock);
|
||||||
return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false);
|
return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public:
|
|||||||
~RefObject()
|
~RefObject()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::unique_lock lock(registeredObjectsLock);
|
std::scoped_lock lock(registeredObjectsLock);
|
||||||
registeredObjects.erase(handle);
|
registeredObjects.erase(handle);
|
||||||
}
|
}
|
||||||
// #pragma warning( disable: 4150)
|
// #pragma warning( disable: 4150)
|
||||||
@@ -114,7 +114,7 @@ public:
|
|||||||
}
|
}
|
||||||
RefPtr(T *ptr, Deleter deleter = Deleter())
|
RefPtr(T *ptr, Deleter deleter = Deleter())
|
||||||
{
|
{
|
||||||
std::unique_lock l(registeredObjectsLock);
|
std::scoped_lock l(registeredObjectsLock);
|
||||||
auto registeredObj = registeredObjects.find(ptr);
|
auto registeredObj = registeredObjects.find(ptr);
|
||||||
// get here for thread safetly
|
// get here for thread safetly
|
||||||
auto registeredEnd = registeredObjects.end();
|
auto registeredEnd = registeredObjects.end();
|
||||||
@@ -249,6 +249,10 @@ public:
|
|||||||
{
|
{
|
||||||
return object->getHandle();
|
return object->getHandle();
|
||||||
}
|
}
|
||||||
|
RefPtr<T, Deleter> clone()
|
||||||
|
{
|
||||||
|
return RefPtr<T, Deleter>(new T(*getHandle()));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefObject<T, Deleter> *object;
|
RefObject<T, Deleter> *object;
|
||||||
|
|||||||
@@ -12,8 +12,36 @@ Actor::~Actor()
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
void Actor::tick(float)
|
|
||||||
|
void Actor::launchStart()
|
||||||
{
|
{
|
||||||
|
rootComponent->launchStart();
|
||||||
|
for(auto child : children)
|
||||||
|
{
|
||||||
|
child->launchStart();
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
Array<Job> Actor::launchTick(float deltaTime) const
|
||||||
|
{
|
||||||
|
Array<Job> result = rootComponent->launchTick(deltaTime);
|
||||||
|
for(auto child : children)
|
||||||
|
{
|
||||||
|
result.addAll(child->launchTick(deltaTime));
|
||||||
|
}
|
||||||
|
result.add(tick(deltaTime));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<Job> Actor::launchUpdate()
|
||||||
|
{
|
||||||
|
Array<Job> result = rootComponent->launchUpdate();
|
||||||
|
for(auto child : children)
|
||||||
|
{
|
||||||
|
result.addAll(child->launchUpdate());
|
||||||
|
}
|
||||||
|
result.add(update());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
void Actor::notifySceneAttach(PScene scene)
|
void Actor::notifySceneAttach(PScene scene)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Math/Transform.h"
|
#include "Math/Transform.h"
|
||||||
|
#include "ThreadPool.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
@@ -12,8 +13,12 @@ class Actor
|
|||||||
public:
|
public:
|
||||||
Actor();
|
Actor();
|
||||||
virtual ~Actor();
|
virtual ~Actor();
|
||||||
|
virtual void launchStart();
|
||||||
void tick(float deltaTime);
|
virtual void start() {}
|
||||||
|
Array<Job> launchTick(float deltaTime) const;
|
||||||
|
virtual Job tick(float deltaTime) const { co_return; }
|
||||||
|
Array<Job> launchUpdate();
|
||||||
|
virtual Job update() { co_return; }
|
||||||
void notifySceneAttach(PScene scene);
|
void notifySceneAttach(PScene scene);
|
||||||
PScene getScene();
|
PScene getScene();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
target_sources(SeeleEngine
|
target_sources(SeeleEngine
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
Util.h
|
||||||
Scene.cpp
|
Scene.cpp
|
||||||
Scene.h)
|
Scene.h)
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ target_sources(SeeleEngine
|
|||||||
CameraComponent.cpp
|
CameraComponent.cpp
|
||||||
Component.h
|
Component.h
|
||||||
Component.cpp
|
Component.cpp
|
||||||
|
MyComponent.h
|
||||||
|
MyComponent.cpp
|
||||||
|
MyOtherComponent.h
|
||||||
|
MyOtherComponent.cpp
|
||||||
PrimitiveComponent.cpp
|
PrimitiveComponent.cpp
|
||||||
PrimitiveComponent.h
|
PrimitiveComponent.h
|
||||||
PrimitiveUniformBufferLayout.h)
|
PrimitiveUniformBufferLayout.h)
|
||||||
@@ -5,11 +5,16 @@
|
|||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
CameraComponent::CameraComponent()
|
CameraComponent::CameraComponent()
|
||||||
: bNeedsViewBuild(true)
|
: aspectRatio(0)
|
||||||
|
, fieldOfView(0)
|
||||||
|
, bNeedsViewBuild(true)
|
||||||
, bNeedsProjectionBuild(true)
|
, bNeedsProjectionBuild(true)
|
||||||
, originPoint(0, 0, 0)
|
, originPoint(0, 0, 0)
|
||||||
, cameraPosition(0, 0, 50)
|
, cameraPosition(0, 0, 50)
|
||||||
|
, eye(Vector())
|
||||||
|
, projectionMatrix(Matrix4())
|
||||||
|
, viewMatrix(Matrix4())
|
||||||
{
|
{
|
||||||
distance = 50;
|
distance = 50;
|
||||||
rotationX = 0;
|
rotationX = 0;
|
||||||
|
|||||||
@@ -13,9 +13,38 @@ Component::Component()
|
|||||||
Component::~Component()
|
Component::~Component()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void Component::tick(float)
|
|
||||||
|
void Component::launchStart()
|
||||||
{
|
{
|
||||||
|
for(auto child : children)
|
||||||
|
{
|
||||||
|
child->launchStart();
|
||||||
|
}
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array<Job> Component::launchTick(float deltaTime) const
|
||||||
|
{
|
||||||
|
Array<Job> result;
|
||||||
|
for(auto child : children)
|
||||||
|
{
|
||||||
|
result.addAll(child->launchTick(deltaTime));
|
||||||
|
}
|
||||||
|
result.add(tick(deltaTime));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<Job> Component::launchUpdate()
|
||||||
|
{
|
||||||
|
Array<Job> result;
|
||||||
|
for(auto child : children)
|
||||||
|
{
|
||||||
|
result.addAll(child->launchUpdate());
|
||||||
|
}
|
||||||
|
result.add(update());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
PComponent Component::getParent()
|
PComponent Component::getParent()
|
||||||
{
|
{
|
||||||
return parent;
|
return parent;
|
||||||
@@ -32,6 +61,25 @@ PActor Component::getOwner()
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
const Array<PComponent>& Component::getChildComponents()
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::setParent(PComponent newParent)
|
||||||
|
{
|
||||||
|
parent = newParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::setOwner(PActor newOwner)
|
||||||
|
{
|
||||||
|
owner = newOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::addChildComponent(PComponent component)
|
||||||
|
{
|
||||||
|
children.add(component);
|
||||||
|
}
|
||||||
|
|
||||||
void Component::notifySceneAttach(PScene scene)
|
void Component::notifySceneAttach(PScene scene)
|
||||||
{
|
{
|
||||||
@@ -118,16 +166,6 @@ Transform Component::getTransform() const
|
|||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Component::setParent(PComponent newParent)
|
|
||||||
{
|
|
||||||
parent = newParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Component::setOwner(PActor newOwner)
|
|
||||||
{
|
|
||||||
owner = newOwner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Component::internalSetTransform(Vector newLocation, Quaternion newRotation)
|
void Component::internalSetTransform(Vector newLocation, Quaternion newRotation)
|
||||||
{
|
{
|
||||||
if (parent != nullptr)
|
if (parent != nullptr)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Math/Transform.h"
|
#include "Math/Transform.h"
|
||||||
|
#include "Scene/Util.h"
|
||||||
|
#include "ThreadPool.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
@@ -12,11 +14,18 @@ class Component
|
|||||||
public:
|
public:
|
||||||
Component();
|
Component();
|
||||||
virtual ~Component();
|
virtual ~Component();
|
||||||
void tick(float deltaTime);
|
void launchStart();
|
||||||
|
virtual void start() {};
|
||||||
|
Array<Job> launchTick(float deltaTime) const;
|
||||||
|
virtual Job tick(float deltaTime) const { co_return; }
|
||||||
|
Array<Job> launchUpdate();
|
||||||
|
virtual Job update() { co_return; }
|
||||||
PComponent getParent();
|
PComponent getParent();
|
||||||
PActor getOwner();
|
PActor getOwner();
|
||||||
|
const Array<PComponent>& getChildComponents();
|
||||||
void setParent(PComponent parent);
|
void setParent(PComponent parent);
|
||||||
void setOwner(PActor owner);
|
void setOwner(PActor owner);
|
||||||
|
void addChildComponent(PComponent component);
|
||||||
virtual void notifySceneAttach(PScene scene);
|
virtual void notifySceneAttach(PScene scene);
|
||||||
|
|
||||||
void setWorldLocation(Vector location);
|
void setWorldLocation(Vector location);
|
||||||
@@ -35,7 +44,30 @@ public:
|
|||||||
|
|
||||||
Transform getTransform() const;
|
Transform getTransform() const;
|
||||||
|
|
||||||
|
template<typename ComponentType>
|
||||||
|
RefPtr<ComponentType> getComponent()
|
||||||
|
{
|
||||||
|
return tryFindComponent<ComponentType>();
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
|
template<typename ComponentType>
|
||||||
|
RefPtr<ComponentType> tryFindComponent()
|
||||||
|
{
|
||||||
|
for(auto child : children)
|
||||||
|
{
|
||||||
|
RefPtr<ComponentType> result = child.cast<ComponentType>();
|
||||||
|
if(result != nullptr)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = parent->tryFindComponent<ComponentType>();
|
||||||
|
if(result != nullptr)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
void internalSetTransform(Vector newLocation, Quaternion newRotation);
|
void internalSetTransform(Vector newLocation, Quaternion newRotation);
|
||||||
void propagateTransformUpdate();
|
void propagateTransformUpdate();
|
||||||
void updateComponentTransform(Quaternion relativeRotationQuat);
|
void updateComponentTransform(Quaternion relativeRotationQuat);
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#include "MyComponent.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
MyComponent::MyComponent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyComponent::start()
|
||||||
|
{
|
||||||
|
otherComp = getComponent<MyOtherComponent>();
|
||||||
|
otherComp.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Job MyComponent::tick(float deltatime) const
|
||||||
|
{
|
||||||
|
writable++;
|
||||||
|
otherComp->data = *writable;
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Job MyComponent::update()
|
||||||
|
{
|
||||||
|
writable.update();
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Component.h"
|
||||||
|
#include "MyOtherComponent.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
class MyComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyComponent();
|
||||||
|
virtual void start();
|
||||||
|
virtual Job tick(float deltatime) const;
|
||||||
|
virtual Job update();
|
||||||
|
private:
|
||||||
|
Writable<PMyOtherComponent> otherComp;
|
||||||
|
Writable<uint32> writable = Writable<uint32>(0);
|
||||||
|
uint32 notWritable = 10;
|
||||||
|
};
|
||||||
|
DECLARE_REF(MyComponent);
|
||||||
|
} // namespace Seele
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include "MyOtherComponent.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
Job MyOtherComponent::tick(float deltaTime) const
|
||||||
|
{
|
||||||
|
std::cout << *data << std::endl;
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Job MyOtherComponent::update()
|
||||||
|
{
|
||||||
|
data.update();
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Component.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
class MyOtherComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Job tick(float deltaTime) const;
|
||||||
|
virtual Job update();
|
||||||
|
Writable<uint32> data = Writable<uint32>(0);
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
DEFINE_REF(MyOtherComponent);
|
||||||
|
} // namespace Seele
|
||||||
@@ -26,7 +26,7 @@ PrimitiveComponent::PrimitiveComponent(PMeshAsset asset)
|
|||||||
batch.useReverseCulling = false;
|
batch.useReverseCulling = false;
|
||||||
batch.useWireframe = false;
|
batch.useWireframe = false;
|
||||||
batch.vertexInput = assetMeshes[i]->vertexInput;
|
batch.vertexInput = assetMeshes[i]->vertexInput;
|
||||||
auto& batchElement = batch.elements.add();
|
MeshBatchElement batchElement;
|
||||||
batchElement.baseVertexIndex = 0;
|
batchElement.baseVertexIndex = 0;
|
||||||
batchElement.firstIndex = 0;
|
batchElement.firstIndex = 0;
|
||||||
batchElement.indexBuffer = assetMeshes[i]->indexBuffer;
|
batchElement.indexBuffer = assetMeshes[i]->indexBuffer;
|
||||||
@@ -35,6 +35,7 @@ PrimitiveComponent::PrimitiveComponent(PMeshAsset asset)
|
|||||||
batchElement.isInstanced = false;
|
batchElement.isInstanced = false;
|
||||||
batchElement.numInstances = 1;
|
batchElement.numInstances = 1;
|
||||||
batchElement.numPrimitives = assetMeshes[i]->indexBuffer->getNumIndices() / 3; //TODO: hardcoded
|
batchElement.numPrimitives = assetMeshes[i]->indexBuffer->getNumIndices() / 3; //TODO: hardcoded
|
||||||
|
batch.elements.push_back(batchElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ public:
|
|||||||
~PrimitiveComponent();
|
~PrimitiveComponent();
|
||||||
virtual void notifySceneAttach(PScene scene) override;
|
virtual void notifySceneAttach(PScene scene) override;
|
||||||
Matrix4 getRenderMatrix();
|
Matrix4 getRenderMatrix();
|
||||||
const Array<StaticMeshBatch>& getStaticMeshes()
|
std::vector<StaticMeshBatch>& getStaticMeshes()
|
||||||
{
|
{
|
||||||
return staticMeshes;
|
return staticMeshes;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Array<PMaterialAsset> materials;
|
std::vector<PMaterialAsset> materials;
|
||||||
Gfx::PUniformBuffer uniformBuffer;
|
Gfx::PUniformBuffer uniformBuffer;
|
||||||
Array<StaticMeshBatch> staticMeshes;
|
std::vector<StaticMeshBatch> staticMeshes;
|
||||||
friend class Scene;
|
friend class Scene;
|
||||||
};
|
};
|
||||||
DEFINE_REF(PrimitiveComponent)
|
DEFINE_REF(PrimitiveComponent)
|
||||||
|
|||||||
@@ -33,19 +33,39 @@ Scene::~Scene()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::tick(double)
|
void Scene::start()
|
||||||
{
|
{
|
||||||
|
for(auto actor : rootActors)
|
||||||
|
{
|
||||||
|
actor->launchStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Job Scene::beginUpdate(double deltaTime)
|
||||||
|
{
|
||||||
|
for(auto actor : rootActors)
|
||||||
|
{
|
||||||
|
co_await Job::all(actor->launchTick(static_cast<float>(deltaTime)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Job Scene::commitUpdate()
|
||||||
|
{
|
||||||
|
for(auto actor : rootActors)
|
||||||
|
{
|
||||||
|
co_await Job::all(actor->launchUpdate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::addActor(PActor actor)
|
void Scene::addActor(PActor actor)
|
||||||
{
|
{
|
||||||
rootActors.add(actor);
|
rootActors.push_back(actor);
|
||||||
actor->notifySceneAttach(this);
|
actor->notifySceneAttach(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
|
void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
|
||||||
{
|
{
|
||||||
primitives.add(comp);
|
primitives.push_back(comp);
|
||||||
for(auto& batch : comp->getStaticMeshes())
|
for(auto& batch : comp->getStaticMeshes())
|
||||||
{
|
{
|
||||||
PrimitiveUniformBuffer data;
|
PrimitiveUniformBuffer data;
|
||||||
@@ -62,6 +82,6 @@ void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
|
|||||||
{
|
{
|
||||||
element.uniformBuffer = uniformBuffer;
|
element.uniformBuffer = uniformBuffer;
|
||||||
}
|
}
|
||||||
staticMeshes.add(batch);
|
staticMeshes.push_back(batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,17 +38,19 @@ class Scene
|
|||||||
public:
|
public:
|
||||||
Scene(Gfx::PGraphics graphics);
|
Scene(Gfx::PGraphics graphics);
|
||||||
~Scene();
|
~Scene();
|
||||||
void tick(double deltaTime);
|
void start();
|
||||||
|
Job beginUpdate(double deltaTime);
|
||||||
|
Job commitUpdate();
|
||||||
void addActor(PActor actor);
|
void addActor(PActor actor);
|
||||||
void addPrimitiveComponent(PPrimitiveComponent comp);
|
void addPrimitiveComponent(PPrimitiveComponent comp);
|
||||||
|
|
||||||
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
const std::vector<PPrimitiveComponent>& getPrimitives() const { return primitives; }
|
||||||
const Array<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
const std::vector<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
|
||||||
const LightEnv& getLightBuffer() const { return lightEnv; }
|
const LightEnv& getLightBuffer() const { return lightEnv; }
|
||||||
private:
|
private:
|
||||||
Array<StaticMeshBatch> staticMeshes;
|
std::vector<StaticMeshBatch> staticMeshes;
|
||||||
Array<PActor> rootActors;
|
std::vector<PActor> rootActors;
|
||||||
Array<PPrimitiveComponent> primitives;
|
std::vector<PPrimitiveComponent> primitives;
|
||||||
LightEnv lightEnv;
|
LightEnv lightEnv;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,25 +26,25 @@ SceneUpdater::~SceneUpdater()
|
|||||||
|
|
||||||
void SceneUpdater::registerComponentUpdate(PComponent component)
|
void SceneUpdater::registerComponentUpdate(PComponent component)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(pendingUpdatesLock);
|
std::scoped_lock lck(pendingUpdatesLock);
|
||||||
updatesRan.add([component](float delta) mutable { component->tick(delta); });
|
updatesRan.add([component](float delta) mutable { component->tick(delta); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneUpdater::registerActorUpdate(PActor actor)
|
void SceneUpdater::registerActorUpdate(PActor actor)
|
||||||
{
|
{
|
||||||
std::unique_lock lck(pendingUpdatesLock);
|
std::scoped_lock lck(pendingUpdatesLock);
|
||||||
updatesRan.add([actor](float delta) mutable { actor->tick(delta); });
|
updatesRan.add([actor](float delta) mutable { actor->tick(delta); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneUpdater::runUpdates(float delta)
|
void SceneUpdater::runUpdates(float delta)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::unique_lock pendingLock(pendingUpdatesLock);
|
std::scoped_lock pendingLock(pendingUpdatesLock);
|
||||||
frameDelta = delta;
|
frameDelta = delta;
|
||||||
pendingUpdates = std::move(updatesRan);
|
pendingUpdates = std::move(updatesRan);
|
||||||
updatesRan = List<std::function<void(float)>>();
|
updatesRan = List<std::function<void(float)>>();
|
||||||
|
|
||||||
std::unique_lock lck(frameFinishedLock);
|
std::scoped_lock lck(frameFinishedLock);
|
||||||
pendingLock.unlock();
|
pendingLock.unlock();
|
||||||
pendingUpdatesSem.release(pendingUpdates.size());
|
pendingUpdatesSem.release(pendingUpdates.size());
|
||||||
frameFinishedCV.wait(lck);
|
frameFinishedCV.wait(lck);
|
||||||
@@ -57,18 +57,18 @@ void SceneUpdater::work()
|
|||||||
pendingUpdatesSem.acquire();
|
pendingUpdatesSem.acquire();
|
||||||
std::function<void(float)> function;
|
std::function<void(float)> function;
|
||||||
{
|
{
|
||||||
std::unique_lock lck(pendingUpdatesLock);
|
std::scoped_lock lck(pendingUpdatesLock);
|
||||||
function = std::move(pendingUpdates.front());
|
function = std::move(pendingUpdates.front());
|
||||||
pendingUpdates.popFront();
|
pendingUpdates.popFront();
|
||||||
if(pendingUpdates.empty())
|
if(pendingUpdates.empty())
|
||||||
{
|
{
|
||||||
std::unique_lock lck(frameFinishedLock);
|
std::scoped_lock lck(frameFinishedLock);
|
||||||
frameFinishedCV.notify_all();
|
frameFinishedCV.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function(frameDelta);
|
function(frameDelta);
|
||||||
{
|
{
|
||||||
std::unique_lock lck(pendingUpdatesLock);
|
std::scoped_lock lck(pendingUpdatesLock);
|
||||||
updatesRan.add(std::move(function));
|
updatesRan.add(std::move(function));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "MinimalEngine.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
class Writable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Writable()
|
||||||
|
{}
|
||||||
|
explicit Writable(T initialData)
|
||||||
|
: data(initialData)
|
||||||
|
, toBeWritten(initialData)
|
||||||
|
{}
|
||||||
|
Writable(const Writable& other) = delete;
|
||||||
|
Writable(Writable&& other) = default;
|
||||||
|
~Writable() = default;
|
||||||
|
Writable& operator=(const Writable& other) = delete;
|
||||||
|
Writable& operator=(Writable&& other) = default;
|
||||||
|
const Writable& operator=(const T& other) const
|
||||||
|
{
|
||||||
|
deferWrite(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Writable& operator=(T&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(std::move(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator+(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data + std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator-(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data - std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator*(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data * std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator/(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data / std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator%(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data % std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator^(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data ^ std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator&(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data & std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Other>
|
||||||
|
const Writable& operator|(Other&& other) const
|
||||||
|
{
|
||||||
|
deferWrite(data | std::forward<Other>(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename Type>
|
||||||
|
bool operator==(Type other) const
|
||||||
|
{
|
||||||
|
return data == other.data;
|
||||||
|
}
|
||||||
|
template<typename Type>
|
||||||
|
bool operator<=>(Type other) const
|
||||||
|
{
|
||||||
|
return data <=> other.data;
|
||||||
|
}
|
||||||
|
const Writable& operator++() const
|
||||||
|
{
|
||||||
|
deferWrite(data+1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const Writable& operator--() const
|
||||||
|
{
|
||||||
|
deferWrite(data-1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Writable&& operator++(int) const
|
||||||
|
{
|
||||||
|
Writable tmp(data);
|
||||||
|
++*this;
|
||||||
|
return std::move(tmp);
|
||||||
|
}
|
||||||
|
Writable&& operator--(int) const
|
||||||
|
{
|
||||||
|
Writable tmp(data);
|
||||||
|
--*this;
|
||||||
|
return std::move(tmp);
|
||||||
|
}
|
||||||
|
const T& operator*() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
const T& get() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
const T& operator->() const
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
// lock should not be necessary, but lets keep it for now
|
||||||
|
std::scoped_lock lock(dataLock);
|
||||||
|
data = toBeWritten;
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
template<typename Type>
|
||||||
|
void deferWrite(Type&& newValue) const
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(dataLock);
|
||||||
|
assert(!dirty);
|
||||||
|
toBeWritten = std::forward<Type>(newValue);
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
mutable bool dirty = false;
|
||||||
|
mutable std::mutex dataLock;
|
||||||
|
mutable T toBeWritten;
|
||||||
|
T data;
|
||||||
|
};
|
||||||
|
template<typename A>
|
||||||
|
concept writable = requires(A&& a)
|
||||||
|
{
|
||||||
|
a.update();
|
||||||
|
};
|
||||||
|
} // namespace Seele
|
||||||
+51
-43
@@ -6,7 +6,7 @@ using namespace Seele;
|
|||||||
std::atomic_uint64_t Seele::globalCounter;
|
std::atomic_uint64_t Seele::globalCounter;
|
||||||
|
|
||||||
Event::Event()
|
Event::Event()
|
||||||
: flag(new std::atomic_bool())
|
: flag(std::make_shared<std::atomic_bool>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,7 +16,8 @@ Event::Event(nullptr_t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Event::Event(const std::string &name)
|
Event::Event(const std::string &name)
|
||||||
: name(name), flag(new std::atomic_bool())
|
: name(name)
|
||||||
|
, flag(std::make_shared<std::atomic_bool>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,75 +49,80 @@ ThreadPool::ThreadPool(uint32 threadCount)
|
|||||||
ThreadPool::~ThreadPool()
|
ThreadPool::~ThreadPool()
|
||||||
{
|
{
|
||||||
running.store(false);
|
running.store(false);
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(jobQueueLock);
|
||||||
|
jobQueueCV.notify_all();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(mainJobLock);
|
||||||
|
mainJobCV.notify_all();
|
||||||
|
}
|
||||||
for (auto &thread : workers)
|
for (auto &thread : workers)
|
||||||
{
|
{
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
workers.clear();
|
||||||
|
waitingJobs.clear();
|
||||||
|
waitingMainJobs.clear();
|
||||||
}
|
}
|
||||||
void ThreadPool::enqueueWaiting(Event &event, Promise* job)
|
void ThreadPool::enqueueWaiting(Event &event, Promise* job)
|
||||||
{
|
{
|
||||||
assert(!job->done());
|
assert(!job->done());
|
||||||
if(event == nullptr)
|
std::scoped_lock lock(waitingLock);
|
||||||
{
|
//std::cout << "Job " << job->finishedEvent.name << " waiting on event " << event.name << std::endl;
|
||||||
std::unique_lock lock(jobQueueLock);
|
waitingJobs[event].push_back(job);
|
||||||
//std::cout << "Queueing job " << job->finishedEvent.name << std::endl;
|
|
||||||
jobQueue.add(job);
|
|
||||||
jobQueueCV.notify_one();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::unique_lock lock(waitingLock);
|
|
||||||
//std::cout << "Job " << job->finishedEvent.name << " waiting on event " << event.name << std::endl;
|
|
||||||
waitingJobs[event].add(job);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void ThreadPool::enqueueWaiting(Event &event, MainPromise* job)
|
void ThreadPool::enqueueWaiting(Event &event, MainPromise* job)
|
||||||
{
|
{
|
||||||
assert(!job->done());
|
assert(!job->done());
|
||||||
if(event == nullptr || event)
|
std::scoped_lock lock(waitingMainLock);
|
||||||
{
|
//std::cout << job->finishedEvent.name << " waiting on event " << event.name << std::endl;
|
||||||
std::unique_lock lock(mainJobLock);
|
waitingMainJobs[event].push_back(job);
|
||||||
//std::cout << "Queueing job " << job->finishedEvent.name << std::endl;
|
}
|
||||||
mainJobs.add(job);
|
void ThreadPool::scheduleJob(Promise* job)
|
||||||
mainJobCV.notify_one();
|
{
|
||||||
}
|
assert(!job->done());
|
||||||
else
|
std::scoped_lock lock(jobQueueLock);
|
||||||
{
|
//std::cout << "Queueing job " << job->finishedEvent.name << std::endl;
|
||||||
std::unique_lock lock(waitingMainLock);
|
jobQueue.push_back(job);
|
||||||
//std::cout << job->finishedEvent.name << " waiting on event " << event.name << std::endl;
|
jobQueueCV.notify_one();
|
||||||
waitingMainJobs[event].add(job);
|
}
|
||||||
}
|
void ThreadPool::scheduleJob(MainPromise* job)
|
||||||
|
{
|
||||||
|
assert(!job->done());
|
||||||
|
std::scoped_lock lock(mainJobLock);
|
||||||
|
//std::cout << "Queueing job " << job->finishedEvent.name << std::endl;
|
||||||
|
mainJobs.push_back(job);
|
||||||
|
mainJobCV.notify_one();
|
||||||
}
|
}
|
||||||
void ThreadPool::notify(Event &event)
|
void ThreadPool::notify(Event &event)
|
||||||
{
|
{
|
||||||
//std::cout << "Event " << event.name << " raised" << std::endl;
|
//std::cout << "Event " << event.name << " raised" << std::endl;
|
||||||
{
|
{
|
||||||
std::unique_lock lock(jobQueueLock);
|
std::scoped_lock lock(jobQueueLock, waitingLock);
|
||||||
std::unique_lock lock2(waitingLock);
|
std::list<Promise*> jobs = std::move(waitingJobs[event]);
|
||||||
List<Promise*> &jobs = waitingJobs[event];
|
waitingJobs.erase(event);
|
||||||
for (auto &job : jobs)
|
for (auto &job : jobs)
|
||||||
{
|
{
|
||||||
//assert(job.id != -1ull);
|
//assert(job.id != -1ull);
|
||||||
//std::cout << "Waking up " << job->finishedEvent.name << std::endl;
|
//std::cout << "Waking up " << job->finishedEvent.name << std::endl;
|
||||||
job->state = Promise::State::SCHEDULED;
|
job->state = Promise::State::SCHEDULED;
|
||||||
jobQueue.add(job);
|
jobQueue.push_back(job);
|
||||||
jobQueueCV.notify_one();
|
jobQueueCV.notify_one();
|
||||||
}
|
}
|
||||||
waitingJobs.erase(event);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mainJobLock);
|
std::scoped_lock lock(mainJobLock, waitingMainLock);
|
||||||
std::unique_lock lock2(waitingMainLock);
|
std::list<MainPromise*> jobs = std::move(waitingMainJobs[event]);
|
||||||
List<MainPromise*> &jobs = waitingMainJobs[event];
|
waitingMainJobs.erase(event);
|
||||||
for (auto &job : jobs)
|
for (auto &job : jobs)
|
||||||
{
|
{
|
||||||
//assert(job.id != -1ull);
|
//assert(job.id != -1ull);
|
||||||
//std::cout << "Waking up main " << job->finishedEvent.name << std::endl;
|
//std::cout << "Waking up main " << job->finishedEvent.name << std::endl;
|
||||||
job->state = MainPromise::State::SCHEDULED;
|
job->state = MainPromise::State::SCHEDULED;
|
||||||
mainJobs.add(job);
|
mainJobs.push_back(job);
|
||||||
mainJobCV.notify_one();
|
mainJobCV.notify_one();
|
||||||
}
|
}
|
||||||
waitingMainJobs.erase(event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ThreadPool::threadLoop(const bool mainThread)
|
void ThreadPool::threadLoop(const bool mainThread)
|
||||||
@@ -134,7 +140,8 @@ void ThreadPool::threadLoop(const bool mainThread)
|
|||||||
}
|
}
|
||||||
if (!mainJobs.empty())
|
if (!mainJobs.empty())
|
||||||
{
|
{
|
||||||
job = mainJobs.retrieve();
|
job = mainJobs.front();
|
||||||
|
mainJobs.pop_front();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -144,7 +151,7 @@ void ThreadPool::threadLoop(const bool mainThread)
|
|||||||
job->resume();
|
job->resume();
|
||||||
if (job->done())
|
if (job->done())
|
||||||
{
|
{
|
||||||
job->raise();
|
job->finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -158,7 +165,8 @@ void ThreadPool::threadLoop(const bool mainThread)
|
|||||||
}
|
}
|
||||||
if (!jobQueue.empty())
|
if (!jobQueue.empty())
|
||||||
{
|
{
|
||||||
job = jobQueue.retrieve();
|
job = jobQueue.front();
|
||||||
|
jobQueue.pop_front();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -167,9 +175,9 @@ void ThreadPool::threadLoop(const bool mainThread)
|
|||||||
}
|
}
|
||||||
//std::cout << "Starting job " << job.id << std::endl;
|
//std::cout << "Starting job " << job.id << std::endl;
|
||||||
job->resume();
|
job->resume();
|
||||||
if (job->done())
|
if(job->done())
|
||||||
{
|
{
|
||||||
job->raise();
|
job->finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-25
@@ -16,6 +16,7 @@ public:
|
|||||||
Event();
|
Event();
|
||||||
Event(nullptr_t);
|
Event(nullptr_t);
|
||||||
Event(const std::string& name);
|
Event(const std::string& name);
|
||||||
|
~Event() = default;
|
||||||
auto operator<=>(const Event& other) const
|
auto operator<=>(const Event& other) const
|
||||||
{
|
{
|
||||||
return flag <=> other.flag;
|
return flag <=> other.flag;
|
||||||
@@ -41,7 +42,7 @@ public:
|
|||||||
constexpr void await_resume() {}
|
constexpr void await_resume() {}
|
||||||
private:
|
private:
|
||||||
std::string name;
|
std::string name;
|
||||||
RefPtr<std::atomic_bool> flag;
|
std::shared_ptr<std::atomic_bool> flag;
|
||||||
friend class ThreadPool;
|
friend class ThreadPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,6 +66,13 @@ struct JobPromiseBase
|
|||||||
id = globalCounter++;
|
id = globalCounter++;
|
||||||
finishedEvent = Event(std::format("Job {}", id));
|
finishedEvent = Event(std::format("Job {}", id));
|
||||||
}
|
}
|
||||||
|
~JobPromiseBase()
|
||||||
|
{
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
handle.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
JobBase<MainJob> get_return_object() noexcept;
|
JobBase<MainJob> get_return_object() noexcept;
|
||||||
|
|
||||||
inline auto initial_suspend() noexcept;
|
inline auto initial_suspend() noexcept;
|
||||||
@@ -78,7 +86,6 @@ struct JobPromiseBase
|
|||||||
|
|
||||||
void resume()
|
void resume()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(promiseLock);
|
|
||||||
if(!handle || handle.done() || executing())
|
if(!handle || handle.done() || executing())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -88,10 +95,9 @@ struct JobPromiseBase
|
|||||||
}
|
}
|
||||||
void setContinuation(JobPromiseBase* cont)
|
void setContinuation(JobPromiseBase* cont)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(promiseLock);
|
std::scoped_lock lock(promiseLock, cont->promiseLock);
|
||||||
std::unique_lock lock2(cont->promiseLock);
|
|
||||||
continuation = cont->handle;
|
continuation = cont->handle;
|
||||||
cont->precondition = finishedEvent;
|
cont->state = State::SCHEDULED;
|
||||||
}
|
}
|
||||||
bool done()
|
bool done()
|
||||||
{
|
{
|
||||||
@@ -113,15 +119,15 @@ struct JobPromiseBase
|
|||||||
{
|
{
|
||||||
return state == State::READY;
|
return state == State::READY;
|
||||||
}
|
}
|
||||||
void raise()
|
void finalize()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(promiseLock);
|
std::scoped_lock lock(promiseLock);
|
||||||
state = State::DONE;
|
state = State::DONE;
|
||||||
finishedEvent.raise();
|
finishedEvent.raise();
|
||||||
}
|
}
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(promiseLock);
|
std::scoped_lock lock(promiseLock);
|
||||||
finishedEvent.reset();
|
finishedEvent.reset();
|
||||||
}
|
}
|
||||||
void enqueue(Event& event)
|
void enqueue(Event& event)
|
||||||
@@ -136,13 +142,12 @@ struct JobPromiseBase
|
|||||||
}
|
}
|
||||||
void schedule()
|
void schedule()
|
||||||
{
|
{
|
||||||
std::unique_lock lock(promiseLock);
|
std::scoped_lock lock(promiseLock);
|
||||||
if(!handle || done() || !ready())
|
if(!handle || done() || !ready())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state = (precondition == nullptr) ? State::SCHEDULED : State::WAITING;
|
getGlobalThreadPool().scheduleJob(this);
|
||||||
getGlobalThreadPool().enqueueWaiting(precondition, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mutex promiseLock;
|
std::mutex promiseLock;
|
||||||
@@ -150,7 +155,6 @@ struct JobPromiseBase
|
|||||||
std::coroutine_handle<> continuation = std::noop_coroutine();
|
std::coroutine_handle<> continuation = std::noop_coroutine();
|
||||||
uint64 id;
|
uint64 id;
|
||||||
Event finishedEvent;
|
Event finishedEvent;
|
||||||
Event precondition = nullptr;
|
|
||||||
State state = State::READY;
|
State state = State::READY;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -193,13 +197,9 @@ public:
|
|||||||
{
|
{
|
||||||
return promise->done();
|
return promise->done();
|
||||||
}
|
}
|
||||||
void raise()
|
void finalize()
|
||||||
{
|
{
|
||||||
promise->raise();
|
promise->finalize();
|
||||||
}
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
promise->reset();
|
|
||||||
}
|
}
|
||||||
Event operator co_await()
|
Event operator co_await()
|
||||||
{
|
{
|
||||||
@@ -245,30 +245,32 @@ using Promise = JobPromiseBase<false>;
|
|||||||
class ThreadPool
|
class ThreadPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency());
|
ThreadPool(uint32 threadCount = 1);
|
||||||
virtual ~ThreadPool();
|
virtual ~ThreadPool();
|
||||||
// Adds a job to the waiting queue for event, or directly to the job queue if event is nullptr
|
// Adds a job to the waiting queue for event
|
||||||
void enqueueWaiting(Event& event, Promise* job);
|
void enqueueWaiting(Event& event, Promise* job);
|
||||||
// Adds a job to the waiting queue for event, or directly to the job queue if event is nullptr
|
// Adds a job to the waiting queue for event
|
||||||
void enqueueWaiting(Event& event, MainPromise* job);
|
void enqueueWaiting(Event& event, MainPromise* job);
|
||||||
|
void scheduleJob(Promise* job);
|
||||||
|
void scheduleJob(MainPromise* job);
|
||||||
void notify(Event& event);
|
void notify(Event& event);
|
||||||
void threadLoop(const bool isMainThread);
|
void threadLoop(const bool isMainThread);
|
||||||
private:
|
private:
|
||||||
std::atomic_bool running;
|
std::atomic_bool running;
|
||||||
std::vector<std::thread> workers;
|
std::vector<std::thread> workers;
|
||||||
|
|
||||||
List<MainPromise*> mainJobs;
|
std::list<MainPromise*> mainJobs;
|
||||||
std::mutex mainJobLock;
|
std::mutex mainJobLock;
|
||||||
std::condition_variable mainJobCV;
|
std::condition_variable mainJobCV;
|
||||||
|
|
||||||
List<Promise*> jobQueue;
|
std::list<Promise*> jobQueue;
|
||||||
std::mutex jobQueueLock;
|
std::mutex jobQueueLock;
|
||||||
std::condition_variable jobQueueCV;
|
std::condition_variable jobQueueCV;
|
||||||
|
|
||||||
std::map<Event, List<MainPromise*>> waitingMainJobs;
|
std::map<Event, std::list<MainPromise*>> waitingMainJobs;
|
||||||
std::mutex waitingMainLock;
|
std::mutex waitingMainLock;
|
||||||
|
|
||||||
std::map<Event, List<Promise*>> waitingJobs;
|
std::map<Event, std::list<Promise*>> waitingJobs;
|
||||||
std::mutex waitingLock;
|
std::mutex waitingLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -283,6 +285,7 @@ inline auto JobPromiseBase<MainJob>::initial_suspend() noexcept
|
|||||||
{
|
{
|
||||||
return std::suspend_always{};
|
return std::suspend_always{};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool MainJob>
|
template<bool MainJob>
|
||||||
inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept
|
inline auto JobPromiseBase<MainJob>::final_suspend() const noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using namespace Seele;
|
|||||||
using namespace Seele::UI;
|
using namespace Seele::UI;
|
||||||
|
|
||||||
Element::Element()
|
Element::Element()
|
||||||
|
: dirty(false)
|
||||||
|
, enabled(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ RenderHierarchy::~RenderHierarchy()
|
|||||||
|
|
||||||
void RenderHierarchy::addElement(PElement addedElement)
|
void RenderHierarchy::addElement(PElement addedElement)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(updateLock);
|
std::scoped_lock lock(updateLock);
|
||||||
updates.add(new AddElementRenderHierarchyUpdate{
|
updates.add(new AddElementRenderHierarchyUpdate{
|
||||||
addedElement.getHandle(),
|
addedElement.getHandle(),
|
||||||
addedElement->getParent().getHandle()
|
addedElement->getParent().getHandle()
|
||||||
@@ -40,7 +40,7 @@ void RenderHierarchy::addElement(PElement addedElement)
|
|||||||
|
|
||||||
void RenderHierarchy::removeElement(PElement elementToRemove)
|
void RenderHierarchy::removeElement(PElement elementToRemove)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(updateLock);
|
std::scoped_lock lock(updateLock);
|
||||||
updates.add(new RemoveElementRenderHierarchyUpdate{
|
updates.add(new RemoveElementRenderHierarchyUpdate{
|
||||||
elementToRemove.getHandle(),
|
elementToRemove.getHandle(),
|
||||||
});
|
});
|
||||||
@@ -48,7 +48,7 @@ void RenderHierarchy::removeElement(PElement elementToRemove)
|
|||||||
|
|
||||||
void RenderHierarchy::moveElement(PElement elementToMove, PElement newParent)
|
void RenderHierarchy::moveElement(PElement elementToMove, PElement newParent)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(updateLock);
|
std::scoped_lock lock(updateLock);
|
||||||
updates.add(new AddElementRenderHierarchyUpdate{
|
updates.add(new AddElementRenderHierarchyUpdate{
|
||||||
elementToMove.getHandle(),
|
elementToMove.getHandle(),
|
||||||
newParent.getHandle()
|
newParent.getHandle()
|
||||||
@@ -62,7 +62,7 @@ void RenderHierarchy::updateHierarchy()
|
|||||||
{
|
{
|
||||||
List<RenderHierarchyUpdate*> localUpdates;
|
List<RenderHierarchyUpdate*> localUpdates;
|
||||||
{ // make a local copy of the updates so we dont hold the lock for too long
|
{ // make a local copy of the updates so we dont hold the lock for too long
|
||||||
std::unique_lock lock(updateLock);
|
std::scoped_lock lock(updateLock);
|
||||||
localUpdates = updates;
|
localUpdates = updates;
|
||||||
updates.clear();
|
updates.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,14 @@ InspectorView::~InspectorView()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorView::beginUpdate()
|
Job InspectorView::beginUpdate()
|
||||||
{
|
{
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorView::update()
|
Job InspectorView::update()
|
||||||
{
|
{
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorView::commitUpdate()
|
void InspectorView::commitUpdate()
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ public:
|
|||||||
InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo);
|
InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo);
|
||||||
virtual ~InspectorView();
|
virtual ~InspectorView();
|
||||||
|
|
||||||
virtual void beginUpdate() override;
|
virtual Job beginUpdate() override;
|
||||||
virtual void update() override;
|
virtual Job update() override;
|
||||||
virtual void commitUpdate() override;
|
virtual void commitUpdate() override;
|
||||||
|
|
||||||
virtual void prepareRender() override;
|
virtual void prepareRender() override;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "Asset/AssetRegistry.h"
|
#include "Asset/AssetRegistry.h"
|
||||||
#include "Scene/Actor/CameraActor.h"
|
#include "Scene/Actor/CameraActor.h"
|
||||||
#include "Scene/Components/CameraComponent.h"
|
#include "Scene/Components/CameraComponent.h"
|
||||||
|
#include "Scene/Components/MyComponent.h"
|
||||||
|
#include "Scene/Components/MyOtherComponent.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -28,18 +30,23 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
|
|||||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ely\\Ely.fbx");
|
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ely\\Ely.fbx");
|
||||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Cube\\cube.obj");
|
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Cube\\cube.obj");
|
||||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Plane\\plane.fbx");
|
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Plane\\plane.fbx");
|
||||||
srand(time(NULL));
|
|
||||||
for(uint32 i = 0; i < 100; ++i)
|
PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka"));
|
||||||
{
|
ayaka->addWorldTranslation(Vector(0, 0, 0));
|
||||||
PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka"));
|
ayaka->setWorldScale(Vector(10, 10, 10));
|
||||||
ayaka->addWorldTranslation(Vector(((float)rand() / RAND_MAX) * 100, 0, ((float)rand()/RAND_MAX) * 100));
|
scene->addPrimitiveComponent(ayaka);
|
||||||
ayaka->setWorldScale(Vector(10, 10, 10));
|
|
||||||
scene->addPrimitiveComponent(ayaka);
|
|
||||||
}
|
|
||||||
|
|
||||||
PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane"));
|
PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane"));
|
||||||
plane->setWorldScale(Vector(100, 100, 100));
|
plane->setWorldScale(Vector(100, 100, 100));
|
||||||
scene->addPrimitiveComponent(plane);
|
scene->addPrimitiveComponent(plane);
|
||||||
|
|
||||||
|
PMyComponent myComp = new MyComponent();
|
||||||
|
PMyOtherComponent myOtherComp = new MyOtherComponent();
|
||||||
|
PActor actor = new Actor();
|
||||||
|
actor->setRootComponent(myComp);
|
||||||
|
myComp->addChildComponent(myOtherComp);
|
||||||
|
scene->addActor(actor);
|
||||||
|
scene->start();
|
||||||
|
|
||||||
PRenderGraphResources resources = new RenderGraphResources();
|
PRenderGraphResources resources = new RenderGraphResources();
|
||||||
depthPrepass.setResources(resources);
|
depthPrepass.setResources(resources);
|
||||||
@@ -59,13 +66,16 @@ Seele::SceneView::~SceneView()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneView::beginUpdate()
|
Job SceneView::beginUpdate()
|
||||||
{
|
{
|
||||||
scene->tick(Gfx::currentFrameDelta);
|
co_await scene->beginUpdate(Gfx::currentFrameDelta);
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneView::update()
|
Job SceneView::update()
|
||||||
{
|
{
|
||||||
|
co_await scene->commitUpdate();
|
||||||
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneView::commitUpdate()
|
void SceneView::commitUpdate()
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ class SceneView : public View
|
|||||||
public:
|
public:
|
||||||
SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
|
SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
|
||||||
~SceneView();
|
~SceneView();
|
||||||
virtual void beginUpdate() override;
|
virtual Job beginUpdate() override;
|
||||||
virtual void update() override;
|
virtual Job update() override;
|
||||||
virtual void commitUpdate() override;
|
virtual void commitUpdate() override;
|
||||||
|
|
||||||
virtual void prepareRender() override;
|
virtual void prepareRender() override;
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ public:
|
|||||||
virtual ~View();
|
virtual ~View();
|
||||||
|
|
||||||
// These are called from the view thread, and handle updating game data
|
// These are called from the view thread, and handle updating game data
|
||||||
virtual void beginUpdate() = 0;
|
virtual Job beginUpdate() = 0;
|
||||||
virtual void update() = 0;
|
virtual Job update() = 0;
|
||||||
// End frame is called with a lock, so it is safe to write to shared memory
|
// End frame is called with a lock, so it is safe to write to shared memory
|
||||||
virtual void commitUpdate() = 0;
|
virtual void commitUpdate() = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ MainJob Window::render()
|
|||||||
co_await windowView->updateFinished;
|
co_await windowView->updateFinished;
|
||||||
windowView->updateFinished.reset();
|
windowView->updateFinished.reset();
|
||||||
{
|
{
|
||||||
std::unique_lock lock(windowView->workerMutex);
|
std::scoped_lock lock(windowView->workerMutex);
|
||||||
windowView->view->prepareRender();
|
windowView->view->prepareRender();
|
||||||
}
|
}
|
||||||
windowView->view->render();
|
windowView->view->render();
|
||||||
@@ -78,7 +78,7 @@ Job Window::viewWorker(size_t viewIndex)
|
|||||||
windowView->view->beginUpdate();
|
windowView->view->beginUpdate();
|
||||||
windowView->view->update();
|
windowView->view->update();
|
||||||
{
|
{
|
||||||
std::unique_lock lock(windowView->workerMutex);
|
std::scoped_lock lock(windowView->workerMutex);
|
||||||
windowView->view->commitUpdate();
|
windowView->view->commitUpdate();
|
||||||
}
|
}
|
||||||
//std::cout << "Update completed" << std::endl;
|
//std::cout << "Update completed" << std::endl;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void WindowManager::notifyWindowClosed(PWindow window)
|
|||||||
windows.remove(windows.find(window));
|
windows.remove(windows.find(window));
|
||||||
if(windows.empty())
|
if(windows.empty())
|
||||||
{
|
{
|
||||||
std::unique_lock lock(windowsLock);
|
std::scoped_lock lock(windowsLock);
|
||||||
windowsCV.notify_all();
|
windowsCV.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,131 +12,170 @@ BOOST_AUTO_TEST_SUITE(Array_Suite)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(empty_constructur)
|
BOOST_AUTO_TEST_CASE(empty_constructur)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
BOOST_CHECK_EQUAL(array.size(), 0);
|
BOOST_CHECK_EQUAL(array.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(initialial_size)
|
BOOST_AUTO_TEST_CASE(initialial_size)
|
||||||
{
|
{
|
||||||
Array<uint8> array(3);
|
Array<uint8> array(3);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 3);
|
BOOST_CHECK_EQUAL(array.size(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(resize)
|
BOOST_AUTO_TEST_CASE(resize)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
array.add(2);
|
array.add(2);
|
||||||
array.add(3);
|
array.add(3);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 2);
|
BOOST_CHECK_EQUAL(array.size(), 2);
|
||||||
array.resize(5);
|
array.resize(5);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 5);
|
BOOST_CHECK_EQUAL(array.size(), 5);
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(clear)
|
BOOST_AUTO_TEST_CASE(clear)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
array.add(3);
|
array.add(3);
|
||||||
array.add(2);
|
array.add(2);
|
||||||
array.add(6);
|
array.add(6);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 3);
|
BOOST_CHECK_EQUAL(array.size(), 3);
|
||||||
array.clear();
|
array.clear();
|
||||||
BOOST_CHECK_EQUAL(array.size(), 0);
|
BOOST_CHECK_EQUAL(array.size(), 0);
|
||||||
|
array.add(2);
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(remove_keeporder)
|
BOOST_AUTO_TEST_CASE(remove_keeporder)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
array.add(1);
|
array.add(1);
|
||||||
array.add(2);
|
array.add(2);
|
||||||
array.add(3);
|
array.add(3);
|
||||||
array.add(4);
|
array.add(4);
|
||||||
array.add(5);
|
array.add(5);
|
||||||
array.remove(1);
|
array.remove(1);
|
||||||
BOOST_CHECK_EQUAL(array[1], 3);
|
BOOST_CHECK_EQUAL(array[1], 3);
|
||||||
BOOST_CHECK_EQUAL(array[2], 4);
|
BOOST_CHECK_EQUAL(array[2], 4);
|
||||||
BOOST_CHECK_EQUAL(array[3], 5);
|
BOOST_CHECK_EQUAL(array[3], 5);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 4);
|
BOOST_CHECK_EQUAL(array.size(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(remove_swap)
|
BOOST_AUTO_TEST_CASE(remove_swap)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
array.add(1);
|
array.add(1);
|
||||||
array.add(2);
|
array.add(2);
|
||||||
array.add(3);
|
array.add(3);
|
||||||
array.add(4);
|
array.add(4);
|
||||||
array.add(5);
|
array.add(5);
|
||||||
array.remove(1, false);
|
array.remove(1, false);
|
||||||
BOOST_CHECK_EQUAL(array[1], 5);
|
BOOST_CHECK_EQUAL(array[1], 5);
|
||||||
BOOST_CHECK_EQUAL(array[2], 3);
|
BOOST_CHECK_EQUAL(array[2], 3);
|
||||||
BOOST_CHECK_EQUAL(array[3], 4);
|
BOOST_CHECK_EQUAL(array[3], 4);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 4);
|
BOOST_CHECK_EQUAL(array.size(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(remove_iterator)
|
BOOST_AUTO_TEST_CASE(remove_iterator)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
array.add(1);
|
array.add(1);
|
||||||
array.add(2);
|
array.add(2);
|
||||||
array.add(3);
|
array.add(3);
|
||||||
array.add(4);
|
array.add(4);
|
||||||
array.add(5);
|
array.add(5);
|
||||||
array.remove(array.find(1), false);
|
array.remove(array.find(1), false);
|
||||||
BOOST_CHECK_EQUAL(array[0], 5);
|
BOOST_CHECK_EQUAL(array[0], 5);
|
||||||
BOOST_CHECK_EQUAL(array[1], 2);
|
BOOST_CHECK_EQUAL(array[1], 2);
|
||||||
BOOST_CHECK_EQUAL(array[2], 3);
|
BOOST_CHECK_EQUAL(array[2], 3);
|
||||||
BOOST_CHECK_EQUAL(array[3], 4);
|
BOOST_CHECK_EQUAL(array[3], 4);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 4);
|
BOOST_CHECK_EQUAL(array.size(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(remove_iterator_keep_order)
|
BOOST_AUTO_TEST_CASE(remove_iterator_keep_order)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
array.add(1);
|
array.add(1);
|
||||||
array.add(2);
|
array.add(2);
|
||||||
array.add(3);
|
array.add(3);
|
||||||
array.add(4);
|
array.add(4);
|
||||||
array.add(5);
|
array.add(5);
|
||||||
array.remove(array.find(1));
|
array.remove(array.find(1));
|
||||||
BOOST_CHECK_EQUAL(array[0], 2);
|
BOOST_CHECK_EQUAL(array[0], 2);
|
||||||
BOOST_CHECK_EQUAL(array[1], 3);
|
BOOST_CHECK_EQUAL(array[1], 3);
|
||||||
BOOST_CHECK_EQUAL(array[2], 4);
|
BOOST_CHECK_EQUAL(array[2], 4);
|
||||||
BOOST_CHECK_EQUAL(array[3], 5);
|
BOOST_CHECK_EQUAL(array[3], 5);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 4);
|
BOOST_CHECK_EQUAL(array.size(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(random_access)
|
BOOST_AUTO_TEST_CASE(random_access)
|
||||||
{
|
{
|
||||||
Array<uint8> array;
|
Array<uint8> array;
|
||||||
array.add(4);
|
array.add(4);
|
||||||
array.add(5);
|
array.add(5);
|
||||||
array.add(6);
|
array.add(6);
|
||||||
BOOST_CHECK_EQUAL(array[2], 6);
|
BOOST_CHECK_EQUAL(array[2], 6);
|
||||||
BOOST_CHECK_EQUAL(array[0], 4);
|
BOOST_CHECK_EQUAL(array[0], 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(copy)
|
||||||
|
{
|
||||||
|
Array<uint8> array;
|
||||||
|
array.add(0);
|
||||||
|
array.add(1);
|
||||||
|
array.add(2);
|
||||||
|
array.add(3);
|
||||||
|
Array<uint8> copy = array;
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(array.begin(), array.end(), copy.begin(), copy.end());
|
||||||
|
Array<uint8> copy2(copy);
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(array.begin(), array.end(), copy2.begin(), copy2.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
class BaseElement
|
||||||
|
{
|
||||||
|
uint64 test;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BaseContainer
|
||||||
|
{
|
||||||
|
Array<BaseElement> elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DerivedContainer : public BaseContainer
|
||||||
|
{
|
||||||
|
uint64 test;
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(virtual_classes)
|
||||||
|
{
|
||||||
|
Array<DerivedContainer> array(64);
|
||||||
|
for(uint32 i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
Array<DerivedContainer> copy = array;
|
||||||
|
BOOST_CHECK_EQUAL(array.size(), copy.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestStruct
|
class TestStruct
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint32 data;
|
uint32 data;
|
||||||
~TestStruct()
|
~TestStruct()
|
||||||
{
|
{
|
||||||
data = 1;
|
data = 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
DECLARE_REF(TestStruct);
|
DECLARE_REF(TestStruct);
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(refptr_interaction)
|
BOOST_AUTO_TEST_CASE(refptr_interaction)
|
||||||
{
|
{
|
||||||
uint32* dataPtr;
|
uint32* dataPtr;
|
||||||
{
|
{
|
||||||
PTestStruct test = new TestStruct();
|
PTestStruct test = new TestStruct();
|
||||||
test->data = 32123;
|
test->data = 32123;
|
||||||
dataPtr = &test->data;
|
dataPtr = &test->data;
|
||||||
{
|
{
|
||||||
Array<PTestStruct> arr(1);
|
Array<PTestStruct> arr(1);
|
||||||
arr[0] = test;
|
arr[0] = test;
|
||||||
}
|
}
|
||||||
BOOST_CHECK_EQUAL(test->data, 32123);
|
BOOST_CHECK_EQUAL(test->data, 32123);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
@@ -146,25 +185,25 @@ BOOST_AUTO_TEST_SUITE(StaticArray_Suite)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(empty_constructur)
|
BOOST_AUTO_TEST_CASE(empty_constructur)
|
||||||
{
|
{
|
||||||
StaticArray<uint8, 2> array;
|
StaticArray<uint8, 2> array;
|
||||||
BOOST_CHECK_EQUAL(array.size(), 2);
|
BOOST_CHECK_EQUAL(array.size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(initialial_size)
|
BOOST_AUTO_TEST_CASE(initialial_size)
|
||||||
{
|
{
|
||||||
StaticArray<uint8, 3> array(3);
|
StaticArray<uint8, 3> array(3);
|
||||||
BOOST_CHECK_EQUAL(array.size(), 3);
|
BOOST_CHECK_EQUAL(array.size(), 3);
|
||||||
BOOST_CHECK_EQUAL(array[1], 3);
|
BOOST_CHECK_EQUAL(array[1], 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(random_access)
|
BOOST_AUTO_TEST_CASE(random_access)
|
||||||
{
|
{
|
||||||
StaticArray<uint8, 3> array;
|
StaticArray<uint8, 3> array;
|
||||||
array[0] = 4;
|
array[0] = 4;
|
||||||
array[1] = 5;
|
array[1] = 5;
|
||||||
array[2] = 6;
|
array[2] = 6;
|
||||||
BOOST_CHECK_EQUAL(array[0], 4);
|
BOOST_CHECK_EQUAL(array[0], 4);
|
||||||
BOOST_CHECK_EQUAL(array[2], 6);
|
BOOST_CHECK_EQUAL(array[2], 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <vld.h>
|
||||||
|
#include "ThreadPool.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
@@ -6,6 +8,7 @@ namespace Seele
|
|||||||
{
|
{
|
||||||
GlobalFixture()
|
GlobalFixture()
|
||||||
{
|
{
|
||||||
|
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||||
}
|
}
|
||||||
~GlobalFixture()
|
~GlobalFixture()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,13 +23,18 @@ Job basicThenThird()
|
|||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(basic_then)
|
Job basicThenBase()
|
||||||
{
|
{
|
||||||
basicThenFirst()
|
co_await basicThenFirst();
|
||||||
.then(basicThenSecond())
|
co_await basicThenSecond();
|
||||||
.then(basicThenThird());
|
co_await basicThenThird();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(basic_then)
|
||||||
|
{
|
||||||
|
basicThenBase();
|
||||||
|
}
|
||||||
|
/*
|
||||||
uint64 basicAllState1 = 0;
|
uint64 basicAllState1 = 0;
|
||||||
uint64 basicAllState2 = 0;
|
uint64 basicAllState2 = 0;
|
||||||
Job basicAllFirst()
|
Job basicAllFirst()
|
||||||
@@ -69,6 +74,6 @@ BOOST_AUTO_TEST_CASE(basic_callable)
|
|||||||
BOOST_REQUIRE_EQUAL(basicCallable, 10);
|
BOOST_REQUIRE_EQUAL(basicCallable, 10);
|
||||||
co_return;
|
co_return;
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
Reference in New Issue
Block a user