Finished writeup and fixed crashes

This commit is contained in:
Dynamitos
2021-10-19 23:04:38 +02:00
parent a0693daa67
commit 451572f254
36 changed files with 295 additions and 375 deletions
+4 -4
View File
@@ -3,22 +3,22 @@
{ {
"name": "Win32", "name": "Win32",
"includePath": [ "includePath": [
"${workspaceFolder}/**", "${workspaceFolder}/src/**"
"external/**"
], ],
"defines": [ "defines": [
"_DEBUG", "_DEBUG",
"UNICODE", "UNICODE",
"_UNICODE" "_UNICODE"
], ],
"intelliSenseMode": "msvc-x64", "intelliSenseMode": "windows-msvc-x64",
"configurationProvider": "ms-vscode.cmake-tools", "configurationProvider": "ms-vscode.cmake-tools",
"cppStandard": "c++20", "cppStandard": "c++20",
"browse": { "browse": {
"path": [ "path": [
"external/**" "external/**"
] ]
} },
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe"
} }
], ],
"version": 4 "version": 4
+2 -1
View File
@@ -133,5 +133,6 @@
"**/target": true "**/target": true
}, },
"C_Cpp.errorSquiggles": "Disabled", "C_Cpp.errorSquiggles": "Disabled",
"git.ignoreSubmodules": true "git.ignoreSubmodules": true,
"cmake.configureOnOpen": true
} }
+4 -2
View File
@@ -21,6 +21,7 @@ set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
set(Boost_USE_STATIC_LIBS OFF) set(Boost_USE_STATIC_LIBS OFF)
set(Boost_LIB_PREFIX lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
#Workaround for vs, because it places artifacts into an additional subfolder #Workaround for vs, because it places artifacts into an additional subfolder
@@ -37,7 +38,6 @@ else()
project (Seele) project (Seele)
endif() endif()
find_package(Vulkan REQUIRED) find_package(Vulkan REQUIRED)
find_package(Boost REQUIRED COMPONENTS serialization) find_package(Boost REQUIRED COMPONENTS serialization)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
@@ -117,7 +117,7 @@ if(WIN32)
add_custom_target(copy-binaries ALL add_custom_target(copy-binaries ALL
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARIES} $<TARGET_FILE_DIR:SeeleEngine> COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARIES} $<TARGET_FILE_DIR:SeeleEngine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $<TARGET_FILE_DIR:SeeleEngine> COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $<TARGET_FILE_DIR:SeeleEngine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $<TARGET_FILE_DIR:SeeleEngine> #COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $<TARGET_FILE_DIR:SeeleEngine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $<TARGET_FILE_DIR:SeeleEngine> COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $<TARGET_FILE_DIR:SeeleEngine>
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $<TARGET_FILE_DIR:SeeleEngine>) COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $<TARGET_FILE_DIR:SeeleEngine>)
else() else()
@@ -127,3 +127,5 @@ endif()
add_custom_target(copy-runtime-files ALL add_custom_target(copy-runtime-files ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/res $<TARGET_FILE_DIR:SeeleEngine> COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/res $<TARGET_FILE_DIR:SeeleEngine>
DEPENDS SeeleEngine copy-binaries) DEPENDS SeeleEngine copy-binaries)
+66 -4
View File
@@ -9,7 +9,7 @@ API that doesn't support it, like OpenGL. These APIs would suffer a significant
## Custom containers and other utilities ## Custom containers and other utilities
Some of the basic containers are reimplemented, mostly not for any particular feature, but because that makes them more customizable and extendable for future uses and Some of the basic containers are reimplemented, mostly not for any particular feature, but because that makes them more customizable and extendable for future uses and
performance optimizations, like serialization for example. Due to them occuring in the code samples later, they will be quickly mentioned here. performance optimizations, like serialization for example. Due to some of them occuring in the code samples later, they will be quickly mentioned here.
- `Array`: A heap-array backed dynamically resizable container, like `std::vector` - `Array`: A heap-array backed dynamically resizable container, like `std::vector`
- `StaticArray`: A static-array backed non-resizable container, like `std::array` - `StaticArray`: A static-array backed non-resizable container, like `std::array`
@@ -139,8 +139,70 @@ The document starts with the asset `name`, followed by the `profile`, which tell
### MaterialAsset ### MaterialAsset
The `MaterialAsset` class represents such a JSON document on disk, and is the base class for `Material` and `MaterialInstance`. It stores the layout of the parameters as well as their values, but does not store, parse or generate any shader code. A `MaterialAsset` represents such a JSON document on disk, as well as the GPU resources needed to render a mesh with the material. When loading the file, the a descriptor layout is generated to fit the `slang` code that will be generated later by consolidating the plain variables (`float`, `double`, etc.) into a single uniform buffer. The parameters are stored in an array of `ShaderParameter`s, which contain the current parameter value, like texture references or plain data, as well as information on how to update the GPU resources.
### Material At the same time a slang-compilable shader is generated, which matches the parameters provided by the descriptor layout. The generated shader is a `Material`, which is an interface that "prepares" a BRDF by initializing its input values, similar to official slang example. How each input value is calculated is read from the `code` section of the JSON document, and wrapped in an accessor to allow for multi line calculations.
The `Material` class inherits from `MaterialAsset` and represents a base material, Here is the material generated from the above JSON example:
```cpp
import VERTEX_INPUT_IMPORT;
import Material;
import BRDF;
import MaterialParameter;
struct Placeholder: IMaterial {
layout(offset = 0)float anisotropic;
layout(offset = 4)float clearCoat;
layout(offset = 8)float clearCoatGloss;
Texture2D diffuseTexture;
layout(offset = 12)float metallic;
Texture2D normalTexture;
layout(offset = 16)float roughness;
layout(offset = 20)float sheen;
layout(offset = 24)float sheenTint;
Texture2D specularTexture;
layout(offset = 28)float specularTint;
layout(offset = 32)float subsurface;
SamplerState textureSampler;
layout(offset = 36)float uvScale;
layout(offset = 40)float3 worldOffset;
float3 getBaseColor(MaterialFragmentParameter input) {
return diffuseTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;;
}
float getMetallic(MaterialFragmentParameter input) {
return 0;;
}
float3 getNormal(MaterialFragmentParameter input) {
return normalTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;;
}
float getSpecular(MaterialFragmentParameter input) {
return specularTexture.Sample(textureSampler, input.texCoords[0] * uvScale).x;;
}
float getRoughness(MaterialFragmentParameter input) {
return roughness;;
}
float getSheen(MaterialFragmentParameter input) {
return sheen;;
}
float3 getWorldOffset() {
return worldOffset;;
}
typedef BlinnPhong BRDF;
BlinnPhong prepare(MaterialFragmentParameter geometry){
BlinnPhong result;
result.baseColor = getBaseColor(geometry);
result.metallic = getMetallic(geometry);
result.normal = getNormal(geometry);
result.specular = getSpecular(geometry);
result.roughness = getRoughness(geometry);
result.sheen = getSheen(geometry);
return result;
}
};
```
### Renderpass interaction
Each render pass has a "base file" containing the vertex and fragment stages. From that base file a variant is generated for each material that will be used with that render pass using `#define` macros to change the material import, and a `type_param` to update the `ParameterBlock` containing the material itself. Other renderpass dependent data like camera parameter or lights are stored in separate descriptor sets, and to avoid code duplication, they parts that are used by more than one render pass are implemented in separate slang files. But since in Vulkan pipeline layouts cannot have empty indices, the descriptor set indices sometimes need to change. This is done using the static `modifyRenderPassMacros` function in each renderpass to `#define` the correct set indices for each shared descriptor layout.
+9 -8
View File
@@ -48,14 +48,15 @@ if (WIN32)
unset(GLFW_LIBRARY_NAME) unset(GLFW_LIBRARY_NAME)
find_file( #find_file(
GLFW_BINARY # GLFW_BINARY
NAMES glfw3${CMAKE_DEBUG_POSTFIX}.dll # NAMES glfw3${CMAKE_DEBUG_POSTFIX}.dll
PATHS # PATHS
$ENV{PROGRAMFILES}/bin # $ENV{PROGRAMFILES}/bin
${GLFW_ROOT}/src # ${CMAKE_BINARY_DIR}
${GLFW_ROOT}/bin # ${GLFW_ROOT}/src
PATH_SUFFIXES Debug Release) # ${GLFW_ROOT}/bin
# PATH_SUFFIXES Debug Release)
else() else()
# Find include files # Find include files
find_path( find_path(
+1 -2
View File
@@ -28,14 +28,13 @@ else()
endif() endif()
ExternalProject_Add(boost ExternalProject_Add(boost
SOURCE_DIR ${BOOST_ROOT} SOURCE_DIR ${BOOST_ROOT}
UPDATE_COMMAND ""
CONFIGURE_COMMAND ./bootstrap.${BOOTSTRAP_EXTENSION} --with-libraries=serialization,test CONFIGURE_COMMAND ./bootstrap.${BOOTSTRAP_EXTENSION} --with-libraries=serialization,test
BUILD_COMMAND ./b2 -d0 BUILD_COMMAND ./b2 -d0
BUILD_IN_SOURCE 1 BUILD_IN_SOURCE 1
INSTALL_COMMAND "") INSTALL_COMMAND "")
list (APPEND EXTRA_CMAKE_ARGS list (APPEND EXTRA_CMAKE_ARGS
-DBoost_NO_SYSTEM_PATHS=OFF) -DBoost_NO_SYSTEM_PATHS=ON)
#-----------------KTX---------------------------- #-----------------KTX----------------------------
list(APPEND DEPENDENCIES ktx) list(APPEND DEPENDENCIES ktx)
+2 -1
View File
@@ -105,7 +105,8 @@ void cullLights(ComputeShaderInput in)
for ( uint i = in.groupIndex; i < numPointLights; i += BLOCK_SIZE * BLOCK_SIZE ) for ( uint i = in.groupIndex; i < numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
{ {
PointLight light = pointLights[i]; PointLight light = pointLights[i];
if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS)) //TODO: why doesn't this check go through?
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
{ {
tAppendLight(i); tAppendLight(i);
if(!light.insidePlane(minPlane)) if(!light.insidePlane(minPlane))
+1 -1
View File
@@ -4,7 +4,7 @@
#include "TextureLoader.h" #include "TextureLoader.h"
#include "MaterialLoader.h" #include "MaterialLoader.h"
#include "MeshLoader.h" #include "MeshLoader.h"
#include "Material/Material.h" #include "Material/MaterialAsset.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Window/WindowManager.h" #include "Window/WindowManager.h"
#include "MeshAsset.h" #include "MeshAsset.h"
+7 -7
View File
@@ -1,6 +1,6 @@
#include "MaterialLoader.h" #include "MaterialLoader.h"
#include "Material/Material.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Material/MaterialAsset.h"
#include "AssetRegistry.h" #include "AssetRegistry.h"
using namespace Seele; using namespace Seele;
@@ -8,8 +8,8 @@ using namespace Seele;
MaterialLoader::MaterialLoader(Gfx::PGraphics graphics) MaterialLoader::MaterialLoader(Gfx::PGraphics graphics)
: graphics(graphics) : graphics(graphics)
{ {
placeholderMaterial = new Material(std::filesystem::absolute("./shaders/Placeholder.asset")); placeholderMaterial = new MaterialAsset(std::filesystem::absolute("./shaders/Placeholder.asset"));
placeholderMaterial->compile(); placeholderMaterial->load();
graphics->getShaderCompiler()->registerMaterial(placeholderMaterial); graphics->getShaderCompiler()->registerMaterial(placeholderMaterial);
} }
@@ -17,10 +17,10 @@ MaterialLoader::~MaterialLoader()
{ {
} }
PMaterial MaterialLoader::queueAsset(const std::filesystem::path& filePath) PMaterialAsset MaterialLoader::queueAsset(const std::filesystem::path& filePath)
{ {
PMaterial result = new Material(filePath); PMaterialAsset result = new MaterialAsset(filePath);
result->compile(); result->load();
graphics->getShaderCompiler()->registerMaterial(result); graphics->getShaderCompiler()->registerMaterial(result);
AssetRegistry::get().registerMaterial(result); AssetRegistry::get().registerMaterial(result);
// TODO: There is actually no real reason to import a standalone material, // TODO: There is actually no real reason to import a standalone material,
@@ -28,7 +28,7 @@ PMaterial MaterialLoader::queueAsset(const std::filesystem::path& filePath)
return result; return result;
} }
PMaterial MaterialLoader::getPlaceHolderMaterial() PMaterialAsset MaterialLoader::getPlaceHolderMaterial()
{ {
return placeholderMaterial; return placeholderMaterial;
} }
+4 -4
View File
@@ -7,19 +7,19 @@
namespace Seele namespace Seele
{ {
DECLARE_REF(Material) DECLARE_REF(MaterialAsset)
DECLARE_NAME_REF(Gfx, Graphics) DECLARE_NAME_REF(Gfx, Graphics)
class MaterialLoader class MaterialLoader
{ {
public: public:
MaterialLoader(Gfx::PGraphics graphic); MaterialLoader(Gfx::PGraphics graphic);
~MaterialLoader(); ~MaterialLoader();
PMaterial queueAsset(const std::filesystem::path& filePath); PMaterialAsset queueAsset(const std::filesystem::path& filePath);
PMaterial getPlaceHolderMaterial(); PMaterialAsset getPlaceHolderMaterial();
private: private:
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
List<std::future<void>> futures; List<std::future<void>> futures;
PMaterial placeholderMaterial; PMaterialAsset placeholderMaterial;
}; };
DEFINE_REF(MaterialLoader) DEFINE_REF(MaterialLoader)
} // namespace Seele } // namespace Seele
+2 -3
View File
@@ -5,7 +5,6 @@
#include "Graphics/Mesh.h" #include "Graphics/Mesh.h"
#include "Graphics/StaticMeshVertexInput.h" #include "Graphics/StaticMeshVertexInput.h"
#include "AssetRegistry.h" #include "AssetRegistry.h"
#include "Material/Material.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
@@ -88,8 +87,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& glob
outMatFile.close(); outMatFile.close();
std::cout << "writing json to " << outMatFilename << std::endl; std::cout << "writing json to " << outMatFilename << std::endl;
PMaterial result = new Material(outMatFilename); PMaterialAsset result = new MaterialAsset(outMatFilename);
result->compile(); result->load();
graphics->getShaderCompiler()->registerMaterial(result); graphics->getShaderCompiler()->registerMaterial(result);
AssetRegistry::get().registerMaterial(result); AssetRegistry::get().registerMaterial(result);
PMaterialAsset asset = AssetRegistry::findMaterial(result->getFileName()); PMaterialAsset asset = AssetRegistry::findMaterial(result->getFileName());
+1 -3
View File
@@ -1,6 +1,4 @@
#include "GraphicsResources.h" #include "GraphicsResources.h"
#include "Material/MaterialInstance.h"
#include "Material/Material.h"
#include "Graphics.h" #include "Graphics.h"
#include "RenderPass/DepthPrepass.h" #include "RenderPass/DepthPrepass.h"
#include "RenderPass/BasePass.h" #include "RenderPass/BasePass.h"
@@ -55,7 +53,7 @@ const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const
ShaderCollection& ShaderMap::createShaders( ShaderCollection& ShaderMap::createShaders(
PGraphics graphics, PGraphics graphics,
RenderPassType renderPass, RenderPassType renderPass,
PMaterial material, PMaterialAsset material,
VertexInputType* vertexInput, VertexInputType* vertexInput,
bool /*bPositionOnly*/) bool /*bPositionOnly*/)
{ {
+1 -2
View File
@@ -17,7 +17,6 @@ namespace Seele
struct VertexInputStream; struct VertexInputStream;
struct VertexStreamComponent; struct VertexStreamComponent;
class VertexInputType; class VertexInputType;
DECLARE_REF(Material)
namespace Gfx namespace Gfx
{ {
DECLARE_REF(Graphics) DECLARE_REF(Graphics)
@@ -140,7 +139,7 @@ public:
ShaderCollection& createShaders( ShaderCollection& createShaders(
PGraphics graphics, PGraphics graphics,
RenderPassType passName, RenderPassType passName,
PMaterial material, PMaterialAsset material,
VertexInputType* vertexInput, VertexInputType* vertexInput,
bool bPositionOnly); bool bPositionOnly);
private: private:
+2 -2
View File
@@ -34,7 +34,7 @@ void BasePassMeshProcessor::addMeshBatch(
const PVertexShaderInput vertexInput = batch.vertexInput; const PVertexShaderInput vertexInput = batch.vertexInput;
const Gfx::ShaderCollection* collection = material->getRenderMaterial()->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType()); const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
assert(collection != nullptr); assert(collection != nullptr);
for(uint32 i = 0; i < batch.elements.size(); ++i) for(uint32 i = 0; i < batch.elements.size(); ++i)
{ {
@@ -47,7 +47,7 @@ void BasePassMeshProcessor::addMeshBatch(
renderCommand->setViewport(target); renderCommand->setViewport(target);
for(uint32 i = 0; i < batch.elements.size(); ++i) for(uint32 i = 0; i < batch.elements.size(); ++i)
{ {
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getRenderMaterial()->getDescriptorLayout()); pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout());
pipelineLayout->create(); pipelineLayout->create();
descriptorSets[BasePass::INDEX_MATERIAL] = material->getDescriptor(); descriptorSets[BasePass::INDEX_MATERIAL] = material->getDescriptor();
descriptorSets[BasePass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++]; descriptorSets[BasePass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++];
@@ -33,7 +33,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
const PVertexShaderInput vertexInput = batch.vertexInput; const PVertexShaderInput vertexInput = batch.vertexInput;
const Gfx::ShaderCollection* collection = material->getRenderMaterial()->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType()); const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType());
assert(collection != nullptr); assert(collection != nullptr);
for(uint32 i = 0; i < batch.elements.size(); ++i) for(uint32 i = 0; i < batch.elements.size(); ++i)
{ {
@@ -46,7 +46,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
renderCommand->setViewport(target); renderCommand->setViewport(target);
for(uint32 i = 0; i < batch.elements.size(); ++i) for(uint32 i = 0; i < batch.elements.size(); ++i)
{ {
pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getRenderMaterial()->getDescriptorLayout()); pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getDescriptorLayout());
pipelineLayout->create(); pipelineLayout->create();
descriptorSets[DepthPrepass::INDEX_MATERIAL] = material->getDescriptor(); descriptorSets[DepthPrepass::INDEX_MATERIAL] = material->getDescriptor();
descriptorSets[DepthPrepass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++]; descriptorSets[DepthPrepass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++];
@@ -33,14 +33,19 @@ void LightCullingPass::beginFrame()
uniformUpdate.data = (uint8*)&viewParams; uniformUpdate.data = (uint8*)&viewParams;
viewParamsBuffer->updateContents(uniformUpdate); viewParamsBuffer->updateContents(uniformUpdate);
LightEnv lightEnv = passData.lightEnv; const LightEnv& lightEnv = passData.lightEnv;
for(uint32 i = 0; i < lightEnv.numPointLights; ++i) uniformUpdate.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
{ uniformUpdate.data = (uint8*)&lightEnv.directionalLights;
lightEnv.pointLights[i].positionVS = lightEnv.pointLights[i].positionWS; directLightBuffer->updateContents(uniformUpdate);
}
uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS; uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
uniformUpdate.data = (uint8*)&lightEnv.pointLights; uniformUpdate.data = (uint8*)&lightEnv.pointLights;
pointLightBuffer->updateContents(uniformUpdate); pointLightBuffer->updateContents(uniformUpdate);
uniformUpdate.size = sizeof(uint32);
uniformUpdate.data = (uint8*)&lightEnv.numDirectionalLights;
numDirLightBuffer->updateContents(uniformUpdate);
uniformUpdate.data = (uint8*)&lightEnv.numPointLights;
numPointLightBuffer->updateContents(uniformUpdate);
BulkResourceData counterReset; BulkResourceData counterReset;
uint32 reset = 0; uint32 reset = 0;
@@ -64,6 +69,7 @@ void LightCullingPass::beginFrame()
cullingDescriptorSet->updateTexture(8, oLightGrid); cullingDescriptorSet->updateTexture(8, oLightGrid);
cullingDescriptorSet->updateTexture(9, tLightGrid); cullingDescriptorSet->updateTexture(9, tLightGrid);
lightEnvDescriptorSet->updateBuffer(0, directLightBuffer); lightEnvDescriptorSet->updateBuffer(0, directLightBuffer);
lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer); lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer);
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer); lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
@@ -133,30 +139,28 @@ void LightCullingPass::publishOutputs()
resources->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList); resources->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList); resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
const LightEnv& lightEnv = passData.lightEnv;
resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS; resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
resourceData.data = (uint8*)&lightEnv.directionalLights;
structInfo.resourceData = resourceData; structInfo.resourceData = resourceData;
structInfo.bDynamic = true; structInfo.bDynamic = true;
directLightBuffer = graphics->createStructuredBuffer(structInfo); directLightBuffer = graphics->createStructuredBuffer(structInfo);
resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS; resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
resourceData.data = (uint8*)&lightEnv.pointLights;
structInfo.resourceData = resourceData; structInfo.resourceData = resourceData;
pointLightBuffer = graphics->createStructuredBuffer(structInfo); pointLightBuffer = graphics->createStructuredBuffer(structInfo);
UniformBufferCreateInfo uniformInfo; UniformBufferCreateInfo uniformInfo;
resourceData.size = sizeof(uint32); resourceData.size = sizeof(uint32);
resourceData.data = (uint8*)&lightEnv.numDirectionalLights;
uniformInfo.resourceData = resourceData; uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true; uniformInfo.bDynamic = true;
numDirLightBuffer = graphics->createUniformBuffer(uniformInfo); numDirLightBuffer = graphics->createUniformBuffer(uniformInfo);
resourceData.data = (uint8*)&lightEnv.numPointLights;
uniformInfo.resourceData = resourceData; uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true; uniformInfo.bDynamic = true;
numPointLightBuffer = graphics->createUniformBuffer(uniformInfo); numPointLightBuffer = graphics->createUniformBuffer(uniformInfo);
resources->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer); resources->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer);
resources->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer); resources->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer);
resources->registerBufferOutput("POINT_LIGHTS", pointLightBuffer); resources->registerBufferOutput("POINT_LIGHTS", pointLightBuffer);
resources->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer); resources->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer);
TextureCreateInfo textureInfo; TextureCreateInfo textureInfo;
textureInfo.width = dispatchParams.numThreadGroups.x; textureInfo.width = dispatchParams.numThreadGroups.x;
textureInfo.height = dispatchParams.numThreadGroups.y; textureInfo.height = dispatchParams.numThreadGroups.y;
@@ -164,6 +168,7 @@ void LightCullingPass::publishOutputs()
textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT; textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT;
oLightGrid = graphics->createTexture2D(textureInfo); oLightGrid = graphics->createTexture2D(textureInfo);
tLightGrid = graphics->createTexture2D(textureInfo); tLightGrid = graphics->createTexture2D(textureInfo);
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid); resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid); resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
} }
+2 -2
View File
@@ -1,5 +1,5 @@
#include "ShaderCompiler.h" #include "ShaderCompiler.h"
#include "Material/Material.h" #include "Material/MaterialAsset.h"
#include "VertexShaderInput.h" #include "VertexShaderInput.h"
using namespace Seele; using namespace Seele;
@@ -16,7 +16,7 @@ ShaderCompiler::~ShaderCompiler()
} }
void ShaderCompiler::registerMaterial(PMaterial material) void ShaderCompiler::registerMaterial(PMaterialAsset material)
{ {
for(auto& type : VertexInputType::getTypeList()) for(auto& type : VertexInputType::getTypeList())
{ {
+2 -3
View File
@@ -3,7 +3,6 @@
namespace Seele namespace Seele
{ {
DECLARE_REF(Material)
DECLARE_NAME_REF(Gfx, Graphics) DECLARE_NAME_REF(Gfx, Graphics)
namespace Gfx namespace Gfx
{ {
@@ -12,9 +11,9 @@ class ShaderCompiler
public: public:
ShaderCompiler(PGraphics graphics); ShaderCompiler(PGraphics graphics);
~ShaderCompiler(); ~ShaderCompiler();
void registerMaterial(PMaterial material); void registerMaterial(PMaterialAsset material);
private: private:
Array<PMaterial> pendingCompiles; Array<PMaterialAsset> pendingCompiles;
PGraphics graphics; PGraphics graphics;
}; };
DEFINE_REF(ShaderCompiler) DEFINE_REF(ShaderCompiler)
@@ -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::lock_guard<std::mutex> lock(m_mutex); std::unique_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::lock_guard<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
// Get shader debug information identifier // Get shader debug information identifier
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {}; GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {};
@@ -336,7 +336,7 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
auto descriptor = descriptorSet.cast<DescriptorSet>(); auto descriptor = descriptorSet.cast<DescriptorSet>();
boundDescriptors.add(descriptor.getHandle()); boundDescriptors.add(descriptor.getHandle());
descriptor->bind(); descriptor->bind();
//std::cout << "Binding descriptor " << descriptor->getHandle() << " to cmd " << handle << std::endl;
VkDescriptorSet setHandle = descriptor->getHandle(); VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
} }
@@ -373,7 +373,7 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
activeCmdBuffer = new CmdBuffer(graphics, commandPool, this); activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
activeCmdBuffer->begin(); activeCmdBuffer->begin();
std::lock_guard lock(allocatedBufferLock); std::unique_lock lock(allocatedBufferLock);
allocatedBuffers.add(activeCmdBuffer); allocatedBuffers.add(activeCmdBuffer);
} }
@@ -397,6 +397,7 @@ PRenderCommand CommandBufferManager::createRenderCommand(const std::string& name
PRenderCommand cmdBuffer = allocatedRenderCommands[i]; PRenderCommand cmdBuffer = allocatedRenderCommands[i];
if (cmdBuffer->isReady()) if (cmdBuffer->isReady())
{ {
cmdBuffer->name = name;
cmdBuffer->begin(activeCmdBuffer); cmdBuffer->begin(activeCmdBuffer);
return cmdBuffer; return cmdBuffer;
} }
@@ -416,6 +417,7 @@ PComputeCommand CommandBufferManager::createComputeCommand(const std::string& na
PComputeCommand cmdBuffer = allocatedComputeCommands[i]; PComputeCommand cmdBuffer = allocatedComputeCommands[i];
if (cmdBuffer->isReady()) if (cmdBuffer->isReady())
{ {
cmdBuffer->name = name;
cmdBuffer->begin(activeCmdBuffer); cmdBuffer->begin(activeCmdBuffer);
return cmdBuffer; return cmdBuffer;
} }
-4
View File
@@ -2,11 +2,7 @@ target_sources(SeeleEngine
PRIVATE PRIVATE
BRDF.h BRDF.h
BRDF.cpp BRDF.cpp
Material.h
Material.cpp
MaterialAsset.h MaterialAsset.h
MaterialAsset.cpp MaterialAsset.cpp
MaterialInstance.h
MaterialInstance.cpp
ShaderExpression.h ShaderExpression.h
ShaderExpression.cpp) ShaderExpression.cpp)
-162
View File
@@ -1,162 +0,0 @@
#include "Material.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/VertexShaderInput.h"
#include "BRDF.h"
#include "Window/WindowManager.h"
#include <nlohmann/json.hpp>
#include <sstream>
#include <iostream>
Gfx::ShaderMap Material::shaderMap;
std::mutex Material::shaderMapLock;
using namespace Seele;
using json = nlohmann::json;
Material::Material()
{
}
Material::Material(const std::string& directory, const std::string& name)
: MaterialAsset(directory, name)
{
}
Material::Material(const std::filesystem::path& fullPath)
: MaterialAsset(fullPath)
{
}
Material::~Material()
{
}
void Material::save()
{
}
void Material::load()
{
}
void Material::compile()
{
setStatus(Status::Loading);
auto& stream = getReadStream();
json j;
stream >> j;
materialName = j["name"].get<std::string>();
layout = WindowManager::getGraphics()->createDescriptorLayout(materialName + "Layout");
//Shader file needs to conform to the slang standard, which prohibits _
materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end());
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
std::string profile = j["profile"].get<std::string>();
codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl;
codeStream << "import Material;" << std::endl;
codeStream << "import BRDF;" << std::endl;
codeStream << "import MaterialParameter;" << std::endl << std::endl;
codeStream << "struct " << materialName << " : IMaterial {" << std::endl;
uint32 uniformBufferOffset = 0;
uint32 bindingCounter = 0; // Uniform buffers are always binding 0
uniformBinding = -1;
for(auto param : j["params"].items())
{
std::string type = param.value()["type"].get<std::string>();
auto defaultValue = param.value().find("default");
if(type.compare("float") == 0)
{
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
if(uniformBinding == -1)
{
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 4;
if(defaultValue != param.value().end())
{
p->data = std::stof(defaultValue.value().get<std::string>());
}
parameters.add(p);
}
else if(type.compare("float3") == 0)
{
PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0);
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
if(uniformBinding == -1)
{
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 12;
if(defaultValue != param.value().end())
{
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
}
parameters.add(p);
}
else if(type.compare("Texture2D") == 0)
{
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
if(defaultValue != param.value().end())
{
std::string defaultString = defaultValue.value().get<std::string>();
p->data = AssetRegistry::findTexture(defaultString);
}
else
{
p->data = AssetRegistry::findTexture(""); // this will return placeholder texture
}
assert(p->data != nullptr);
parameters.add(p);
}
else if(type.compare("SamplerState") == 0)
{
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
SamplerCreateInfo createInfo;
p->data = WindowManager::getGraphics()->createSamplerState(createInfo);
parameters.add(p);
}
else
{
std::cout << "Error unsupported parameter type" << std::endl;
}
codeStream << "\t" << type << " " << param.key() << ";\n";
}
uniformDataSize = uniformBufferOffset;
if(uniformDataSize != 0)
{
uniformData = new uint8[uniformDataSize];
UniformBufferCreateInfo uniformInitializer;
uniformInitializer.resourceData.data = uniformData;
uniformInitializer.resourceData.size = uniformDataSize;
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(uniformInitializer);
}
BRDF* brdf = BRDF::getBRDFByName(profile);
brdf->generateMaterialCode(codeStream, j["code"]);
codeStream << "};";
codeStream.close();
layout->create();
setStatus(Status::Ready);
}
const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
{
Gfx::ShaderPermutation permutation;
permutation.passType = renderPass;
std::string vertexInputName = vertexInput->getName();
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
return shaderMap.findShaders(Gfx::PermutationId(permutation));
}
Gfx::ShaderCollection& Material::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput)
{
std::lock_guard lock(shaderMapLock);
return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false);
}
-34
View File
@@ -1,34 +0,0 @@
#pragma once
#include "MinimalEngine.h"
#include "MaterialAsset.h"
namespace Seele
{
class VertexInputType;
class Material : public MaterialAsset
{
public:
Material();
Material(const std::string &directory, const std::string &name);
Material(const std::filesystem::path& fullPath);
~Material();
virtual void save() override;
virtual void load() override;
virtual const Material* getRenderMaterial() const { return this; }
Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; }
// The name of the generated material shader, opposed to the name of the .asset file
const std::string& getName() {return materialName;}
const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const;
Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput);
void compile();
private:
static Gfx::ShaderMap shaderMap;
static std::mutex shaderMapLock;
std::string materialName;
friend class MaterialLoader;
friend class MaterialInstance;
};
DEFINE_REF(Material)
} // namespace Seele
+137 -3
View File
@@ -1,5 +1,16 @@
#include "MaterialAsset.h" #include "MaterialAsset.h"
#include "Window/WindowManager.h" #include "Window/WindowManager.h"
#include "Asset/AssetRegistry.h"
#include "BRDF.h"
#include <nlohmann/json.hpp>
#include <sstream>
#include <iostream>
Gfx::ShaderMap MaterialAsset::shaderMap;
std::mutex MaterialAsset::shaderMapLock;
using namespace Seele;
using json = nlohmann::json;
using namespace Seele; using namespace Seele;
@@ -21,6 +32,118 @@ MaterialAsset::~MaterialAsset()
{ {
} }
void MaterialAsset::save()
{
assert(false && "TODO");
}
void MaterialAsset::load()
{
setStatus(Status::Loading);
auto& stream = getReadStream();
json j;
stream >> j;
materialName = j["name"].get<std::string>();
layout = WindowManager::getGraphics()->createDescriptorLayout(materialName + "Layout");
//Shader file needs to conform to the slang standard, which prohibits _
materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end());
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
std::string profile = j["profile"].get<std::string>();
codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl;
codeStream << "import Material;" << std::endl;
codeStream << "import BRDF;" << std::endl;
codeStream << "import MaterialParameter;" << std::endl << std::endl;
codeStream << "struct " << materialName << " : IMaterial {" << std::endl;
uint32 uniformBufferOffset = 0;
uint32 bindingCounter = 0; // Uniform buffers are always binding 0
uniformBinding = -1;
for(auto param : j["params"].items())
{
std::string type = param.value()["type"].get<std::string>();
auto defaultValue = param.value().find("default");
if(type.compare("float") == 0)
{
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
if(uniformBinding == -1)
{
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 4;
if(defaultValue != param.value().end())
{
p->data = std::stof(defaultValue.value().get<std::string>());
}
parameters.add(p);
}
else if(type.compare("float3") == 0)
{
PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0);
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
if(uniformBinding == -1)
{
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 12;
if(defaultValue != param.value().end())
{
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
}
parameters.add(p);
}
else if(type.compare("Texture2D") == 0)
{
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
if(defaultValue != param.value().end())
{
std::string defaultString = defaultValue.value().get<std::string>();
p->data = AssetRegistry::findTexture(defaultString);
}
else
{
p->data = AssetRegistry::findTexture(""); // this will return placeholder texture
}
assert(p->data != nullptr);
parameters.add(p);
}
else if(type.compare("SamplerState") == 0)
{
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
SamplerCreateInfo createInfo;
p->data = WindowManager::getGraphics()->createSamplerState(createInfo);
parameters.add(p);
}
else
{
std::cout << "Error unsupported parameter type" << std::endl;
}
codeStream << "\t" << type << " " << param.key() << ";\n";
}
uniformDataSize = uniformBufferOffset;
if(uniformDataSize != 0)
{
uniformData = new uint8[uniformDataSize];
UniformBufferCreateInfo uniformInitializer;
uniformInitializer.resourceData.data = uniformData;
uniformInitializer.resourceData.size = uniformDataSize;
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(uniformInitializer);
}
BRDF* brdf = BRDF::getBRDFByName(profile);
brdf->generateMaterialCode(codeStream, j["code"]);
codeStream << "};";
codeStream.close();
layout->create();
setStatus(Status::Ready);
}
void MaterialAsset::beginFrame() void MaterialAsset::beginFrame()
{ {
} }
@@ -48,7 +171,18 @@ void MaterialAsset::updateDescriptorData()
descriptorSet->writeChanges(); descriptorSet->writeChanges();
} }
const Gfx::PDescriptorSet MaterialAsset::getDescriptor() const const Gfx::ShaderCollection* MaterialAsset::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
{ {
return descriptorSet; Gfx::ShaderPermutation permutation;
} permutation.passType = renderPass;
std::string vertexInputName = vertexInput->getName();
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
return shaderMap.findShaders(Gfx::PermutationId(permutation));
}
Gfx::ShaderCollection& MaterialAsset::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput)
{
std::unique_lock lock(shaderMapLock);
return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false);
}
+14 -6
View File
@@ -6,7 +6,6 @@
namespace Seele namespace Seele
{ {
DECLARE_REF(VertexShaderInput) DECLARE_REF(VertexShaderInput)
DECLARE_REF(Material)
class MaterialAsset : public Asset class MaterialAsset : public Asset
{ {
public: public:
@@ -16,18 +15,26 @@ public:
~MaterialAsset(); ~MaterialAsset();
virtual void beginFrame(); virtual void beginFrame();
virtual void endFrame(); virtual void endFrame();
virtual void save() = 0; virtual void save() override;
virtual void load() = 0; virtual void load() override;
virtual const Material* getRenderMaterial() const = 0;
Gfx::SeBlendOp getBlendMode() const {return Gfx::SE_BLEND_OP_END_RANGE;} Gfx::SeBlendOp getBlendMode() const {return Gfx::SE_BLEND_OP_END_RANGE;}
Gfx::MaterialShadingModel getShadingModel() const {return Gfx::MaterialShadingModel::DefaultLit;} Gfx::MaterialShadingModel getShadingModel() const {return Gfx::MaterialShadingModel::DefaultLit;}
// This needs to be called while the descriptorset is unused // This needs to be called while the descriptorset is unused
void updateDescriptorData(); void updateDescriptorData();
void resetDescriptorSet(); void resetDescriptorSet();
const Gfx::PDescriptorSet getDescriptor() const; const Gfx::PDescriptorSet getDescriptor() const { return descriptorSet; };
Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; }
// The name of the generated material shader, opposed to the name of the .asset file
const std::string& getName() {return materialName;}
const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const;
Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput);
private:
static Gfx::ShaderMap shaderMap;
static std::mutex shaderMapLock;
protected:
//For now its simply the collection of parameters, since there is no point for expressions //For now its simply the collection of parameters, since there is no point for expressions
Array<PShaderParameter> parameters; Array<PShaderParameter> parameters;
Gfx::PDescriptorSet descriptorSet; Gfx::PDescriptorSet descriptorSet;
@@ -36,6 +43,7 @@ protected:
uint32 uniformDataSize; uint32 uniformDataSize;
uint8* uniformData; uint8* uniformData;
int32 uniformBinding; int32 uniformBinding;
std::string materialName;
}; };
DEFINE_REF(MaterialAsset) DEFINE_REF(MaterialAsset)
} // namespace Seele } // namespace Seele
-42
View File
@@ -1,42 +0,0 @@
#include "MaterialInstance.h"
#include "Material.h"
#include "Window/WindowManager.h"
using namespace Seele;
MaterialInstance::MaterialInstance()
{
}
MaterialInstance::MaterialInstance(const std::string& directory, const std::string& name)
: MaterialAsset(directory, name)
{
}
MaterialInstance::MaterialInstance(const std::filesystem::path& fullPath)
: MaterialAsset(fullPath)
{
}
MaterialInstance::~MaterialInstance()
{
}
void MaterialInstance::save()
{
}
void MaterialInstance::load()
{
baseMaterial = nullptr; // TODO: actually load the file
UniformBufferCreateInfo uniformInitializer;
uniformInitializer.resourceData.size = baseMaterial->uniformDataSize;
uniformInitializer.resourceData.data = nullptr;
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(uniformInitializer);
}
const Material* MaterialInstance::getRenderMaterial() const
{
return baseMaterial;
}
-22
View File
@@ -1,22 +0,0 @@
#pragma once
#include "MaterialAsset.h"
namespace Seele
{
DECLARE_NAME_REF(Gfx, DescriptorSet)
DECLARE_REF(Material)
class MaterialInstance : public MaterialAsset
{
public:
MaterialInstance();
MaterialInstance(const std::string& directory, const std::string& name);
MaterialInstance(const std::filesystem::path& fullPath);
~MaterialInstance();
virtual void save() override;
virtual void load() override;
virtual const Material* getRenderMaterial() const;
private:
Material* baseMaterial;
};
DEFINE_REF(MaterialInstance)
} // namespace Seele
@@ -9,7 +9,7 @@ CameraComponent::CameraComponent()
: bNeedsViewBuild(true) : bNeedsViewBuild(true)
, bNeedsProjectionBuild(true) , bNeedsProjectionBuild(true)
, originPoint(0, 0, 0) , originPoint(0, 0, 0)
, cameraPosition(0, 0, 0) , cameraPosition(0, 0, 50)
{ {
distance = 50; distance = 50;
rotationX = 0; rotationX = 0;
@@ -1,6 +1,6 @@
#include "PrimitiveComponent.h" #include "PrimitiveComponent.h"
#include "Scene/Scene.h" #include "Scene/Scene.h"
#include "Material/MaterialInstance.h" #include "Material/MaterialAsset.h"
#include "Asset/MeshAsset.h" #include "Asset/MeshAsset.h"
#include "Graphics/VertexShaderInput.h" #include "Graphics/VertexShaderInput.h"
#include <iostream> #include <iostream>
+1 -2
View File
@@ -1,8 +1,7 @@
#include "Scene.h" #include "Scene.h"
#include "Components/PrimitiveComponent.h" #include "Components/PrimitiveComponent.h"
#include "Components/PrimitiveUniformBufferLayout.h" #include "Components/PrimitiveUniformBufferLayout.h"
#include "Material/MaterialInstance.h" #include "Material/MaterialAsset.h"
#include "Material/Material.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
using namespace Seele; using namespace Seele;
-1
View File
@@ -4,7 +4,6 @@
#include "Graphics/GraphicsResources.h" #include "Graphics/GraphicsResources.h"
#include "Components/PrimitiveComponent.h" #include "Components/PrimitiveComponent.h"
#include "Graphics/MeshBatch.h" #include "Graphics/MeshBatch.h"
#include "Material/Material.h"
#include "SceneUpdater.h" #include "SceneUpdater.h"
namespace Seele namespace Seele
+4 -4
View File
@@ -31,7 +31,7 @@ RenderHierarchy::~RenderHierarchy()
void RenderHierarchy::addElement(PElement addedElement) void RenderHierarchy::addElement(PElement addedElement)
{ {
std::lock_guard lock(updateLock); std::unique_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::lock_guard lock(updateLock); std::unique_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::lock_guard lock(updateLock); std::unique_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::lock_guard lock(updateLock); std::unique_lock lock(updateLock);
localUpdates = updates; localUpdates = updates;
updates.clear(); updates.clear();
} }
-2
View File
@@ -1,7 +1,5 @@
target_sources(SeeleEngine target_sources(SeeleEngine
PRIVATE PRIVATE
Frame.h
Frame.cpp
InspectorView.h InspectorView.h
InspectorView.cpp InspectorView.cpp
SceneView.h SceneView.h
View File
-18
View File
@@ -1,18 +0,0 @@
#pragma once
#include "View.h"
namespace Seele
{
// A frame is the mutable data needed to
// process a time step for the game updates
// It contains all the game update relevant data
// and is handed over to the renderer for read only processing
// If the game loop runs faster than the renderer, the renderer
// simply discards old Frames and starts working on the more recent ones
// if the game loop runs slower than the renderer (bad), the renderer has to wait
struct Frame
{
uint64 frameNumber;
Array<PViewFrame> viewFrame;
};
} // namespace Seele
+4 -8
View File
@@ -25,10 +25,10 @@ void Window::render()
gfxHandle->beginFrame(); gfxHandle->beginFrame();
for(auto& windowView : views) for(auto& windowView : views)
{ {
{ windowView->view->beginUpdate();
std::lock_guard lock(windowView->workerMutex); windowView->view->update();
windowView->view->prepareRender(); windowView->view->commitUpdate();
} windowView->view->prepareRender();
windowView->view->render(); windowView->view->render();
} }
gfxHandle->endFrame(); gfxHandle->endFrame();
@@ -58,9 +58,5 @@ void Window::viewWorker(WindowView* windowView)
{ {
while(true) while(true)
{ {
windowView->view->beginUpdate();
windowView->view->update();
std::lock_guard lock(windowView->workerMutex);
windowView->view->commitUpdate();
} }
} }