Trying to fix invalid descriptorlayout

This commit is contained in:
Dynamitos
2020-10-03 11:00:10 +02:00
parent 79388bf41a
commit ceee96b462
69 changed files with 1087 additions and 393 deletions
+9 -2
View File
@@ -3,7 +3,8 @@
{ {
"name": "Win32", "name": "Win32",
"includePath": [ "includePath": [
"${workspaceFolder}/**" "${workspaceFolder}/**",
"${VULKAN_SDK}\\Include"
], ],
"defines": [ "defines": [
"_DEBUG", "_DEBUG",
@@ -13,7 +14,13 @@
"windowsSdkVersion": "10.0.18362.0", "windowsSdkVersion": "10.0.18362.0",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe", "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe",
"intelliSenseMode": "msvc-x64", "intelliSenseMode": "msvc-x64",
"configurationProvider": "ms-vscode.cmake-tools" "configurationProvider": "ms-vscode.cmake-tools",
"cppStandard": "c++17",
"browse": {
"path": [
"${VULKAN_SDK}/**"
]
}
} }
], ],
"version": 4 "version": 4
+3 -1
View File
@@ -111,5 +111,7 @@
"cmake.skipConfigureIfCachePresent": false, "cmake.skipConfigureIfCachePresent": false,
"cmake.configureArgs": [ "cmake.configureArgs": [
"-Wno-dev" "-Wno-dev"
] ],
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.intelliSenseMode": "msvc-x64"
} }
+12 -5
View File
@@ -5,6 +5,7 @@ set(CMAKE_CXX_STANDARD 17)
# Handle superbuild first # Handle superbuild first
option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON) option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON)
set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine) set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine)
set(EXTERNAL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/external) set(EXTERNAL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/external)
set(ASSIMP_ROOT ${EXTERNAL_ROOT}/assimp) set(ASSIMP_ROOT ${EXTERNAL_ROOT}/assimp)
@@ -14,12 +15,18 @@ set(GLM_ROOT ${EXTERNAL_ROOT}/glm)
set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw) set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw)
set(JSON_ROOT ${EXTERNAL_ROOT}/json) set(JSON_ROOT ${EXTERNAL_ROOT}/json)
set(STB_ROOT ${EXTERNAL_ROOT}/stb) set(STB_ROOT ${EXTERNAL_ROOT}/stb)
set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
set(Boost_LIB_PREFIX lib) set(Boost_LIB_PREFIX lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
#Workaround for vs, because it places artifacts into an additional subfolder
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/bin/Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/bin/Release)
if (USE_SUPERBUILD) if (USE_SUPERBUILD)
project (SUPERBUILD NONE) project (SUPERBUILD NONE)
# execute the superbuild (this script will be invoked again without the # execute the superbuild (this script will be invoked again without the
@@ -30,26 +37,25 @@ else()
project (Seele) project (Seele)
endif() endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
#Workaround for vs, because it places artifacts into an additional subfolder
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/bin/Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/bin/Release)
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)
find_package(assimp REQUIRED ${ASSIMP_ROOT}) find_package(assimp REQUIRED)
find_package(JSON REQUIRED) find_package(JSON REQUIRED)
find_package(GLFW REQUIRED) find_package(GLFW REQUIRED)
find_package(SPIRV REQUIRED)
include_directories(${GLM_INCLUDE_DIRS}) include_directories(${GLM_INCLUDE_DIRS})
include_directories(${STB_INCLUDE_DIRS}) include_directories(${STB_INCLUDE_DIRS})
include_directories(${Vulkan_INCLUDE_DIR}) include_directories(${Vulkan_INCLUDE_DIR})
include_directories(${SPIRV_INCLUDE_DIRS})
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
include_directories(${GLFW_INCLUDE_DIRS}) include_directories(${GLFW_INCLUDE_DIRS})
include_directories(${SLANG_INCLUDE_DIRS}) include_directories(${SLANG_INCLUDE_DIRS})
include_directories(${ASSIMP_INCLUDE_DIRS}) include_directories(${ASSIMP_INCLUDE_DIRS})
include_directories(${JSON_INCLUDE_DIRS}) include_directories(${JSON_INCLUDE_DIRS})
include_directories(${SPIRV_INCLUDE_DIRS})
include_directories(${ENGINE_ROOT}) include_directories(${ENGINE_ROOT})
include_directories(src/Engine) include_directories(src/Engine)
add_definitions(${GLM_DEFINITIONS}) add_definitions(${GLM_DEFINITIONS})
@@ -66,6 +72,7 @@ target_link_libraries(SeeleEngine ${GLFW_LIBRARIES})
target_link_libraries(SeeleEngine ${SLANG_LIBRARY}) target_link_libraries(SeeleEngine ${SLANG_LIBRARY})
target_link_libraries(SeeleEngine ${ASSIMP_LIBRARIES}) target_link_libraries(SeeleEngine ${ASSIMP_LIBRARIES})
target_link_libraries(SeeleEngine ${JSON_LIBRARY}) target_link_libraries(SeeleEngine ${JSON_LIBRARY})
target_link_libraries(SeeleEngine ${SPIRV_LIBRARIES})
#target_precompile_headers(SeeleEngine #target_precompile_headers(SeeleEngine
# PRIVATE # PRIVATE
+4 -1
View File
@@ -6,7 +6,10 @@
"debug": { "debug": {
"short": "Debug", "short": "Debug",
"long": "Enable debugging and validation", "long": "Enable debugging and validation",
"buildType": "Debug" "buildType": "Debug",
"settings": {
"CMAKE_DEBUG_POSTFIX": "d"
}
}, },
"release": { "release": {
"short": "Release", "short": "Release",
+4 -6
View File
@@ -26,19 +26,17 @@ if (WIN32)
# Find library files # Find library files
find_library( find_library(
ASSIMP_LIBRARY ASSIMP_LIBRARY
NAMES assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.lib NAMES assimp-vc${MSVC_TOOLSET_VERSION}-mt${CMAKE_DEBUG_POSTFIX}
PATHS PATHS
$ENV{PROGRAMFILES}/lib $ENV{PROGRAMFILES}/lib
${ASSIMP_ROOT}/lib/ ${ASSIMP_ROOT}/lib/)
PATH_SUFFIXES Debug Release)
find_file( find_file(
ASSIMP_BINARY ASSIMP_BINARY
NAMES assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.dll NAMES assimp-vc${MSVC_TOOLSET_VERSION}-mt${CMAKE_DEBUG_POSTFIX}.dll
PATHS PATHS
$ENV{PROGRAMFILES}/bin $ENV{PROGRAMFILES}/bin
${ASSIMP_ROOT}/bin/ ${ASSIMP_ROOT}/bin/)
PATH_SUFFIXES Debug Release)
else() else()
# Find include files # Find include files
find_path( find_path(
+13 -1
View File
@@ -8,7 +8,7 @@ set(ASSIMP_BUILD_TESTS OFF CACHE INTERNAL "")
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE INTERNAL "") set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE INTERNAL "")
set(ASSIMP_INSTALL OFF CACHE INTERNAL "") set(ASSIMP_INSTALL OFF CACHE INTERNAL "")
add_subdirectory(${ASSIMP_ROOT} ${ASSIMP_ROOT}) add_subdirectory(${ASSIMP_ROOT} ${})
target_compile_definitions(assimp PRIVATE _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) target_compile_definitions(assimp PRIVATE _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING)
#-------------BOOST---------------- #-------------BOOST----------------
@@ -97,6 +97,18 @@ list(APPEND EXTRA_CMAKE_ARGS
-DSLANG_BINARY=${SLANG_BINARY} -DSLANG_BINARY=${SLANG_BINARY}
-DSLANG_GLSLANG=${SLANG_GLSLANG}) -DSLANG_GLSLANG=${SLANG_GLSLANG})
#----------------SPIR-V-CROSS--------------------
list(APPEND DEPENDENCIES spirv-cross-reflect)
set(SPIRV_CROSS_ENABLE_HLSL OFF CACHE BOOL "")
set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "")
set(SPIRV_CROSS_CLI OFF CACHE BOOL "")
set(SPIRV_CROSS_ENABLE_C_API OFF CACHE BOOL "")
set(SPIRV_CROSS_ENABLE_UTIL OFF CACHE BOOL "")
set(SPIRV_CROSS_SKIP_INSTALL ON CACHE BOOL "")
add_subdirectory(${SPIRV_ROOT})
#-----------------SeeleEngine-------------------- #-----------------SeeleEngine--------------------
ExternalProject_Add(SeeleEngine ExternalProject_Add(SeeleEngine
DEPENDS ${DEPENDENCIES} DEPENDS ${DEPENDENCIES}
+1 -1
+2 -18
View File
@@ -1,30 +1,14 @@
import Common;
import Material; import Material;
import VERTEX_INPUT_IMPORT; import VERTEX_INPUT_IMPORT;
import MATERIAL_IMPORT; import MATERIAL_IMPORT;
import PrimitiveSceneData;
struct ViewParams
{
float4x4 viewMatrix;
float4x4 projectionMatrix;
float4 cameraPos_WS;
};
layout(set = 0, binding = 0)
ParameterBlock<ViewParams> gViewParams;
layout(set = 1)
type_param TMaterial : IMaterial;
ParameterBlock<TMaterial> gMaterial;
struct ModelParameter struct ModelParameter
{ {
float4x4 modelMatrix; float4x4 modelMatrix;
} }
[[vk::push_constant]]
ConstantBuffer<ModelParameter> gModelParams;
struct VertexStageOutput struct VertexStageOutput
{ {
float4 position : SV_Position; float4 position : SV_Position;
+4 -6
View File
@@ -1,7 +1,7 @@
import Common;
import LightEnv; import LightEnv;
import BRDF; import BRDF;
import Material; import Material;
import Common;
import VERTEX_INPUT_IMPORT; import VERTEX_INPUT_IMPORT;
import MATERIAL_IMPORT; import MATERIAL_IMPORT;
@@ -13,9 +13,6 @@ import MaterialParameter;
//layout(set = 0, binding = 3) //layout(set = 0, binding = 3)
//RWTexture2D<uint2> lightGrid; //RWTexture2D<uint2> lightGrid;
type_param TMaterial : IMaterial;
layout(set = 1)
ParameterBlock<TMaterial> gMaterial;
struct VertexStageOutput struct VertexStageOutput
{ {
@@ -31,9 +28,10 @@ VertexStageOutput vertexMain(
VertexStageOutput output; VertexStageOutput output;
VertexValueCache cache = input.getVertexCache(); VertexValueCache cache = input.getVertexCache();
float3 worldPosition = input.getWorldPosition(); float3 worldPosition = input.getWorldPosition();
worldPosition += gMaterial.getWorldOffset();
float4 clipSpacePosition; float4 clipSpacePosition;
float3x3 tangentToLocal = cache.tangentToLocal; float3x3 tangentToLocal = cache.getTangentToLocal();
MaterialVertexParameter vertexParams = input.getMaterialVertexParameters(cache, worldPosition, tangentToLocal); MaterialVertexParameter vertexParams = input.getMaterialVertexParameters(cache, worldPosition, tangentToLocal);
float4 viewSpacePosition = mul(gViewParams.viewMatrix, float4(worldPosition, 1)); float4 viewSpacePosition = mul(gViewParams.viewMatrix, float4(worldPosition, 1));
@@ -75,5 +73,5 @@ float4 fragmentMain(
} }
return float4(0, 1, 0, 1); return float4(result, 1);
} }
+14 -3
View File
@@ -2,17 +2,28 @@ const static float PI = 3.1415926535897932f;
const static uint MAX_PARTICLES = 65536; const static uint MAX_PARTICLES = 65536;
const static uint BLOCK_SIZE = 8; const static uint BLOCK_SIZE = 8;
cbuffer ScreenToViewParams struct ViewParameter
{
float4x4 viewMatrix;
float4x4 projectionMatrix;
float4 cameraPos_WS;
}
layout(set = 1, binding = 0, std430)
ConstantBuffer<ViewParameter> gViewParams;
struct ScreenToViewParams
{ {
float4x4 inverseProjection; float4x4 inverseProjection;
float2 screenDimensions; float2 screenDimensions;
} }
layout(set = 1, binding = 1, std430)
ConstantBuffer<ScreenToViewParams> gScreenToViewParams;
// Convert clip space coordinates to view space // Convert clip space coordinates to view space
float4 clipToView( float4 clip ) float4 clipToView( float4 clip )
{ {
// View space position. // View space position.
float4 view = mul( inverseProjection, clip ); float4 view = mul( gScreenToViewParams.inverseProjection, clip );
// Perspective projection. // Perspective projection.
view = view / view.w; view = view / view.w;
@@ -23,7 +34,7 @@ float4 clipToView( float4 clip )
float4 screenToView( float4 screen ) float4 screenToView( float4 screen )
{ {
// Convert to normalized texture coordinates // Convert to normalized texture coordinates
float2 texCoord = screen.xy / screenDimensions; float2 texCoord = screen.xy / gScreenToViewParams.screenDimensions;
// Convert to clip space // Convert to clip space
float4 clip = float4( float2( texCoord.x, -texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w ); float4 clip = float4( float2( texCoord.x, -texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w );
+6 -7
View File
@@ -23,28 +23,27 @@ struct PointLight : ILightEnv
{ {
float4 positionWS; float4 positionWS;
float4 positionVS; float4 positionVS;
float3 color; float4 colorRange;
float range;
float3 illuminate<B:IBRDF>(MaterialFragmentParameter input, B brdf, float3 viewDir) float3 illuminate<B:IBRDF>(MaterialFragmentParameter input, B brdf, float3 viewDir)
{ {
float3 lightVec = positionWS.xyz - input.worldPosition; float3 lightVec = positionWS.xyz - input.worldPosition;
float d = length(lightVec); float d = length(lightVec);
float3 direction = normalize(lightVec); float3 direction = normalize(lightVec);
float illuminance = max(1 - d / range, 0); float illuminance = max(1 - d / colorRange.w, 0);
return illuminance * brdf.evaluate(viewDir, direction, input.worldNormal, input.worldTangent, input.worldBiTangent, color); return illuminance * brdf.evaluate(viewDir, direction, input.worldNormal, input.worldTangent, input.worldBiTangent, colorRange.xyz);
} }
bool insidePlane(Plane plane) bool insidePlane(Plane plane)
{ {
return dot(plane.n, positionVS.xyz) - plane.d < -range; return dot(plane.n, positionVS.xyz) - plane.d < -colorRange.w;
} }
bool insideFrustum(Frustum frustum, float zNear, float zFar) bool insideFrustum(Frustum frustum, float zNear, float zFar)
{ {
bool result = true; bool result = true;
//if(positionVS.z - range > zNear || positionVS.z + range < zFar) //if(positionVS.z - range > zNear || positionVS.z + colorRange.w < zFar)
{ {
// result = false; // result = false;
} }
@@ -69,5 +68,5 @@ struct Lights
uint numPointLights; uint numPointLights;
}; };
layout(set = 0, binding = 1) layout(set = 0, binding = 0, std430)
ConstantBuffer<Lights> gLightEnv; ConstantBuffer<Lights> gLightEnv;
+4
View File
@@ -16,3 +16,7 @@ interface IMaterial
float getRoughness(MaterialFragmentParameter input); float getRoughness(MaterialFragmentParameter input);
float getSheen(MaterialFragmentParameter input); float getSheen(MaterialFragmentParameter input);
}; };
type_param TMaterial : IMaterial;
layout(set = 2, binding = 0, std430)
ParameterBlock<TMaterial> gMaterial;
-1
View File
@@ -44,4 +44,3 @@ struct MaterialFragmentParameter
} }
}; };
+1 -12
View File
@@ -4,16 +4,5 @@ struct PrimitiveSceneData
float4x4 worldToLocal; float4x4 worldToLocal;
}; };
layout(set = 3, binding = 0, std430)
struct ViewParameter
{
float4x4 viewMatrix;
float4x4 projectionMatrix;
float4 cameraPos_WS;
};
layout(set = 0)
ConstantBuffer<ViewParameter> gViewParams;
layout(set = 2)
ConstantBuffer<PrimitiveSceneData> gSceneData; ConstantBuffer<PrimitiveSceneData> gSceneData;
+28 -5
View File
@@ -1,13 +1,30 @@
import Common;
import MaterialParameter; import MaterialParameter;
import PrimitiveSceneData; import PrimitiveSceneData;
struct VertexValueCache struct VertexValueCache
{ {
float3x3 tangentToLocal; //This struct is passed between vertex and fragment stage
float3x3 tangentToWorld; //which means, that it is passed as out mat3x3 in glsl
//but Slang for some reason puts a layout(row_major) above
//every attribute, including this matrix, but matrix layout
//qualifiers are illegal for non-uniform and buffer fields,
//leading to a compiler error
float3 tangentToLocal[3];
float3 tangentToWorld[3];
float tangentToWorldSign; float tangentToWorldSign;
float4 color; float4 color;
float3x3 getTangentToLocal()
{
return float3x3(tangentToLocal[0], tangentToLocal[1], tangentToLocal[2]);
}
float3x3 getTangentToWorld()
{
return float3x3(tangentToWorld[0], tangentToWorld[1], tangentToWorld[2]);
}
#if USE_INSTANCING #if USE_INSTANCING
float4 instanceOrigin; float4 instanceOrigin;
float3 instanceTransform1; float3 instanceTransform1;
@@ -133,9 +150,15 @@ struct VertexShaderInput
#endif #endif
float tangentSign; float tangentSign;
cache.tangentToLocal = calcTangentToLocal(tangentSign); float3x3 tangentToLocal = calcTangentToLocal(tangentSign);
cache.tangentToLocal[0] = tangentToLocal[0];
cache.tangentToLocal[1] = tangentToLocal[1];
cache.tangentToLocal[2] = tangentToLocal[2];
float3x3 localToWorld = float3x3(gSceneData.localToWorld[0].xyz, gSceneData.localToWorld[1].xyz, gSceneData.localToWorld[2].xyz); float3x3 localToWorld = float3x3(gSceneData.localToWorld[0].xyz, gSceneData.localToWorld[1].xyz, gSceneData.localToWorld[2].xyz);
cache.tangentToWorld = mul(cache.tangentToLocal, localToWorld); float3x3 tangentToWorld = mul(tangentToLocal, localToWorld);
cache.tangentToWorld[0] = tangentToWorld[0];
cache.tangentToWorld[1] = tangentToWorld[1];
cache.tangentToWorld[2] = tangentToWorld[2];
cache.tangentToWorldSign = tangentSign; cache.tangentToWorldSign = tangentSign;
return cache; return cache;
@@ -146,7 +169,7 @@ struct VertexShaderInput
MaterialVertexParameter result; MaterialVertexParameter result;
result.worldPosition = worldPosition; result.worldPosition = worldPosition;
result.vertexColor = cache.color; result.vertexColor = cache.color;
result.tangentToWorld = cache.tangentToWorld; result.tangentToWorld = cache.getTangentToWorld();
// TODO instancing // TODO instancing
/*for(int i = 0; i < NUM_MATERIAL_TEXCOORDS-1; i+=2) /*for(int i = 0; i < NUM_MATERIAL_TEXCOORDS-1; i+=2)
{ {
+15 -6
View File
@@ -24,7 +24,6 @@ void AssetRegistry::importFile(const std::string &filePath)
{ {
std::filesystem::path fsPath = std::filesystem::path(filePath); std::filesystem::path fsPath = std::filesystem::path(filePath);
std::string extension = fsPath.extension().string(); std::string extension = fsPath.extension().string();
std::cout << extension << std::endl;
if (extension.compare(".fbx") == 0 if (extension.compare(".fbx") == 0
|| extension.compare(".obj") == 0) || extension.compare(".obj") == 0)
{ {
@@ -46,6 +45,16 @@ PMeshAsset AssetRegistry::findMesh(const std::string &filePath)
return get().meshes[filePath]; return get().meshes[filePath];
} }
PTextureAsset AssetRegistry::findTexture(const std::string &filePath)
{
PTextureAsset result = get().textures[filePath];
if(result == nullptr)
{
return get().textureLoader->getPlaceholderTexture();
}
return result;
}
PMaterialAsset AssetRegistry::findMaterial(const std::string &filePath) PMaterialAsset AssetRegistry::findMaterial(const std::string &filePath)
{ {
return get().materials[filePath]; return get().materials[filePath];
@@ -61,11 +70,6 @@ std::ifstream AssetRegistry::createReadStream(const std::string& relativePath, s
return get().internalCreateReadStream(relativePath, openmode); return get().internalCreateReadStream(relativePath, openmode);
} }
PTextureAsset AssetRegistry::findTexture(const std::string &filePath)
{
return get().textures[filePath];
}
AssetRegistry &AssetRegistry::get() AssetRegistry &AssetRegistry::get()
{ {
static AssetRegistry instance; static AssetRegistry instance;
@@ -122,6 +126,11 @@ void AssetRegistry::registerMesh(PMeshAsset mesh)
} }
} }
void AssetRegistry::registerMaterial(PMaterialAsset material)
{
materials[material->getFileName()] = material;
}
std::ofstream AssetRegistry::internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode) std::ofstream AssetRegistry::internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode)
{ {
return std::ofstream(rootFolder.generic_string().append(relativePath), openmode); return std::ofstream(rootFolder.generic_string().append(relativePath), openmode);
+7
View File
@@ -1,6 +1,7 @@
#include "MaterialLoader.h" #include "MaterialLoader.h"
#include "Material/Material.h" #include "Material/Material.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "AssetRegistry.h"
using namespace Seele; using namespace Seele;
@@ -21,7 +22,13 @@ PMaterial MaterialLoader::queueAsset(const std::filesystem::path& filePath)
PMaterial result = new Material(filePath); PMaterial result = new Material(filePath);
result->compile(); result->compile();
graphics->getShaderCompiler()->registerMaterial(result); graphics->getShaderCompiler()->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,
// maybe in the future there could be a substance loader or something // maybe in the future there could be a substance loader or something
return result; return result;
} }
PMaterial MaterialLoader::getPlaceHolderMaterial()
{
return placeholderMaterial;
}
+1
View File
@@ -15,6 +15,7 @@ public:
MaterialLoader(Gfx::PGraphics graphic); MaterialLoader(Gfx::PGraphics graphic);
~MaterialLoader(); ~MaterialLoader();
PMaterial queueAsset(const std::filesystem::path& filePath); PMaterial queueAsset(const std::filesystem::path& filePath);
PMaterial getPlaceHolderMaterial();
private: private:
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
List<std::future<void>> futures; List<std::future<void>> futures;
+24 -23
View File
@@ -33,7 +33,7 @@ void MeshLoader::importAsset(const std::filesystem::path &path)
import(path); import(path);
} }
void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics) void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics)
{ {
using json = nlohmann::json; using json = nlohmann::json;
for(uint32 i = 0; i < scene->mNumMaterials; ++i) for(uint32 i = 0; i < scene->mNumMaterials; ++i)
@@ -42,7 +42,6 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
json matCode; json matCode;
matCode["name"] = material->GetName().C_Str(); matCode["name"] = material->GetName().C_Str();
matCode["profile"] = "BlinnPhong"; //TODO: other shading models matCode["profile"] = "BlinnPhong"; //TODO: other shading models
std::vector<std::string> code;
aiString texPath; aiString texPath;
//TODO make samplers based on used textures //TODO make samplers based on used textures
matCode["params"]["texSampler"] = matCode["params"]["texSampler"] =
@@ -57,7 +56,7 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
{"type", "Texture2D"}, {"type", "Texture2D"},
{"default", texPath.C_Str()} {"default", texPath.C_Str()}
}; };
code.push_back("result.baseColor = diffuseTexture.Sample(textureSampler, geometry.texCoord).xyz;\n"); matCode["code"]["baseColor"] = "return diffuseTexture.Sample(textureSampler, geometry.texCoord).xyz;";
} }
if(material->GetTexture(aiTextureType_SPECULAR, 0, &texPath) == AI_SUCCESS) if(material->GetTexture(aiTextureType_SPECULAR, 0, &texPath) == AI_SUCCESS)
{ {
@@ -67,7 +66,7 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
{"type", "Texture2D"}, {"type", "Texture2D"},
{"default", texPath.C_Str()} {"default", texPath.C_Str()}
}; };
code.push_back("result.specular = specularTexture.Sample(textureSampler, geometry.texCoord).xyz;\n"); matCode["code"]["specular"] = "return specularTexture.Sample(textureSampler, geometry.texCoord).xyz;";
} }
if(material->GetTexture(aiTextureType_NORMALS, 0, &texPath) == AI_SUCCESS) if(material->GetTexture(aiTextureType_NORMALS, 0, &texPath) == AI_SUCCESS)
{ {
@@ -77,21 +76,20 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
{"type", "Texture2D"}, {"type", "Texture2D"},
{"default", texPath.C_Str()} {"default", texPath.C_Str()}
}; };
code.push_back("float3 bumpMapNormal = normalTexture.Sample(textureSampler, geometry.texCoord).xyz;\n"); matCode["code"]["normal"] = "return normalTexture.Sample(textureSampler, geometry.texCoord).xyz;";
code.push_back("bumpMapNormal = 2.0 * bumpMapNormal - float3(1.0f, 1.0f, 1.0f);\n");
code.push_back("result.normal = geometry.transformLocalToWorld(bumpMapNormal);\n");
} }
code.push_back("return result;\n");
matCode["code"] = code;
std::string outMatFilename = matCode["name"].get<std::string>().append(".asset"); std::string outMatFilename = matCode["name"].get<std::string>().append(".asset");
std::ofstream outMatFile = AssetRegistry::createWriteStream(outMatFilename); std::ofstream outMatFile = AssetRegistry::createWriteStream(outMatFilename);
outMatFile << std::setw(4) << matCode; outMatFile << std::setw(4) << matCode;
outMatFile.flush(); outMatFile.flush();
outMatFile.close(); outMatFile.close();
//TODO: let the material loader handle this instead //TODO: let the material loader handle this instead
std::cout << matCode["name"] << std::endl; //std::cout << matCode << std::endl;
AssetRegistry::importFile(outMatFilename); PMaterial result = new Material(outMatFilename);
PMaterialAsset asset = AssetRegistry::findMaterial(outMatFilename); result->compile();
graphics->getShaderCompiler()->registerMaterial(result);
AssetRegistry::get().registerMaterial(result);
PMaterialAsset asset = AssetRegistry::findMaterial(result->getFileName());
globalMaterials[i] = asset; globalMaterials[i] = asset;
} }
} }
@@ -148,35 +146,38 @@ VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gf
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo); Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT); return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
} }
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PMaterialAsset> materials, Gfx::PGraphics graphics) void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PMaterialAsset> materials, Gfx::PGraphics graphics)
{ {
for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
{ {
aiMesh *mesh = scene->mMeshes[meshIndex]; aiMesh *mesh = scene->mMeshes[meshIndex];
PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str())); PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str()));
VertexStreamComponent positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics); StaticMeshDataType data;
vertexShaderInput->setPositionStream(positionStream); data.positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics);
for(uint32 i = 0; i < MAX_TEXCOORDS; ++i) for(uint32 i = 0; i < MAX_TEXCOORDS; ++i)
{ {
if(mesh->HasTextureCoords(i)) if(mesh->HasTextureCoords(i))
{ {
VertexStreamComponent texCoordStream = createVertexStream(mesh->mNumVertices, mesh->mTextureCoords[i], graphics); data.textureCoordinates.add(createVertexStream(mesh->mNumVertices, mesh->mTextureCoords[i], graphics));
vertexShaderInput->setTexCoordStream(i, texCoordStream);
} }
} }
if(mesh->HasNormals()) if(mesh->HasNormals())
{ {
VertexStreamComponent normalStream = createVertexStream(mesh->mNumVertices, mesh->mNormals, graphics); data.tangentBasisComponents[0] = createVertexStream(mesh->mNumVertices, mesh->mNormals, graphics);
vertexShaderInput->setTangentXStream(normalStream);
} }
if(mesh->HasTangentsAndBitangents()) if(mesh->HasTangentsAndBitangents())
{ {
//TODO: use bitangent to calculate sign for 4th coordinate of tangentstream //TODO: use bitangent to calculate sign for 4th coordinate of tangentstream
VertexStreamComponent tangentStream = createVertexStream(mesh->mNumVertices, mesh->mTangents, graphics); data.tangentBasisComponents[1] = createVertexStream(mesh->mNumVertices, mesh->mTangents, graphics);
vertexShaderInput->setTangentZStream(tangentStream);
} }
if(mesh->HasVertexColors(0))
{
//data.colorComponent = createVertexStream(mesh->mNumVertices, mesh->mColors[0], graphics);
}
vertexShaderInput->setData(data);
vertexShaderInput->init(graphics);
Array<uint32> indices(mesh->mNumFaces * 3); Array<uint32> indices(mesh->mNumFaces * 3);
for (uint32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) for (uint32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex)
@@ -197,7 +198,7 @@ void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PM
globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex]; globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex];
} }
} }
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels) void MeshLoader::convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels)
{ {
for(uint32 i = 0; i < numPixels; ++i) for(uint32 i = 0; i < numPixels; ++i)
{ {
@@ -207,7 +208,7 @@ void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels)
dst[i * 4 + 3] = src[i].a; dst[i * 4 + 3] = src[i].a;
} }
} }
void loadTextures(const aiScene* scene, Gfx::PGraphics graphics, const std::filesystem::path& meshPath) void MeshLoader::loadTextures(const aiScene* scene, Gfx::PGraphics graphics, const std::filesystem::path& meshPath)
{ {
for (uint32 i = 0; i < scene->mNumTextures; ++i) for (uint32 i = 0; i < scene->mNumTextures; ++i)
{ {
+10 -1
View File
@@ -5,9 +5,13 @@
#include <future> #include <future>
#include <filesystem> #include <filesystem>
struct aiScene;
struct aiTexel;
namespace Seele namespace Seele
{ {
DECLARE_REF(MeshAsset) DECLARE_REF(Mesh);
DECLARE_REF(MeshAsset);
DECLARE_REF(MaterialAsset);
DECLARE_NAME_REF(Gfx, Graphics); DECLARE_NAME_REF(Gfx, Graphics);
class MeshLoader class MeshLoader
{ {
@@ -16,6 +20,11 @@ public:
~MeshLoader(); ~MeshLoader();
void importAsset(const std::filesystem::path& filePath); void importAsset(const std::filesystem::path& filePath);
private: private:
void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics);
void loadTextures(const aiScene* scene, Gfx::PGraphics graphics, const std::filesystem::path& meshPath);
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PMaterialAsset> materials, Gfx::PGraphics graphics);
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
void import(const std::filesystem::path& path); void import(const std::filesystem::path& path);
List<std::future<void>> futures; List<std::future<void>> futures;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
+10 -2
View File
@@ -12,7 +12,10 @@ using namespace Seele;
TextureLoader::TextureLoader(Gfx::PGraphics graphics) TextureLoader::TextureLoader(Gfx::PGraphics graphics)
: graphics(graphics) : graphics(graphics)
{ {
placeholderAsset = new TextureAsset();
placeholderTexture = import("./textures/placeholder.png"); placeholderTexture = import("./textures/placeholder.png");
placeholderAsset->setTexture(placeholderTexture);
placeholderAsset->setStatus(Asset::Status::Ready);
} }
TextureLoader::~TextureLoader() TextureLoader::~TextureLoader()
@@ -26,11 +29,16 @@ void TextureLoader::importAsset(const std::filesystem::path& filePath)
asset->setStatus(Asset::Status::Loading); asset->setStatus(Asset::Status::Loading);
asset->setTexture(placeholderTexture); asset->setTexture(placeholderTexture);
AssetRegistry::get().textures[filePath.string()] = asset; AssetRegistry::get().textures[filePath.string()] = asset;
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable { //futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
Gfx::PTexture2D texture = import(filePath); Gfx::PTexture2D texture = import(filePath);
asset->setTexture(texture); asset->setTexture(texture);
asset->setStatus(Asset::Status::Ready); asset->setStatus(Asset::Status::Ready);
})); //}));
}
PTextureAsset TextureLoader::getPlaceholderTexture()
{
return placeholderAsset;
} }
Gfx::PTexture2D TextureLoader::import(const std::filesystem::path& path) Gfx::PTexture2D TextureLoader::import(const std::filesystem::path& path)
+2
View File
@@ -16,11 +16,13 @@ public:
TextureLoader(Gfx::PGraphics graphic); TextureLoader(Gfx::PGraphics graphic);
~TextureLoader(); ~TextureLoader();
void importAsset(const std::filesystem::path& filePath); void importAsset(const std::filesystem::path& filePath);
PTextureAsset getPlaceholderTexture();
private: private:
Gfx::PTexture2D import(const std::filesystem::path& path); Gfx::PTexture2D import(const std::filesystem::path& path);
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
List<std::future<void>> futures; List<std::future<void>> futures;
Gfx::PTexture2D placeholderTexture; Gfx::PTexture2D placeholderTexture;
PTextureAsset placeholderAsset;
}; };
DEFINE_REF(TextureLoader); DEFINE_REF(TextureLoader);
} // namespace Seele } // namespace Seele
+25
View File
@@ -229,6 +229,15 @@ namespace Seele
refreshIterators(); refreshIterators();
return _data[arraySize - 1]; return _data[arraySize - 1];
} }
T &addUnique(const T &item = T())
{
Iterator it;
if((it = find(item)) != endIt)
{
return *it;
}
return add(item);
}
template<typename... args> template<typename... args>
T &emplace(args...) T &emplace(args...)
{ {
@@ -291,6 +300,22 @@ namespace Seele
} }
refreshIterators(); refreshIterators();
} }
inline uint32 indexOf(Iterator iterator)
{
return iterator - beginIt;
}
inline uint32 indexOf(ConstIterator iterator) const
{
return iterator.p - beginIt.p;
}
inline uint32 indexOf(T& t)
{
return indexOf(find(t));
}
inline uint32 indexOf(const T& t) const
{
return indexOf(find(t));
}
inline uint32 size() const inline uint32 size() const
{ {
return arraySize; return arraySize;
+15
View File
@@ -11,3 +11,18 @@ Graphics::Graphics()
Graphics::~Graphics() Graphics::~Graphics()
{ {
} }
PVertexBuffer Graphics::getNullVertexBuffer()
{
if(nullVertexBuffer == nullptr)
{
VertexBufferCreateInfo createInfo;
createInfo.numVertices = 1;
createInfo.vertexSize = sizeof(Vector4);
Vector4 data = Vector4(1, 1, 1, 1);
createInfo.resourceData.data = reinterpret_cast<uint8*>(&data);
createInfo.resourceData.size = sizeof(Vector4);
nullVertexBuffer = createVertexBuffer(createInfo);
}
return nullVertexBuffer;
}
+7 -2
View File
@@ -41,17 +41,22 @@ public:
virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0; virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0; virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
virtual PRenderCommand createRenderCommand() = 0; virtual PRenderCommand createRenderCommand() = 0;
virtual PVertexDeclaration createVertexDeclaration(const Array<VertexElement>& element) = 0;
virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0; virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0;
virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0; virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0;
virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0; virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0; virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0;
virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0; virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0; virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0;
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
virtual Gfx::PDescriptorLayout createDescriptorLayout() = 0; virtual PDescriptorLayout createDescriptorLayout() = 0;
virtual Gfx::PPipelineLayout createPipelineLayout() = 0; virtual PPipelineLayout createPipelineLayout() = 0;
PVertexBuffer getNullVertexBuffer();
protected: protected:
PVertexBuffer nullVertexBuffer;
QueueFamilyMapping queueMapping; QueueFamilyMapping queueMapping;
PShaderCompiler shaderCompiler; PShaderCompiler shaderCompiler;
friend class Window; friend class Window;
+1
View File
@@ -7,6 +7,7 @@ namespace Gfx
static constexpr bool useAsyncCompute = true; static constexpr bool useAsyncCompute = true;
static constexpr bool waitIdleOnSubmit = true; static constexpr bool waitIdleOnSubmit = true;
static constexpr uint32 numFramesBuffered = 3; static constexpr uint32 numFramesBuffered = 3;
static uint32 currentFrameIndex = 0;
enum class MaterialShadingModel enum class MaterialShadingModel
{ {
+15 -5
View File
@@ -19,7 +19,7 @@ struct GraphicsInitializer
Array<const char *> instanceExtensions; Array<const char *> instanceExtensions;
Array<const char *> deviceExtensions; Array<const char *> deviceExtensions;
GraphicsInitializer() GraphicsInitializer()
: applicationName("SeeleEngine"), engineName("SeeleEngine"), layers{"VK_LAYER_LUNARG_standard_validation"}, instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr) : applicationName("SeeleEngine"), engineName("SeeleEngine"), layers{"VK_LAYER_KHRONOS_validation"}, instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr)
{ {
} }
GraphicsInitializer(const GraphicsInitializer &other) GraphicsInitializer(const GraphicsInitializer &other)
@@ -74,6 +74,9 @@ struct TextureCreateInfo
{ {
} }
}; };
struct SamplerCreateInfo
{
};
struct VertexBufferCreateInfo struct VertexBufferCreateInfo
{ {
BulkResourceData resourceData; BulkResourceData resourceData;
@@ -114,12 +117,18 @@ struct SePushConstantRange
struct VertexElement struct VertexElement
{ {
VertexElement(){} VertexElement(){}
VertexElement(uint32 location, SeFormat vertexFormat, uint32 offset) //VertexElement(uint8 attributeIndex, SeFormat vertexFormat, uint8 offset)
: location(location), vertexFormat(vertexFormat), offset(offset) // : attributeIndex(attributeIndex), vertexFormat(vertexFormat), offset(offset)
//{}
VertexElement(uint8 streamIndex, uint8 offset, SeFormat vertexFormat, uint8 attributeIndex, uint8 stride)
: streamIndex(streamIndex), offset(offset), vertexFormat(vertexFormat), attributeIndex(attributeIndex), stride(stride)
{} {}
uint32 location; uint8 streamIndex;
uint8 offset;
SeFormat vertexFormat; SeFormat vertexFormat;
uint32 offset; uint8 attributeIndex;
uint8 stride;
uint8 bInstanced = 0;
}; };
struct RasterizationState struct RasterizationState
{ {
@@ -190,6 +199,7 @@ struct GraphicsPipelineCreateInfo
Gfx::PGeometryShader geometryShader; Gfx::PGeometryShader geometryShader;
Gfx::PFragmentShader fragmentShader; Gfx::PFragmentShader fragmentShader;
Gfx::PRenderPass renderPass; Gfx::PRenderPass renderPass;
Gfx::PPipelineLayout pipelineLayout;
Gfx::SePrimitiveTopology topology; Gfx::SePrimitiveTopology topology;
Gfx::RasterizationState rasterizationState; Gfx::RasterizationState rasterizationState;
Gfx::DepthStencilState depthStencilState; Gfx::DepthStencilState depthStencilState;
+53 -16
View File
@@ -72,6 +72,13 @@ ShaderCollection& ShaderMap::createShaders(
collection.fragmentShader = graphics->createFragmentShader(createInfo); collection.fragmentShader = graphics->createFragmentShader(createInfo);
} }
ShaderPermutation permutation;
std::string materialName = material->getFileName(); //Filename is fine, because it just has to be unique
std::string vertexInputName = vertexInput->getName();
permutation.passType = renderPass;
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
collection.id = PermutationId(permutation);
return collection; return collection;
} }
@@ -95,6 +102,11 @@ PDescriptorSet DescriptorLayout::allocatedDescriptorSet()
return result; return result;
} }
void DescriptorLayout::reset()
{
allocator->reset();
}
void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout) void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout)
{ {
if (descriptorSetLayouts.size() <= setIndex) if (descriptorSetLayouts.size() <= setIndex)
@@ -110,7 +122,6 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo
{ {
if (otherBindings[i].descriptorType != SE_DESCRIPTOR_TYPE_MAX_ENUM) if (otherBindings[i].descriptorType != SE_DESCRIPTOR_TYPE_MAX_ENUM)
{ {
assert(thisBindings[i].descriptorType != SE_DESCRIPTOR_TYPE_MAX_ENUM ? thisBindings[i].descriptorType == otherBindings[i].descriptorType : true);
thisBindings[i] = otherBindings[i]; thisBindings[i] = otherBindings[i];
} }
} }
@@ -118,8 +129,8 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo
else else
{ {
descriptorSetLayouts[setIndex] = layout; descriptorSetLayouts[setIndex] = layout;
layout->setIndex = setIndex;
} }
layout->setIndex = setIndex;
} }
void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant) void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant)
@@ -155,14 +166,27 @@ Buffer::~Buffer()
{ {
} }
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, QueueType startQueueType) UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData)
: Buffer(mapping, startQueueType) : Buffer(mapping, resourceData.owner)
, size(resourceData.size)
{ {
if(resourceData.data != nullptr)
{
contents = new uint8[size];
std::memcpy(contents, resourceData.data, size);
}
} }
UniformBuffer::~UniformBuffer() UniformBuffer::~UniformBuffer()
{ {
} }
void UniformBuffer::updateContents(const BulkResourceData& resourceData)
{
assert(size == resourceData.size);
std::memcpy(contents, resourceData.data, size);
}
StructuredBuffer::StructuredBuffer(QueueFamilyMapping mapping, QueueType startQueueType) StructuredBuffer::StructuredBuffer(QueueFamilyMapping mapping, QueueType startQueueType)
: Buffer(mapping, startQueueType) : Buffer(mapping, startQueueType)
{ {
@@ -220,15 +244,27 @@ VertexDeclaration::VertexDeclaration()
VertexDeclaration::~VertexDeclaration() VertexDeclaration::~VertexDeclaration()
{ {
} }
uint32 VertexDeclaration::addVertexStream(const VertexStreamComponent &element)
static std::mutex vertexDeclarationLock;
static Map<uint32, PVertexDeclaration> vertexDeclarationCache;
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList)
{ {
VertexStream& stream = vertexStreams.add(); std::scoped_lock lock(vertexDeclarationLock);
stream.addVertexElement(VertexElement(element.streamOffset, element.type, element.offset)); boost::crc_32_type result;
return stream.vertexDescription.size() - 1; result.process_bytes(&elementList, sizeof(VertexElement) * elementList.size());
} uint32 key = result.checksum();
const Array<VertexStream> &VertexDeclaration::getVertexStreams() const
{ auto found = vertexDeclarationCache[key];
return vertexStreams; if(found == nullptr)
{
return found;
}
PVertexDeclaration newDeclaration = graphics->createVertexDeclaration(elementList);
vertexDeclarationCache[key] = newDeclaration;
return newDeclaration;
} }
Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
@@ -263,21 +299,21 @@ RenderTargetLayout::RenderTargetLayout()
} }
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment) RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment)
: inputAttachments(), colorAttachments(), depthAttachment(depthAttachment) : inputAttachments(), colorAttachments(), depthAttachment(depthAttachment), width(depthAttachment->getTexture()->getSizeX()), height(depthAttachment->getTexture()->getSizeY())
{ {
} }
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment) RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment)
: inputAttachments(), depthAttachment(depthAttachment) : inputAttachments(), depthAttachment(depthAttachment), width(depthAttachment->getTexture()->getSizeX()), height(depthAttachment->getTexture()->getSizeY())
{ {
colorAttachments.add(colorAttachment); colorAttachments.add(colorAttachment);
} }
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet) RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet)
: inputAttachments(), colorAttachments(colorAttachments), depthAttachment(depthAttachment) : inputAttachments(), colorAttachments(colorAttachments), depthAttachment(depthAttachment), width(depthAttachment->getTexture()->getSizeX()), height(depthAttachment->getTexture()->getSizeY())
{ {
} }
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment) RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
: inputAttachments(inputAttachments), colorAttachments(colorAttachments), depthAttachment(depthAttachment) : inputAttachments(inputAttachments), colorAttachments(colorAttachments), depthAttachment(depthAttachment), width(depthAttachment->getTexture()->getSizeX()), height(depthAttachment->getTexture()->getSizeY())
{ {
} }
@@ -298,3 +334,4 @@ Viewport::Viewport(PWindow owner, const ViewportCreateInfo &viewportInfo)
Viewport::~Viewport() Viewport::~Viewport()
{ {
} }
+33 -4
View File
@@ -16,6 +16,7 @@ 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);
@@ -178,6 +179,7 @@ public:
DescriptorAllocator() {} DescriptorAllocator() {}
virtual ~DescriptorAllocator() {} virtual ~DescriptorAllocator() {}
virtual void allocateDescriptorSet(PDescriptorSet &descriptorSet) = 0; virtual void allocateDescriptorSet(PDescriptorSet &descriptorSet) = 0;
virtual void reset() = 0;
}; };
DEFINE_REF(DescriptorAllocator); DEFINE_REF(DescriptorAllocator);
DECLARE_REF(UniformBuffer); DECLARE_REF(UniformBuffer);
@@ -187,6 +189,8 @@ class DescriptorSet
{ {
public: public:
virtual ~DescriptorSet() {} virtual ~DescriptorSet() {}
virtual void beginFrame() = 0;
virtual void endFrame() = 0;
virtual void writeChanges() = 0; virtual void writeChanges() = 0;
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0; virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
@@ -213,6 +217,7 @@ public:
} }
virtual void create() = 0; virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1); virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
virtual void reset();
virtual PDescriptorSet allocatedDescriptorSet(); virtual PDescriptorSet allocatedDescriptorSet();
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; } const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
inline uint32 getSetIndex() const { return setIndex; } inline uint32 getSetIndex() const { return setIndex; }
@@ -308,9 +313,28 @@ protected:
class UniformBuffer : public Buffer class UniformBuffer : public Buffer
{ {
public: public:
UniformBuffer(QueueFamilyMapping mapping, QueueType startQueueType); UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData);
virtual ~UniformBuffer(); virtual ~UniformBuffer();
virtual void updateContents(const BulkResourceData& resourceData);
bool isDataEquals(UniformBuffer* other)
{
if(other == nullptr)
{
return false;
}
if(size != other->size)
{
return false;
}
if(std::memcmp(contents, other->contents, size) != 0)
{
return false;
}
return true;
}
protected: protected:
void* contents;
uint32 size;
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
}; };
@@ -393,11 +417,9 @@ class VertexDeclaration
public: public:
VertexDeclaration(); VertexDeclaration();
~VertexDeclaration(); ~VertexDeclaration();
uint32 addVertexStream(const VertexStreamComponent &vertexStream);
const Array<VertexStream> &getVertexStreams() const;
static PVertexDeclaration createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList);
private: private:
Array<VertexStream> vertexStreams;
}; };
DEFINE_REF(VertexDeclaration); DEFINE_REF(VertexDeclaration);
class GraphicsPipeline class GraphicsPipeline
@@ -429,6 +451,7 @@ public:
virtual uint32 getSizeX() const = 0; virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0; virtual uint32 getSizeY() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0;
virtual class Texture2D* getTexture2D() { return nullptr; }
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
@@ -444,19 +467,23 @@ public:
virtual uint32 getSizeX() const = 0; virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0; virtual uint32 getSizeY() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0;
virtual class Texture2D* getTexture2D() { return this; }
protected: protected:
//Inherited via QueueOwnedResource //Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
}; };
DEFINE_REF(Texture2D); DEFINE_REF(Texture2D);
DECLARE_REF(Viewport);
class RenderCommand class RenderCommand
{ {
public: public:
RenderCommand(); RenderCommand();
virtual ~RenderCommand(); virtual ~RenderCommand();
virtual void setViewport(Gfx::PViewport viewport) = 0;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindDescriptor(Array<Gfx::PDescriptorSet> sets) = 0;
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0; virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
virtual void draw(const MeshBatchElement& data) = 0; virtual void draw(const MeshBatchElement& data) = 0;
@@ -592,6 +619,8 @@ public:
Array<PRenderTargetAttachment> inputAttachments; Array<PRenderTargetAttachment> inputAttachments;
Array<PRenderTargetAttachment> colorAttachments; Array<PRenderTargetAttachment> colorAttachments;
PRenderTargetAttachment depthAttachment; PRenderTargetAttachment depthAttachment;
uint32 width;
uint32 height;
}; };
DEFINE_REF(RenderTargetLayout); DEFINE_REF(RenderTargetLayout);
+2 -2
View File
@@ -2,7 +2,7 @@
namespace Seele namespace Seele
{ {
DECLARE_REF(Material); DECLARE_REF(MaterialAsset);
DECLARE_REF(VertexShaderInput); DECLARE_REF(VertexShaderInput);
DECLARE_NAME_REF(Gfx, VertexBuffer); DECLARE_NAME_REF(Gfx, VertexBuffer);
DECLARE_NAME_REF(Gfx, IndexBuffer); DECLARE_NAME_REF(Gfx, IndexBuffer);
@@ -54,7 +54,7 @@ struct MeshBatch
PVertexShaderInput vertexInput; PVertexShaderInput vertexInput;
PMaterial material; PMaterialAsset material;
inline int32 getNumPrimitives() const inline int32 getNumPrimitives() const
{ {
+109 -21
View File
@@ -1,11 +1,14 @@
#include "BasePass.h" #include "BasePass.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/Window.h" #include "Graphics/Window.h"
#include "Scene/Components/CameraComponent.h"
#include "Scene/Actor/CameraActor.h"
using namespace Seele; using namespace Seele;
BasePassMeshProcessor::BasePassMeshProcessor(const PScene scene, Gfx::PGraphics graphics, uint8 translucentBasePass) BasePassMeshProcessor::BasePassMeshProcessor(const PScene scene, Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass)
: MeshProcessor(scene, graphics) : MeshProcessor(scene, graphics)
, target(viewport)
, translucentBasePass(translucentBasePass) , translucentBasePass(translucentBasePass)
{ {
} }
@@ -16,31 +19,49 @@ BasePassMeshProcessor::~BasePassMeshProcessor()
void BasePassMeshProcessor::addMeshBatch( void BasePassMeshProcessor::addMeshBatch(
const MeshBatch& batch, const MeshBatch& batch,
const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass renderPass,
Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet> descriptorSets,
int32 staticMeshId) int32 staticMeshId)
{ {
const PMaterial material = batch.material; const PMaterialAsset material = batch.material;
const Gfx::MaterialShadingModel shadingModel = material->getShadingModel(); const Gfx::MaterialShadingModel shadingModel = material->getShadingModel();
const PVertexShaderInput vertexInput = batch.vertexInput; const PVertexShaderInput vertexInput = batch.vertexInput;
//TODO query tesselation 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)
{
Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocatedDescriptorSet();
descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer);
descriptorSet->writeChanges();
cachedPrimitiveSets.add(descriptorSet);
}
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand(); Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
buildMeshDrawCommand(batch, renderCommand->setViewport(target);
primitiveComponent, uint32 primitiveDescriptorIndex = 0;
renderPass, for(uint32 i = 0; i < batch.elements.size(); ++i)
renderCommand, {
material, pipelineLayout->addDescriptorLayout(2, material->getRenderMaterial()->getDescriptorLayout());
collection->vertexShader, pipelineLayout->create();
collection->controlShader, descriptorSets[2] = material->getDescriptor();
collection->evalutionShader, descriptorSets[3] = cachedPrimitiveSets[primitiveDescriptorIndex++];
collection->geometryShader, buildMeshDrawCommand(batch,
collection->fragmentShader, // primitiveComponent,
false); renderPass,
pipelineLayout,
renderCommand,
descriptorSets,
collection->vertexShader,
collection->controlShader,
collection->evalutionShader,
collection->geometryShader,
collection->fragmentShader,
false);
}
renderCommands.add(renderCommand); renderCommands.add(renderCommand);
} }
@@ -52,12 +73,16 @@ Array<Gfx::PRenderCommand> BasePassMeshProcessor::getRenderCommands()
void BasePassMeshProcessor::clearCommands() void BasePassMeshProcessor::clearCommands()
{ {
renderCommands.clear(); renderCommands.clear();
cachedPrimitiveSets.clear();
} }
BasePass::BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport) BasePass::BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
: processor(new BasePassMeshProcessor(scene, graphics, false)) : processor(new BasePassMeshProcessor(scene, viewport, graphics, false))
, scene(scene) , scene(scene)
, graphics(graphics) , graphics(graphics)
, viewport(viewport)
, descriptorSets(4)
, source(source->getCameraComponent())
{ {
Gfx::PRenderTargetAttachment colorAttachment = new Gfx::SwapchainAttachment(viewport->getOwner()); Gfx::PRenderTargetAttachment colorAttachment = new Gfx::SwapchainAttachment(viewport->getOwner());
TextureCreateInfo depthBufferInfo; TextureCreateInfo depthBufferInfo;
@@ -70,20 +95,83 @@ BasePass::BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport v
new Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE); new Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment); Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment);
renderPass = graphics->createRenderPass(layout); renderPass = graphics->createRenderPass(layout);
BulkResourceData uniformInitializer;
basePassLayout = graphics->createPipelineLayout();
lightLayout = graphics->createDescriptorLayout();
lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformInitializer.size = sizeof(LightEnv);
uniformInitializer.data = (uint8*)&scene->getLightEnvironment();
lightUniform = graphics->createUniformBuffer(uniformInitializer);
lightLayout->create();
basePassLayout->addDescriptorLayout(0, lightLayout);
descriptorSets[0] = lightLayout->allocatedDescriptorSet();
viewLayout = graphics->createDescriptorLayout();
viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformInitializer.size = sizeof(ViewParameter);
uniformInitializer.data = (uint8*)&viewParams;
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
viewLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformInitializer.size = sizeof(ScreenToViewParameter);
uniformInitializer.data = (uint8*)&screenToViewParams;
screenToViewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
viewLayout->create();
basePassLayout->addDescriptorLayout(1, viewLayout);
descriptorSets[1] = viewLayout->allocatedDescriptorSet();
primitiveLayout = graphics->createDescriptorLayout();
primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
primitiveLayout->create();
basePassLayout->addDescriptorLayout(3, primitiveLayout);
} }
BasePass::~BasePass() BasePass::~BasePass()
{ {
} }
void BasePass::render() void BasePass::beginFrame()
{ {
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset();
BulkResourceData uniformUpdate;
uniformUpdate.size = sizeof(LightEnv);
uniformUpdate.data = (uint8*)&scene->getLightEnvironment();
lightUniform->updateContents(uniformUpdate);
descriptorSets[0]->beginFrame();
descriptorSets[0]->updateBuffer(0, lightUniform);
descriptorSets[0]->writeChanges();
viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.cameraPosition = Vector4(source->getTransform().getPosition(), 0);
screenToViewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
screenToViewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
uniformUpdate.size = sizeof(ViewParameter);
uniformUpdate.data = (uint8*)&viewParams;
viewParamBuffer->updateContents(uniformUpdate);
uniformUpdate.size = sizeof(ScreenToViewParameter);
uniformUpdate.data = (uint8*)&screenToViewParams;
screenToViewParamBuffer->updateContents(uniformUpdate);
descriptorSets[1]->beginFrame();
descriptorSets[1]->updateBuffer(0, viewParamBuffer);
descriptorSets[1]->updateBuffer(1, screenToViewParamBuffer);
descriptorSets[1]->writeChanges();
}
void BasePass::render()
{
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
for (auto &&primitive : scene->getStaticMeshes()) for (auto &&primitive : scene->getStaticMeshes())
{ {
processor->addMeshBatch(primitive, nullptr, renderPass); processor->addMeshBatch(primitive, renderPass, basePassLayout, primitiveLayout, descriptorSets);
} }
graphics->executeCommands(processor->getRenderCommands()); graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass(); graphics->endRenderPass();
} }
void BasePass::endFrame()
{
}
+39 -3
View File
@@ -7,33 +7,69 @@ namespace Seele
class BasePassMeshProcessor : public MeshProcessor class BasePassMeshProcessor : public MeshProcessor
{ {
public: public:
BasePassMeshProcessor(const PScene scene, Gfx::PGraphics graphics, uint8 translucentBasePass); BasePassMeshProcessor(const PScene scene, Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass);
virtual ~BasePassMeshProcessor(); virtual ~BasePassMeshProcessor();
virtual void addMeshBatch( virtual void addMeshBatch(
const MeshBatch& batch, const MeshBatch& batch,
const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass renderPass,
Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet> descriptorSets,
int32 staticMeshId = -1) override; int32 staticMeshId = -1) override;
Array<Gfx::PRenderCommand> getRenderCommands(); Array<Gfx::PRenderCommand> getRenderCommands();
void clearCommands(); void clearCommands();
private: private:
Array<Gfx::PRenderCommand> renderCommands; Array<Gfx::PRenderCommand> renderCommands;
Array<Gfx::PDescriptorSet> cachedPrimitiveSets;
Gfx::PViewport target;
uint8 translucentBasePass; uint8 translucentBasePass;
}; };
DEFINE_REF(BasePassMeshProcessor); DEFINE_REF(BasePassMeshProcessor);
DECLARE_REF(CameraActor);
DECLARE_REF(CameraComponent);
class BasePass class BasePass
{ {
public: public:
BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport); BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source);
~BasePass(); ~BasePass();
void beginFrame();
void render(); void render();
void endFrame();
private: private:
struct ViewParameter
{
Matrix4 viewMatrix;
Matrix4 projectionMatrix;
Vector4 cameraPosition;
} viewParams;
struct ScreenToViewParameter
{
Matrix4 inverseProjectionMatrix;
Vector2 screenDimensions;
} screenToViewParams;
Gfx::PRenderPass renderPass; Gfx::PRenderPass renderPass;
Gfx::PTexture2D depthBuffer; Gfx::PTexture2D depthBuffer;
const PScene scene; const PScene scene;
UPBasePassMeshProcessor processor; UPBasePassMeshProcessor processor;
Gfx::PPipelineLayout basePassLayout;
// Set 0: Light environment
Gfx::PDescriptorLayout lightLayout;
Gfx::PUniformBuffer lightUniform;
// Set 1: viewParameter
Gfx::PDescriptorLayout viewLayout;
Gfx::PUniformBuffer viewParamBuffer;
Gfx::PUniformBuffer screenToViewParamBuffer;
// Set 2: materials, generated
// Set 3: primitive scene data
Gfx::PDescriptorLayout primitiveLayout;
Gfx::PUniformBuffer primitiveUniformBuffer;
Array<Gfx::PDescriptorSet> descriptorSets;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
PCameraComponent source;
Gfx::PViewport viewport;
}; };
DEFINE_REF(BasePass); DEFINE_REF(BasePass);
} // namespace Seele } // namespace Seele
@@ -17,10 +17,11 @@ MeshProcessor::~MeshProcessor()
void MeshProcessor::buildMeshDrawCommand( void MeshProcessor::buildMeshDrawCommand(
const MeshBatch& meshBatch, const MeshBatch& meshBatch,
const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass renderPass,
Gfx::PPipelineLayout pipelineLayout,
Gfx::PRenderCommand drawCommand, Gfx::PRenderCommand drawCommand,
PMaterial material, Array<Gfx::PDescriptorSet> descriptors,
Gfx::PVertexShader vertexShader, Gfx::PVertexShader vertexShader,
Gfx::PControlShader controlShader, Gfx::PControlShader controlShader,
Gfx::PEvaluationShader evaluationShader, Gfx::PEvaluationShader evaluationShader,
@@ -40,6 +41,7 @@ void MeshProcessor::buildMeshDrawCommand(
pipelineInitializer.geometryShader = geometryShader; pipelineInitializer.geometryShader = geometryShader;
pipelineInitializer.fragmentShader = fragmentShader; pipelineInitializer.fragmentShader = fragmentShader;
pipelineInitializer.renderPass = renderPass; pipelineInitializer.renderPass = renderPass;
pipelineInitializer.pipelineLayout = pipelineLayout;
VertexInputStreamArray vertexStreams; VertexInputStreamArray vertexStreams;
if(positionOnly) if(positionOnly)
@@ -50,9 +52,10 @@ void MeshProcessor::buildMeshDrawCommand(
{ {
vertexInput->getStreams(vertexStreams); vertexInput->getStreams(vertexStreams);
} }
drawCommand->bindVertexBuffer(vertexStreams);
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInitializer); Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInitializer);
drawCommand->bindPipeline(pipeline); drawCommand->bindPipeline(pipeline);
drawCommand->bindVertexBuffer(vertexStreams);
drawCommand->bindDescriptor(descriptors);
for(auto element : meshBatch.elements) for(auto element : meshBatch.elements)
{ {
drawCommand->bindIndexBuffer(element.indexBuffer); drawCommand->bindIndexBuffer(element.indexBuffer);
@@ -16,15 +16,19 @@ protected:
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
virtual void addMeshBatch( virtual void addMeshBatch(
const MeshBatch& meshBatch, const MeshBatch& meshBatch,
const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass renderPass,
Gfx::PPipelineLayout pipelineLayout,
Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet> descriptorSets,
int32 staticMeshId = -1) = 0; int32 staticMeshId = -1) = 0;
void buildMeshDrawCommand( void buildMeshDrawCommand(
const MeshBatch& meshBatch, const MeshBatch& meshBatch,
const PPrimitiveComponent primitiveComponent, // const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass renderPass, const Gfx::PRenderPass renderPass,
Gfx::PPipelineLayout pipelineLayout,
Gfx::PRenderCommand drawCommand, Gfx::PRenderCommand drawCommand,
PMaterial material, Array<Gfx::PDescriptorSet> descriptors,
Gfx::PVertexShader vertexShader, Gfx::PVertexShader vertexShader,
Gfx::PControlShader controlShader, Gfx::PControlShader controlShader,
Gfx::PEvaluationShader evaluationShader, Gfx::PEvaluationShader evaluationShader,
+4 -4
View File
@@ -5,11 +5,11 @@
using namespace Seele; using namespace Seele;
SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target) SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target, PCameraActor source)
: RenderPath(graphics, target) : RenderPath(graphics, target)
, scene(scene) , scene(scene)
{ {
basePass = new BasePass(scene, graphics, target); basePass = new BasePass(scene, graphics, target, source);
} }
SceneRenderPath::~SceneRenderPath() SceneRenderPath::~SceneRenderPath()
@@ -28,7 +28,7 @@ void SceneRenderPath::init()
void SceneRenderPath::beginFrame() void SceneRenderPath::beginFrame()
{ {
basePass->beginFrame();
} }
void SceneRenderPath::render() void SceneRenderPath::render()
@@ -38,5 +38,5 @@ void SceneRenderPath::render()
void SceneRenderPath::endFrame() void SceneRenderPath::endFrame()
{ {
basePass->endFrame();
} }
+2 -1
View File
@@ -5,10 +5,11 @@
namespace Seele namespace Seele
{ {
DECLARE_REF(Scene); DECLARE_REF(Scene);
DECLARE_REF(CameraActor);
class SceneRenderPath : public RenderPath class SceneRenderPath : public RenderPath
{ {
public: public:
SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target); SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target, PCameraActor source);
virtual ~SceneRenderPath(); virtual ~SceneRenderPath();
void setTargetScene(PScene scene); void setTargetScene(PScene scene);
virtual void init(); virtual void init();
+4 -1
View File
@@ -2,6 +2,7 @@
#include "SceneRenderPath.h" #include "SceneRenderPath.h"
#include "Scene/Scene.h" #include "Scene/Scene.h"
#include "Window.h" #include "Window.h"
#include "Scene/Actor/CameraActor.h"
using namespace Seele; using namespace Seele;
@@ -9,7 +10,9 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
: View(graphics, owner, createInfo) : View(graphics, owner, createInfo)
{ {
scene = new Scene(graphics); scene = new Scene(graphics);
renderer = new SceneRenderPath(scene, graphics, viewport); PCameraActor camera = new CameraActor();
scene->addActor(camera);
renderer = new SceneRenderPath(scene, graphics, viewport, camera);
} }
Seele::SceneView::~SceneView() Seele::SceneView::~SceneView()
+1 -1
View File
@@ -18,7 +18,7 @@ ShaderCompiler::~ShaderCompiler()
void ShaderCompiler::registerMaterial(PMaterial material) void ShaderCompiler::registerMaterial(PMaterial material)
{ {
for(auto type : VertexInputType::getTypeList()) for(auto& type : VertexInputType::getTypeList())
{ {
material->createShaders(graphics, Gfx::RenderPassType::DepthPrepass, type); material->createShaders(graphics, Gfx::RenderPassType::DepthPrepass, type);
material->createShaders(graphics, Gfx::RenderPassType::BasePass, type); material->createShaders(graphics, Gfx::RenderPassType::BasePass, type);
+47 -26
View File
@@ -1,4 +1,5 @@
#include "StaticMeshVertexInput.h" #include "StaticMeshVertexInput.h"
#include "Graphics/Graphics.h"
using namespace Seele; using namespace Seele;
@@ -13,36 +14,56 @@ StaticMeshVertexInput::~StaticMeshVertexInput()
} }
void StaticMeshVertexInput::setPositionStream(const VertexStreamComponent& positionStream) void StaticMeshVertexInput::init(Gfx::PGraphics graphics)
{ {
declaration->addVertexStream(positionStream); if(data.positionStream.vertexBuffer != data.tangentBasisComponents[0].vertexBuffer)
positionDeclaration->addVertexStream(positionStream); {
data.positionStream = positionStream; Array<Gfx::VertexElement> positionOnlyStreamElements;
positionOnlyStreamElements.add(accessPositionStreamComponent(data.positionStream, 0));
initPositionDeclaration(graphics, positionOnlyStreamElements);
}
Array<Gfx::VertexElement> elements;
if(data.positionStream.vertexBuffer != nullptr)
{
elements.add(accessStreamComponent(data.positionStream, 0));
}
uint8 tangentBasisAttributes[2] = {1, 2};
for(int32 axisIndex = 0; axisIndex < 2; axisIndex++)
{
if(data.tangentBasisComponents[axisIndex].vertexBuffer != nullptr)
{
elements.add(accessStreamComponent(data.tangentBasisComponents[axisIndex], tangentBasisAttributes[axisIndex]));
}
}
if(data.colorComponent.vertexBuffer != nullptr)
{
elements.add(accessStreamComponent(data.colorComponent, 3));
}
else
{
elements.add(accessStreamComponent(VertexStreamComponent(graphics->getNullVertexBuffer(), 0, 0, Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), 3));
}
if(data.textureCoordinates.size())
{
const int32 baseTexCoordAttribute = 4;
for(uint32 coordinateIndex = 0; coordinateIndex < data.textureCoordinates.size(); ++coordinateIndex)
{
elements.add(accessStreamComponent(
data.textureCoordinates[coordinateIndex],
baseTexCoordAttribute + coordinateIndex
));
}
}
initDeclaration(graphics, elements);
} }
void StaticMeshVertexInput::setTangentXStream(const VertexStreamComponent& tangentXStream) void StaticMeshVertexInput::setData(StaticMeshDataType data)
{ {
declaration->addVertexStream(tangentXStream); this->data = data;
data.tangentBasisComponents[0] = tangentXStream;
}
void StaticMeshVertexInput::setTangentZStream(const VertexStreamComponent& tangentZStream)
{
declaration->addVertexStream(tangentZStream);
data.tangentBasisComponents[1] = tangentZStream;
}
void StaticMeshVertexInput::setTexCoordStream(uint32 index, const VertexStreamComponent& textureStream)
{
//TODO: replace add with proper indexing
declaration->addVertexStream(textureStream);
data.textureCoordinates.add(textureStream);
}
void StaticMeshVertexInput::setColorStream(const VertexStreamComponent& colorStream)
{
declaration->addVertexStream(colorStream);
data.colorComponent = colorStream;
} }
IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput"); IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput");
+2 -5
View File
@@ -20,11 +20,8 @@ class StaticMeshVertexInput : public VertexShaderInput
public: public:
StaticMeshVertexInput(std::string name); StaticMeshVertexInput(std::string name);
virtual ~StaticMeshVertexInput(); virtual ~StaticMeshVertexInput();
void setPositionStream(const VertexStreamComponent& positionStream); virtual void init(Gfx::PGraphics graphics) override;
void setTangentXStream(const VertexStreamComponent& tangentXStream); void setData(StaticMeshDataType data);
void setTangentZStream(const VertexStreamComponent& tangentZStream);
void setTexCoordStream(uint32 index, const VertexStreamComponent& textureStream);
void setColorStream(const VertexStreamComponent& colorStream);
private: private:
StaticMeshDataType data; StaticMeshDataType data;
}; };
+34 -3
View File
@@ -1,5 +1,6 @@
#include "VertexShaderInput.h" #include "VertexShaderInput.h"
#include "Graphics/Mesh.h" #include "Graphics/Mesh.h"
#include "Graphics/Graphics.h"
#include <sstream> #include <sstream>
#include <memory> #include <memory>
@@ -7,7 +8,7 @@ using namespace Seele;
List<VertexInputType*> VertexInputType::globalTypeList; List<VertexInputType*> VertexInputType::globalTypeList;
List<VertexInputType*> VertexInputType::getTypeList() List<VertexInputType*>& VertexInputType::getTypeList()
{ {
return globalTypeList; return globalTypeList;
} }
@@ -62,7 +63,7 @@ void VertexShaderInput::getStreams(VertexInputStreamArray& outVertexStreams) con
{ {
for(uint32 i = 0; i < streams.size(); ++i) for(uint32 i = 0; i < streams.size(); ++i)
{ {
const VertexInputStream& stream = streams[i]; const VertexStream& stream = streams[i];
if(stream.vertexBuffer == nullptr) if(stream.vertexBuffer == nullptr)
{ {
outVertexStreams.add(VertexInputStream(i, 0, nullptr)); outVertexStreams.add(VertexInputStream(i, 0, nullptr));
@@ -78,7 +79,37 @@ void VertexShaderInput::getPositionOnlyStream(VertexInputStreamArray& outVertexS
{ {
for (uint32 i = 0; i < positionStreams.size(); ++i) for (uint32 i = 0; i < positionStreams.size(); ++i)
{ {
const VertexInputStream& stream = positionStreams[i]; const VertexStream& stream = positionStreams[i];
outVertexStreams.add(VertexInputStream(i, stream.offset, stream.vertexBuffer)); outVertexStreams.add(VertexInputStream(i, stream.offset, stream.vertexBuffer));
} }
} }
Gfx::VertexElement VertexShaderInput::accessStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex)
{
VertexStream vertexStream;
vertexStream.vertexBuffer = component.vertexBuffer;
vertexStream.stride = component.stride;
vertexStream.offset = component.offset;
return Gfx::VertexElement(streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
}
Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex)
{
VertexStream vertexStream;
vertexStream.vertexBuffer = component.vertexBuffer;
vertexStream.stride = component.stride;
vertexStream.offset = component.offset;
return Gfx::VertexElement(streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
}
void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements)
{
declaration = graphics->createVertexDeclaration(elements);
}
void VertexShaderInput::initPositionDeclaration(Gfx::PGraphics graphics, const Array<Gfx::VertexElement>& elements)
{
positionDeclaration = graphics->createVertexDeclaration(elements);
}
+27 -3
View File
@@ -81,7 +81,7 @@ struct VertexStreamComponent
class VertexInputType class VertexInputType
{ {
public: public:
static List<VertexInputType*> getTypeList(); static List<VertexInputType*>& getTypeList();
static VertexInputType* getVertexInputByName(const std::string& name); static VertexInputType* getVertexInputByName(const std::string& name);
VertexInputType( VertexInputType(
@@ -117,6 +117,7 @@ class VertexShaderInput
public: public:
VertexShaderInput(std::string name); VertexShaderInput(std::string name);
virtual ~VertexShaderInput(); virtual ~VertexShaderInput();
virtual void init(Gfx::PGraphics graphics) {};
void getStreams(VertexInputStreamArray& outVertexStreams) const; void getStreams(VertexInputStreamArray& outVertexStreams) const;
void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const; void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const;
virtual bool supportsTesselation() { return false; } virtual bool supportsTesselation() { return false; }
@@ -125,11 +126,34 @@ public:
Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;} Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;}
std::string getName() const { return name; } std::string getName() const { return name; }
protected: protected:
Gfx::VertexElement accessStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex);
Gfx::VertexElement accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex);
void initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements);
void initPositionDeclaration(Gfx::PGraphics graphics, const Array<Gfx::VertexElement>& elements);
static List<PVertexShaderInput> registeredInputs; static List<PVertexShaderInput> registeredInputs;
static std::mutex registeredInputsLock; static std::mutex registeredInputsLock;
Array<Gfx::VertexAttribute> layout; Array<Gfx::VertexAttribute> layout;
StaticArray<VertexInputStream, 16> streams;
StaticArray<VertexInputStream, 16> positionStreams; // internal helper class, basically a VertexInputStream plus stride
struct VertexStream
{
Gfx::PVertexBuffer vertexBuffer = nullptr;
uint8 stride = 0;
uint8 offset = 0;
friend bool operator==(const VertexStream& a, const VertexStream& b)
{
return a.vertexBuffer == b.vertexBuffer &&
a.stride == b.stride &&
a.offset == b.offset;
}
VertexStream()
{
}
};
Array<VertexStream> streams;
Array<VertexStream> positionStreams;
Gfx::PVertexDeclaration declaration; Gfx::PVertexDeclaration declaration;
Gfx::PVertexDeclaration positionDeclaration; Gfx::PVertexDeclaration positionDeclaration;
std::string name; std::string name;
+6 -1
View File
@@ -71,6 +71,11 @@ ShaderBuffer::~ShaderBuffer()
graphics = nullptr; graphics = nullptr;
} }
VkDeviceSize ShaderBuffer::getOffset() const
{
return buffers[currentBuffer].allocation->getOffset();
}
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
VkBufferMemoryBarrier barrier = VkBufferMemoryBarrier barrier =
@@ -235,7 +240,7 @@ void ShaderBuffer::unlock()
UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData) UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner) : Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner)
, Gfx::UniformBuffer(graphics->getFamilyMapping(), resourceData.owner) , Gfx::UniformBuffer(graphics->getFamilyMapping(), resourceData)
{ {
if (resourceData.data != nullptr) if (resourceData.data != nullptr)
{ {
@@ -150,6 +150,7 @@ void SecondaryCmdBuffer::begin(PCmdBuffer parent)
inheritanceInfo.renderPass = parent->renderPass->getHandle(); inheritanceInfo.renderPass = parent->renderPass->getHandle();
inheritanceInfo.subpass = parent->subpassIndex; inheritanceInfo.subpass = parent->subpassIndex;
beginInfo.pInheritanceInfo = &inheritanceInfo; beginInfo.pInheritanceInfo = &inheritanceInfo;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo)); VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
} }
@@ -158,6 +159,14 @@ void SecondaryCmdBuffer::end()
VK_CHECK(vkEndCommandBuffer(handle)); VK_CHECK(vkEndCommandBuffer(handle));
} }
void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport)
{
VkViewport vp = viewport.cast<Viewport>()->getHandle();
VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY());
vkCmdSetViewport(handle, 0, 1, &vp);
vkCmdSetScissor(handle, 0, 1, &scissors);
}
void SecondaryCmdBuffer::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline) void SecondaryCmdBuffer::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
{ {
pipeline = gfxPipeline.cast<GraphicsPipeline>(); pipeline = gfxPipeline.cast<GraphicsPipeline>();
@@ -168,6 +177,17 @@ void SecondaryCmdBuffer::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
VkDescriptorSet setHandle = descriptorSet.cast<DescriptorSet>()->getHandle(); VkDescriptorSet setHandle = descriptorSet.cast<DescriptorSet>()->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
} }
void SecondaryCmdBuffer::bindDescriptor(Array<Gfx::PDescriptorSet> descriptorSets)
{
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
for(uint32 i = 0; i < descriptorSets.size(); ++i)
{
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
}
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, descriptorSets.size(), sets, 0, nullptr);
delete[] sets;
}
void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& streams) void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& streams)
{ {
Array<VkBuffer> buffers(streams.size()); Array<VkBuffer> buffers(streams.size());
@@ -70,15 +70,17 @@ private:
DEFINE_REF(CmdBuffer); DEFINE_REF(CmdBuffer);
DECLARE_REF(GraphicsPipeline); DECLARE_REF(GraphicsPipeline);
class SecondaryCmdBuffer : public CmdBufferBase, public Gfx::RenderCommand class SecondaryCmdBuffer : public Gfx::RenderCommand, public CmdBufferBase
{ {
public: public:
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool); SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~SecondaryCmdBuffer(); virtual ~SecondaryCmdBuffer();
void begin(PCmdBuffer parent); void begin(PCmdBuffer parent);
void end(); void end();
virtual void setViewport(Gfx::PViewport viewport) override;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override;
virtual void bindDescriptor(Array<Gfx::PDescriptorSet> descriptorSets) override;
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) override; virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void draw(const MeshBatchElement& data) override; virtual void draw(const MeshBatchElement& data) override;
@@ -7,6 +7,11 @@
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
DescriptorLayout::DescriptorLayout(PGraphics graphics)
: graphics(graphics)
, layoutHandle(VK_NULL_HANDLE)
{
}
DescriptorLayout::~DescriptorLayout() DescriptorLayout::~DescriptorLayout()
{ {
if (layoutHandle != VK_NULL_HANDLE) if (layoutHandle != VK_NULL_HANDLE)
@@ -36,7 +41,13 @@ void DescriptorLayout::create()
init::DescriptorSetLayoutCreateInfo(bindings.data(), bindings.size()); init::DescriptorSetLayoutCreateInfo(bindings.data(), bindings.size());
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
std::cout << "creating descriptorlayout " << layoutHandle << std::endl;
allocator = new DescriptorAllocator(graphics, *this); allocator = new DescriptorAllocator(graphics, *this);
boost::crc_32_type result;
result.process_bytes(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size());
hash = result.checksum();
} }
PipelineLayout::~PipelineLayout() PipelineLayout::~PipelineLayout()
@@ -47,15 +58,23 @@ PipelineLayout::~PipelineLayout()
} }
} }
static Map<uint32, VkPipelineLayout> layoutCache;
void PipelineLayout::create() void PipelineLayout::create()
{ {
vulkanDescriptorLayouts.resize(descriptorSetLayouts.size()); vulkanDescriptorLayouts.resize(descriptorSetLayouts.size());
for (size_t i = 0; i < descriptorSetLayouts.size(); ++i) for (size_t i = 0; i < descriptorSetLayouts.size(); ++i)
{ {
// There could be unused descriptor set indices
if(descriptorSetLayouts[i] == nullptr)
{
continue;
}
PDescriptorLayout layout = descriptorSetLayouts[i].cast<DescriptorLayout>(); PDescriptorLayout layout = descriptorSetLayouts[i].cast<DescriptorLayout>();
layout->create(); layout->create();
vulkanDescriptorLayouts[i] = layout->getHandle(); vulkanDescriptorLayouts[i] = layout->getHandle();
} }
VkPipelineLayoutCreateInfo createInfo = VkPipelineLayoutCreateInfo createInfo =
init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), vulkanDescriptorLayouts.size()); init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), vulkanDescriptorLayouts.size());
Array<VkPushConstantRange> vkPushConstants(pushConstants.size()); Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
@@ -67,11 +86,20 @@ void PipelineLayout::create()
} }
createInfo.pushConstantRangeCount = vkPushConstants.size(); createInfo.pushConstantRangeCount = vkPushConstants.size();
createInfo.pPushConstantRanges = vkPushConstants.data(); createInfo.pPushConstantRanges = vkPushConstants.data();
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
boost::crc_32_type result; boost::crc_32_type result;
result.process_bytes(&createInfo, sizeof(VkPipelineLayoutCreateInfo)); result.process_bytes(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount);
result.process_bytes(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount);
layoutHash = result.checksum(); layoutHash = result.checksum();
if(layoutCache[layoutHash] != VK_NULL_HANDLE)
{
layoutHandle = layoutCache[layoutHash];
return;
}
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
layoutCache[layoutHash] = layoutHandle;
} }
void PipelineLayout::reset() void PipelineLayout::reset()
@@ -85,29 +113,57 @@ DescriptorSet::~DescriptorSet()
{ {
} }
void DescriptorSet::beginFrame()
{
currentFrameSet = (currentFrameSet + 1) % Gfx::numFramesBuffered;
}
void DescriptorSet::endFrame()
{
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
{ {
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>(); PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize()); UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[currentFrameSet][binding]);
// bufferInfos.add(bufferInfo); if(vulkanBuffer->isDataEquals(cachedBuffer))
{
return;
}
VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize());
bufferInfos.add(bufferInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back()); VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[currentFrameSet], VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[currentFrameSet][binding] = vulkanBuffer.getHandle();
} }
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer) void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
{ {
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>(); PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize()); StructuredBuffer* cachedBuffer = reinterpret_cast<StructuredBuffer*>(cachedData[currentFrameSet][binding]);
// bufferInfos.add(bufferInfo); if(vulkanBuffer.getHandle() == cachedBuffer)
{
return;
}
VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize());
bufferInfos.add(bufferInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back()); VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[currentFrameSet], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[currentFrameSet][binding] = vulkanBuffer.getHandle();
} }
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState) void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
{ {
PSamplerState vulkanSampler = samplerState.cast<SamplerState>(); PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[currentFrameSet][binding]);
if(vulkanSampler.getHandle() == cachedSampler)
{
return;
}
VkDescriptorImageInfo imageInfo = VkDescriptorImageInfo imageInfo =
init::DescriptorImageInfo( init::DescriptorImageInfo(
vulkanSampler->sampler, vulkanSampler->sampler,
@@ -115,13 +171,20 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerSt
VK_IMAGE_LAYOUT_UNDEFINED); VK_IMAGE_LAYOUT_UNDEFINED);
imageInfos.add(imageInfo); imageInfos.add(imageInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back()); VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[currentFrameSet], VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[currentFrameSet][binding] = vulkanSampler.getHandle();
} }
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState) void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
{ {
PTextureHandle vulkanTexture = TextureBase::cast(texture); TextureHandle* vulkanTexture = TextureBase::cast(texture);
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[currentFrameSet][binding]);
if(vulkanTexture == cachedTexture)
{
return;
}
//It is assumed that the image is in the correct layout //It is assumed that the image is in the correct layout
VkDescriptorImageInfo imageInfo = VkDescriptorImageInfo imageInfo =
init::DescriptorImageInfo( init::DescriptorImageInfo(
@@ -134,12 +197,14 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
imageInfo.sampler = vulkanSampler->sampler; imageInfo.sampler = vulkanSampler->sampler;
} }
imageInfos.add(imageInfo); imageInfos.add(imageInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, binding, &imageInfos.back()); VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[currentFrameSet], samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, binding, &imageInfos.back());
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{ {
writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
} }
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[currentFrameSet][binding] = vulkanTexture;
} }
bool DescriptorSet::operator<(Gfx::PDescriptorSet other) bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
@@ -160,8 +225,10 @@ void DescriptorSet::writeChanges()
} }
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout) DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout)
: layout(layout), graphics(graphics) : layout(layout), graphics(graphics), currentCachedIndex(0)
{ {
std::memset(&cachedHandles, 0, sizeof(cachedHandles));
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM
std::memset(perTypeSizes, 0, sizeof(perTypeSizes)); std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
for (uint32 i = 0; i < layout.getBindings().size(); ++i) for (uint32 i = 0; i < layout.getBindings().size(); ++i)
@@ -198,5 +265,25 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
VkDescriptorSetLayout layoutHandle = layout.getHandle(); VkDescriptorSetLayout layoutHandle = layout.getHandle();
VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo allocInfo =
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1); init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &vulkanSet->setHandle)); for(uint32 i = 0; i < Gfx::numFramesBuffered; ++i)
{
if(cachedHandles[currentCachedIndex] != VK_NULL_HANDLE)
{
vulkanSet->setHandle[i] = cachedHandles[currentCachedIndex++];
}
else
{
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &vulkanSet->setHandle[i]));
cachedHandles[currentCachedIndex++] = vulkanSet->setHandle[i];
}
vulkanSet->cachedData[i].resize(layout.bindings.size());
// Not really pretty, but this way the set knows which ones are valid
std::memset(vulkanSet->cachedData[i].data(), 0, sizeof(void*) * vulkanSet->cachedData[i].size());
}
}
void DescriptorAllocator::reset()
{
currentCachedIndex = 0;
} }
@@ -9,10 +9,7 @@ DECLARE_REF(Graphics);
class DescriptorLayout : public Gfx::DescriptorLayout class DescriptorLayout : public Gfx::DescriptorLayout
{ {
public: public:
DescriptorLayout(PGraphics graphics) DescriptorLayout(PGraphics graphics);
: graphics(graphics), layoutHandle(VK_NULL_HANDLE)
{
}
virtual ~DescriptorLayout(); virtual ~DescriptorLayout();
virtual void create(); virtual void create();
inline VkDescriptorSetLayout getHandle() const inline VkDescriptorSetLayout getHandle() const
@@ -21,9 +18,11 @@ public:
} }
private: private:
uint32 hash;
PGraphics graphics; PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings; Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle; VkDescriptorSetLayout layoutHandle;
friend class DescriptorAllocator;
}; };
DEFINE_REF(DescriptorLayout); DEFINE_REF(DescriptorLayout);
class PipelineLayout : public Gfx::PipelineLayout class PipelineLayout : public Gfx::PipelineLayout
@@ -59,6 +58,7 @@ public:
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout); DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
virtual ~DescriptorAllocator(); virtual ~DescriptorAllocator();
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet); virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
virtual void reset();
inline VkDescriptorPool getHandle() const inline VkDescriptorPool getHandle() const
{ {
@@ -71,7 +71,9 @@ public:
private: private:
PGraphics graphics; PGraphics graphics;
int maxSets = 512; const static int maxSets = 512;
VkDescriptorSet cachedHandles[maxSets];
uint32 currentCachedIndex;
VkDescriptorPool poolHandle; VkDescriptorPool poolHandle;
DescriptorLayout &layout; DescriptorLayout &layout;
}; };
@@ -81,10 +83,13 @@ class DescriptorSet : public Gfx::DescriptorSet
{ {
public: public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner) DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE) : graphics(graphics), owner(owner), currentFrameSet(0)
{ {
} }
virtual ~DescriptorSet(); virtual ~DescriptorSet();
virtual void beginFrame();
virtual void endFrame();
virtual void writeChanges();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer); virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer); virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState); virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
@@ -92,7 +97,7 @@ public:
virtual bool operator<(Gfx::PDescriptorSet other); virtual bool operator<(Gfx::PDescriptorSet other);
inline VkDescriptorSet getHandle() const inline VkDescriptorSet getHandle() const
{ {
return setHandle; return setHandle[currentFrameSet];
} }
virtual uint32 getSetIndex() const virtual uint32 getSetIndex() const
{ {
@@ -100,11 +105,15 @@ public:
} }
private: private:
virtual void writeChanges();
Array<VkDescriptorImageInfo> imageInfos; Array<VkDescriptorImageInfo> imageInfos;
Array<VkDescriptorBufferInfo> bufferInfos; Array<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors; Array<VkWriteDescriptorSet> writeDescriptors;
VkDescriptorSet setHandle; // contains the previously bound resources at every binding
// since the layout is fixed, trying to bind a texture to a buffer
// would not work anyways, so casts should be safe
Array<void*> cachedData[Gfx::numFramesBuffered];
VkDescriptorSet setHandle[Gfx::numFramesBuffered];
uint32 currentFrameSet;
PDescriptorAllocator owner; PDescriptorAllocator owner;
PGraphics graphics; PGraphics graphics;
friend class DescriptorAllocator; friend class DescriptorAllocator;
@@ -39,6 +39,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
renderPass->getRenderArea().extent.width, renderPass->getRenderArea().extent.width,
renderPass->getRenderArea().extent.height, renderPass->getRenderArea().extent.height,
1); 1);
VK_CHECK(vkCreateFramebuffer(graphics->getDevice(), &createInfo, nullptr, &handle)); VK_CHECK(vkCreateFramebuffer(graphics->getDevice(), &createInfo, nullptr, &handle));
boost::crc_32_type result; boost::crc_32_type result;
+17 -1
View File
@@ -124,6 +124,13 @@ Gfx::PRenderCommand Graphics::createRenderCommand()
cmdBuffer->begin(getGraphicsCommands()->getCommands()); cmdBuffer->begin(getGraphicsCommands()->getCommands());
return cmdBuffer; return cmdBuffer;
} }
Gfx::PVertexDeclaration Graphics::createVertexDeclaration(const Array<Gfx::VertexElement>& element)
{
PVertexDeclaration declaration = new VertexDeclaration(element);
return declaration;
}
Gfx::PVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo) Gfx::PVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
{ {
PVertexShader shader = new VertexShader(this); PVertexShader shader = new VertexShader(this);
@@ -159,6 +166,15 @@ Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCr
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
return pipeline; return pipeline;
} }
Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
{
PSamplerState sampler = new SamplerState(); // TODO: proper sampler creation
VkSamplerCreateInfo vkInfo =
init::SamplerCreateInfo();
VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler));
return sampler;
}
Gfx::PDescriptorLayout Graphics::createDescriptorLayout() Gfx::PDescriptorLayout Graphics::createDescriptorLayout()
{ {
PDescriptorLayout layout = new DescriptorLayout(this); PDescriptorLayout layout = new DescriptorLayout(this);
@@ -280,7 +296,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1); appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1);
appInfo.pEngineName = initInfo.engineName; appInfo.pEngineName = initInfo.engineName;
appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1); appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1);
appInfo.apiVersion = VK_API_VERSION_1_1; appInfo.apiVersion = VK_API_VERSION_1_2;
VkInstanceCreateInfo info = {}; VkInstanceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@@ -53,12 +53,14 @@ public:
virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override; virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override; virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
virtual Gfx::PRenderCommand createRenderCommand() override; virtual Gfx::PRenderCommand createRenderCommand() override;
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override;
virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override; virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
virtual Gfx::PDescriptorLayout createDescriptorLayout() override; virtual Gfx::PDescriptorLayout createDescriptorLayout() override;
virtual Gfx::PPipelineLayout createPipelineLayout() override; virtual Gfx::PPipelineLayout createPipelineLayout() override;
@@ -49,6 +49,14 @@ void QueueOwnedResourceDeletion::run()
} }
} }
void UniformBuffer::updateContents(const BulkResourceData &resourceData)
{
Gfx::UniformBuffer::updateContents(resourceData);
void* data = lock();
std::memcpy(data, resourceData.data, resourceData.size);
unlock();
}
Semaphore::Semaphore(PGraphics graphics) Semaphore::Semaphore(PGraphics graphics)
: graphics(graphics) : graphics(graphics)
{ {
@@ -121,3 +129,12 @@ void Fence::wait(uint32 timeout)
break; break;
} }
} }
VertexDeclaration::VertexDeclaration(const Array<Gfx::VertexElement>& elementList)
: elementList(elementList)
{
}
VertexDeclaration::~VertexDeclaration()
{
}
@@ -53,6 +53,17 @@ private:
}; };
DEFINE_REF(Fence); DEFINE_REF(Fence);
class VertexDeclaration : public Gfx::VertexDeclaration
{
public:
Array<Gfx::VertexElement> elementList;
VertexDeclaration(const Array<Gfx::VertexElement>& elementList);
virtual ~VertexDeclaration();
private:
};
DEFINE_REF(VertexDeclaration);
class QueueOwnedResourceDeletion class QueueOwnedResourceDeletion
{ {
public: public:
@@ -83,6 +94,11 @@ public:
{ {
return buffers[currentBuffer].buffer; return buffers[currentBuffer].buffer;
} }
uint32 getSize() const
{
return size;
}
VkDeviceSize getOffset() const;
void advanceBuffer() void advanceBuffer()
{ {
currentBuffer = (currentBuffer + 1) % numBuffers; currentBuffer = (currentBuffer + 1) % numBuffers;
@@ -116,7 +132,7 @@ class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer
public: public:
UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData); UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData);
virtual ~UniformBuffer(); virtual ~UniformBuffer();
virtual void updateContents(const BulkResourceData &resourceData);
protected: protected:
// Inherited via Vulkan::Buffer // Inherited via Vulkan::Buffer
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
@@ -232,23 +248,16 @@ private:
friend class TextureBase; friend class TextureBase;
friend class Texture2D; friend class Texture2D;
}; };
DEFINE_REF(TextureHandle);
DECLARE_REF(TextureBase);
class TextureBase class TextureBase
{ {
public: public:
static PTextureHandle cast(Gfx::PTexture texture) static TextureHandle* cast(Gfx::PTexture texture);
{
PTextureBase base = texture.cast<TextureBase>();
return base->textureHandle;
}
void changeLayout(VkImageLayout newLayout); void changeLayout(VkImageLayout newLayout);
protected: protected:
PTextureHandle textureHandle; TextureHandle* textureHandle;
}; };
DEFINE_REF(TextureBase);
class Texture2D : public Gfx::Texture2D, public TextureBase class Texture2D : public Gfx::Texture2D, public TextureBase
{ {
@@ -290,7 +299,7 @@ protected:
}; };
DEFINE_REF(Texture2D); DEFINE_REF(Texture2D);
class SamplerState class SamplerState : public Gfx::SamplerState
{ {
public: public:
VkSampler sampler; VkSampler sampler;
@@ -343,9 +352,9 @@ public:
virtual ~Viewport(); virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY); virtual void resize(uint32 newX, uint32 newY);
virtual void move(uint32 newOffsetX, uint32 newOffsetY); virtual void move(uint32 newOffsetX, uint32 newOffsetY);
VkViewport getHandle() const { return handle; }
protected:
private: private:
VkViewport handle;
PGraphics graphics; PGraphics graphics;
friend class Graphics; friend class Graphics;
}; };
@@ -768,7 +768,14 @@ VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStag
#pragma warning(disable : 4100) #pragma warning(disable : 4100)
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userDataManager) VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userDataManager)
{ {
std::cerr << layerPrefix << ": " << msg << std::endl; if(flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
{
std::cerr << layerPrefix << ": " << msg << std::endl;
}
else
{
std::cerr << layerPrefix << ": " << msg << std::endl;
}
return VK_FALSE; return VK_FALSE;
} }
#pragma warning(default : 4100) #pragma warning(default : 4100)
@@ -54,24 +54,17 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
createInfo.flags = 0; createInfo.flags = 0;
createInfo.stageCount = 0; createInfo.stageCount = 0;
PPipelineLayout layout = graphics->createPipelineLayout();
VkPipelineTessellationStateCreateInfo tessInfo; VkPipelineTessellationStateCreateInfo tessInfo;
VkPipelineShaderStageCreateInfo stageInfos[5]; VkPipelineShaderStageCreateInfo stageInfos[5];
std::memset(stageInfos, 0, sizeof(stageInfos)); std::memset(stageInfos, 0, sizeof(stageInfos));
if(gfxInfo.vertexShader != nullptr)
{ PVertexShader vertexShader = gfxInfo.vertexShader.cast<VertexShader>();
PVertexShader shader = gfxInfo.vertexShader.cast<VertexShader>(); VkPipelineShaderStageCreateInfo& vertInfo = stageInfos[createInfo.stageCount++];
VkPipelineShaderStageCreateInfo& vertInfo = stageInfos[createInfo.stageCount++]; vertInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vertInfo.module = vertexShader->getModuleHandle();
vertInfo.module = shader->getModuleHandle(); vertInfo.pName = vertexShader->getEntryPointName();
vertInfo.pName = shader->getEntryPointName();
for(auto descriptor : shader->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
}
if(gfxInfo.controlShader != nullptr) if(gfxInfo.controlShader != nullptr)
{ {
assert(gfxInfo.evalShader != nullptr); assert(gfxInfo.evalShader != nullptr);
@@ -94,15 +87,6 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
tessInfo.pNext = 0; tessInfo.pNext = 0;
tessInfo.flags = 0; tessInfo.flags = 0;
tessInfo.patchControlPoints = control->getNumPatches(); tessInfo.patchControlPoints = control->getNumPatches();
for(auto descriptor : eval->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
for(auto descriptor : control->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
} }
if(gfxInfo.geometryShader != nullptr) if(gfxInfo.geometryShader != nullptr)
{ {
@@ -113,11 +97,6 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT;
geometryInfo.module = geometry->getModuleHandle(); geometryInfo.module = geometry->getModuleHandle();
geometryInfo.pName = geometry->getEntryPointName(); geometryInfo.pName = geometry->getEntryPointName();
for(auto descriptor : geometry->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
} }
if(gfxInfo.fragmentShader != nullptr) if(gfxInfo.fragmentShader != nullptr)
{ {
@@ -128,40 +107,81 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragmentInfo.module = fragment->getModuleHandle(); fragmentInfo.module = fragment->getModuleHandle();
fragmentInfo.pName = fragment->getEntryPointName(); fragmentInfo.pName = fragment->getEntryPointName();
for(auto descriptor : fragment->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
} }
layout->create();
VkPipelineVertexInputStateCreateInfo vertexInput = VkPipelineVertexInputStateCreateInfo vertexInput =
init::PipelineVertexInputStateCreateInfo(); init::PipelineVertexInputStateCreateInfo();
Gfx::PVertexDeclaration vertexDecl = gfxInfo.vertexDeclaration; PVertexDeclaration vertexDecl = gfxInfo.vertexDeclaration;
auto vertexStreams = vertexDecl->getVertexStreams(); auto vertexStreams = vertexDecl->elementList;
Array<VkVertexInputBindingDescription> bindingDesc(vertexStreams.size());
Array<VkVertexInputAttributeDescription> attribDesc;
uint32 bindingNum = 0; uint32 bindingNum = 0;
for(auto vertexBinding : vertexStreams) uint32 bindingsMask = 0;
uint32 attributesNum = 0;
Array<VkVertexInputBindingDescription> bindings;
Array<VkVertexInputAttributeDescription> attributes;
Map<uint32, uint32> bindingToStream;
Map<uint32, uint32> streamToBinding;
std::memset(bindings.data(), 0, sizeof(VkVertexInputBindingDescription) * 16); // if default allocation size ever changes, this breaks
std::memset(attributes.data(), 0, sizeof(VkVertexInputAttributeDescription) * 16);
for(auto& element : vertexStreams)
{ {
uint32 stride = 0; //if((1 << element.attributeIndex) & vertexAttributeMask) // TODO: attribute mask
for(auto vertexAttrib : vertexBinding.getVertexDescriptions())
{ {
auto attrib = attribDesc.add(); if(element.streamIndex >= bindings.size())
attrib.binding = bindingNum; {
attrib.format = cast(vertexAttrib.vertexFormat); bindings.resize(element.streamIndex + 1); // This should not cause any actual allocations
attrib.location = vertexAttrib.location; }
attrib.offset = vertexAttrib.offset; VkVertexInputBindingDescription currBinding = bindings[element.streamIndex];
if((bindingsMask & (1 << element.streamIndex)) != 0)
{
assert(currBinding.binding == element.streamIndex);
assert(currBinding.inputRate == element.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
assert(currBinding.stride == element.stride);
}
else
{
assert(currBinding.binding == 0 && currBinding.inputRate == 0 && currBinding.stride == 0);
currBinding.binding = element.streamIndex;
currBinding.inputRate = element.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
currBinding.stride = element.stride;
bindingsMask |= 1 << element.streamIndex;
}
} }
bindingDesc[bindingNum].binding = bindingNum; }
bindingDesc[bindingNum].stride = stride;
bindingDesc[bindingNum].inputRate = vertexBinding.isInstanced() ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; for(uint32 i = 0; i < bindings.size(); ++i)
{
if(!((1 << i) & bindingsMask))
{
continue;
}
bindingToStream[bindingNum] = i;
streamToBinding[i] = bindingNum;
VkVertexInputBindingDescription& currBinding = bindings[bindingNum];
currBinding = bindings[i];
currBinding.binding = bindingNum;
bindingNum++; bindingNum++;
} }
vertexInput.pVertexBindingDescriptions = bindingDesc.data();
vertexInput.vertexBindingDescriptionCount = bindingDesc.size(); for(auto& element : vertexStreams)
vertexInput.pVertexAttributeDescriptions = attribDesc.data(); {
vertexInput.vertexAttributeDescriptionCount = attribDesc.size(); //TODO: vertex attribute mask
if(attributesNum >= attributes.size())
{
attributes.resize(attributesNum + 1); // This should not cause any actual allocations
}
VkVertexInputAttributeDescription& currAttribute = attributes[attributesNum++];
currAttribute.location = element.attributeIndex;
currAttribute.binding = streamToBinding[element.streamIndex];
currAttribute.format = cast(element.vertexFormat);
currAttribute.offset = element.offset;
}
vertexInput.pVertexBindingDescriptions = bindings.data();
vertexInput.vertexBindingDescriptionCount = bindings.size();
vertexInput.pVertexAttributeDescriptions = attributes.data();
vertexInput.vertexAttributeDescriptionCount = attributes.size();
VkPipelineInputAssemblyStateCreateInfo assemblyInfo = VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
init::PipelineInputAssemblyStateCreateInfo( init::PipelineInputAssemblyStateCreateInfo(
@@ -242,6 +262,8 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
0 0
); );
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
createInfo.pStages = stageInfos; createInfo.pStages = stageInfos;
createInfo.pVertexInputState = &vertexInput; createInfo.pVertexInputState = &vertexInput;
createInfo.pInputAssemblyState = &assemblyInfo; createInfo.pInputAssemblyState = &assemblyInfo;
@@ -260,7 +282,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
auto beginTime = std::chrono::high_resolution_clock::now(); auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle)); VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
auto endTime = std::chrono::high_resolution_clock::now(); auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - beginTime).count(); int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Gfx creation time: " << delta << std::endl; std::cout << "Gfx creation time: " << delta << std::endl;
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo); PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo);
@@ -11,6 +11,11 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout)
: Gfx::RenderPass(layout) : Gfx::RenderPass(layout)
, graphics(graphics) , graphics(graphics)
{ {
renderArea.extent.width = layout->width;
renderArea.extent.height = layout->height;
renderArea.offset.x = 0;
renderArea.offset.y = 0;
subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
Array<VkAttachmentDescription> attachments; Array<VkAttachmentDescription> attachments;
Array<VkAttachmentReference> inputRefs; Array<VkAttachmentReference> inputRefs;
Array<VkAttachmentReference> colorRefs; Array<VkAttachmentReference> colorRefs;
+38 -16
View File
@@ -2,6 +2,8 @@
#include "VulkanGraphics.h" #include "VulkanGraphics.h"
#include "VulkanDescriptorSets.h" #include "VulkanDescriptorSets.h"
#include "slang.h" #include "slang.h"
#include "spirv_cross/spirv_reflect.hpp"
#include <fstream>
using namespace slang; using namespace slang;
using namespace Seele; using namespace Seele;
@@ -46,8 +48,42 @@ static SlangStage getStageFromShaderType(ShaderType type)
} }
} }
/*static void createMixedDescriptorLayout(PDescriptorLayout layout, VariableLayoutReflection* parameter)
{
//std::cout << "category: " << (uint32)parameter->ge << std::endl;
uint32 categoryCount = parameter->getCategoryCount();
std::cout << "Mixed parameter " << parameter->getName() << " with categories: " << std::endl;
for(uint32 i = 0; i < categoryCount; ++i)
{
ParameterCategory category = parameter->getCategoryByIndex(i);
uint32 offset = parameter->getOffset(category);
uint32 space = parameter->getBindingSpace(category);
std::cout << "category: " << category << std::endl << " offset: " << offset << std::endl << " space: " << space << std::endl;
}
}
static Gfx::SeDescriptorType getTypeFromKind(slang::TypeReflection::Kind kind)
{
switch (kind)
{
case slang::TypeReflection::Kind::ConstantBuffer:
case slang::TypeReflection::Kind::GenericTypeParameter:
case slang::TypeReflection::Kind::ParameterBlock:
return Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case slang::TypeReflection::Kind::ShaderStorageBuffer:
return Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case slang::TypeReflection::Kind::TextureBuffer:
return Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case slang::TypeReflection::Kind::SamplerState:
return Gfx::SE_DESCRIPTOR_TYPE_SAMPLER;
default:
return Gfx::SE_DESCRIPTOR_TYPE_MAX_ENUM;
}
}*/
void Shader::create(const ShaderCreateInfo& createInfo) void Shader::create(const ShaderCreateInfo& createInfo)
{ {
std::cout << "--------------------------------" << std::endl;
entryPointName = createInfo.entryPoint; entryPointName = createInfo.entryPoint;
static SlangSession* session = spCreateSession(NULL); static SlangSession* session = spCreateSession(NULL);
@@ -82,28 +118,14 @@ void Shader::create(const ShaderCreateInfo& createInfo)
std::cout << diagnostics << std::endl; std::cout << diagnostics << std::endl;
} }
ShaderReflection* reflection = slang::ShaderReflection::get(request);
uint32 parameterCount = reflection->getParameterCount();
for(uint32 i = 0; i < parameterCount; ++i)
{
VariableLayoutReflection* parameter =
reflection->getParameterByIndex(i);
uint32 descriptorIndex = parameter->getBindingSpace();
uint32 descriptorBinding = parameter->getBindingIndex();
PDescriptorLayout& layout = descriptorSets[descriptorIndex];
std::cout << parameter->getTypeLayout()->getName() << std::endl;
//layout->addDescriptorBinding(descriptorBinding, parame)
}
size_t dataSize = 0; size_t dataSize = 0;
const void* data = spGetEntryPointCode(request, entryPointIndex, &dataSize); const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
VkShaderModuleCreateInfo moduleInfo; VkShaderModuleCreateInfo moduleInfo;
moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleInfo.pNext = nullptr; moduleInfo.pNext = nullptr;
moduleInfo.flags = 0; moduleInfo.flags = 0;
moduleInfo.codeSize = dataSize; moduleInfo.codeSize = dataSize;
moduleInfo.pCode = static_cast<const uint32*>(data); moduleInfo.pCode = data;
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module)); VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
} }
+2 -1
View File
@@ -22,7 +22,8 @@ public:
} }
const char* getEntryPointName() const const char* getEntryPointName() const
{ {
return entryPointName.c_str(); //SLang renames all entry points to main, so we dont need that
return "main";//entryPointName.c_str();
} }
Map<uint32, PDescriptorLayout> getDescriptorLayouts(); Map<uint32, PDescriptorLayout> getDescriptorLayouts();
private: private:
@@ -162,6 +162,16 @@ TextureHandle::~TextureHandle()
deletionQueue.addPendingDelete(cmdBuffer, [device, img]() { vkDestroyImage(device, img, nullptr); }); deletionQueue.addPendingDelete(cmdBuffer, [device, img]() { vkDestroyImage(device, img, nullptr); });
} }
TextureHandle* TextureBase::cast(Gfx::PTexture texture)
{
if(texture->getTexture2D() != nullptr)
{
PTexture2D texture2D = texture.cast<Texture2D>();
return texture2D->textureHandle;
}
return nullptr;
}
void TextureHandle::changeLayout(VkImageLayout newLayout) void TextureHandle::changeLayout(VkImageLayout newLayout)
{ {
VkImageMemoryBarrier barrier = VkImageMemoryBarrier barrier =
@@ -258,6 +258,9 @@ void Window::choosePresentMode(const Array<VkPresentModeKHR> &modes)
Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &viewportInfo) Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &viewportInfo)
: Gfx::Viewport(owner, viewportInfo), graphics(graphics) : Gfx::Viewport(owner, viewportInfo), graphics(graphics)
{ {
handle = init::Viewport(static_cast<float>(viewportInfo.sizeX), static_cast<float>(viewportInfo.sizeY), 0.f, 1.f);
handle.x = static_cast<float>(viewportInfo.offsetX);
handle.y = static_cast<float>(viewportInfo.offsetY);
} }
Viewport::~Viewport() Viewport::~Viewport()
+2 -1
View File
@@ -8,4 +8,5 @@ target_sources(SeeleEngine
MaterialAsset.cpp MaterialAsset.cpp
MaterialInstance.h MaterialInstance.h
MaterialInstance.cpp MaterialInstance.cpp
ShaderExpression.h) ShaderExpression.h
ShaderExpression.cpp)
+41 -15
View File
@@ -2,6 +2,7 @@
#include "Asset/AssetRegistry.h" #include "Asset/AssetRegistry.h"
#include "Graphics/VertexShaderInput.h" #include "Graphics/VertexShaderInput.h"
#include "BRDF.h" #include "BRDF.h"
#include "Graphics/WindowManager.h"
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
@@ -32,21 +33,23 @@ Material::~Material()
void Material::save() void Material::save()
{ {
} }
void Material::load() void Material::load()
{ {
} }
void Material::compile() void Material::compile()
{ {
layout = WindowManager::getGraphics()->createDescriptorLayout();
auto& stream = getReadStream(); auto& stream = getReadStream();
json j; json j;
stream >> j; stream >> j;
materialName = j["name"].get<std::string>(); materialName = j["name"].get<std::string>();
std::cout << "Compiling material " << materialName << std::endl;
//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::ofstream codeStream("./shaders/generated/"+materialName+".slang");
std::string profile = j["profile"].get<std::string>(); std::string profile = j["profile"].get<std::string>();
@@ -57,45 +60,55 @@ void Material::compile()
codeStream << "import MaterialParameter;" << std::endl; codeStream << "import MaterialParameter;" << std::endl;
codeStream << "struct " << materialName << ": IMaterial {" << std::endl; codeStream << "struct " << materialName << ": IMaterial {" << std::endl;
uint32 uniformBufferOffset = 0;
uint32 bindingCounter = 1; // Uniform buffers are always binding 0
layout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
for(auto param : j["params"].items()) for(auto param : j["params"].items())
{ {
std::string type = param.value()["type"].get<std::string>(); std::string type = param.value()["type"].get<std::string>();
auto default = param.value().find("default"); auto default = param.value().find("default");
if(type.compare("float") == 0) if(type.compare("float") == 0)
{ {
PFloatParameter p = new FloatParameter(); PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
p->name = param.key(); codeStream << "layout(offset = " << uniformBufferOffset << ")";
uniformBufferOffset += 4;
if(default != param.value().end()) if(default != param.value().end())
{ {
p->defaultValue = std::stof(default.value().get<std::string>()); p->data = std::stof(default.value().get<std::string>());
} }
parameters.add(p); parameters.add(p);
} }
else if(type.compare("float3") == 0) else if(type.compare("float3") == 0)
{ {
PVectorParameter p = new VectorParameter(); PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0);
p->name = param.key(); codeStream << "layout(offset = " << uniformBufferOffset << ")";
uniformBufferOffset += 12;
if(default != param.value().end()) if(default != param.value().end())
{ {
p->defaultValue = parseVector(default.value().get<std::string>().c_str()); p->data = parseVector(default.value().get<std::string>().c_str());
} }
parameters.add(p); parameters.add(p);
} }
else if(type.compare("Texture2D") == 0) else if(type.compare("Texture2D") == 0)
{ {
PTextureParameter p = new TextureParameter(); PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
p->name = param.key(); layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
if(default != param.value().end()) if(default != param.value().end())
{ {
p->data = AssetRegistry::findTexture(default.value().get<std::string>());
}
else
{
p->data = AssetRegistry::findTexture(""); // this will return placeholder texture
} }
parameters.add(p); parameters.add(p);
} }
else if(type.compare("SamplerState") == 0) else if(type.compare("SamplerState") == 0)
{ {
PSamplerParameter p = new SamplerParameter(); PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
p->name = param.key(); layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
SamplerCreateInfo createInfo;
p->data = WindowManager::getGraphics()->createSamplerState(createInfo);
parameters.add(p); parameters.add(p);
} }
else else
@@ -104,6 +117,18 @@ void Material::compile()
} }
codeStream << type << " " << param.key() << ";\n"; codeStream << type << " " << param.key() << ";\n";
} }
uniformDataSize = uniformBufferOffset;
if(uniformDataSize != 0)
{
uniformData = new uint8[uniformDataSize];
BulkResourceData resourceData;
resourceData.data = uniformData;
resourceData.size = uniformDataSize;
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(resourceData);
}
layout->create();
descriptorSet = layout->allocatedDescriptorSet();
updateDescriptorData();
BRDF* brdf = BRDF::getBRDFByName(profile); BRDF* brdf = BRDF::getBRDFByName(profile);
brdf->generateMaterialCode(codeStream, j["code"]); brdf->generateMaterialCode(codeStream, j["code"]);
codeStream << "};"; codeStream << "};";
@@ -113,10 +138,11 @@ void Material::compile()
const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
{ {
Gfx::ShaderPermutation permutation; Gfx::ShaderPermutation permutation;
permutation.passType = renderPass;
std::string materialName = getFileName(); std::string materialName = getFileName();
std::string vertexInputName = vertexInput->getName(); std::string vertexInputName = vertexInput->getName();
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName)); std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.materialName, vertexInputName.c_str(), sizeof(permutation.materialName)); std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
return shaderMap.findShaders(Gfx::PermutationId(permutation)); return shaderMap.findShaders(Gfx::PermutationId(permutation));
} }
+5 -1
View File
@@ -14,7 +14,9 @@ public:
~Material(); ~Material();
virtual void save() override; virtual void save() override;
virtual void load() override; virtual void load() override;
virtual PMaterial getRenderMaterial() { return this; } 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 std::string& getName() {return materialName;}
const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const; const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const;
@@ -25,7 +27,9 @@ private:
static std::mutex shaderMapLock; static std::mutex shaderMapLock;
std::string materialName; std::string materialName;
Gfx::PDescriptorLayout layout;
friend class MaterialLoader; friend class MaterialLoader;
friend class MaterialInstance;
}; };
DEFINE_REF(Material); DEFINE_REF(Material);
} // namespace Seele } // namespace Seele
+33
View File
@@ -1,4 +1,5 @@
#include "MaterialAsset.h" #include "MaterialAsset.h"
#include "Graphics/WindowManager.h"
using namespace Seele; using namespace Seele;
@@ -19,3 +20,35 @@ MaterialAsset::MaterialAsset(const std::filesystem::path& fullPath)
MaterialAsset::~MaterialAsset() MaterialAsset::~MaterialAsset()
{ {
} }
void MaterialAsset::beginFrame()
{
descriptorSet->beginFrame();
}
void MaterialAsset::endFrame()
{
descriptorSet->endFrame();
}
void MaterialAsset::updateDescriptorData()
{
BulkResourceData uniformUpdate;
uniformUpdate.size = uniformDataSize;
uniformUpdate.data = uniformData;
for(auto param : parameters)
{
param->updateDescriptorSet(descriptorSet, uniformData);
}
if(uniformUpdate.size != 0)
{
uniformBuffer->updateContents(uniformUpdate);
descriptorSet->updateBuffer(0, uniformBuffer);
}
descriptorSet->writeChanges();
}
Gfx::PDescriptorSet MaterialAsset::getDescriptor() const
{
return descriptorSet;
}
+10 -1
View File
@@ -14,15 +14,24 @@ public:
MaterialAsset(const std::string &directory, const std::string &name); MaterialAsset(const std::string &directory, const std::string &name);
MaterialAsset(const std::filesystem::path &fullPath); MaterialAsset(const std::filesystem::path &fullPath);
~MaterialAsset(); ~MaterialAsset();
virtual void beginFrame();
virtual void endFrame();
virtual void save() = 0; virtual void save() = 0;
virtual void load() = 0; virtual void load() = 0;
virtual PMaterial getRenderMaterial() = 0; 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
void updateDescriptorData();
Gfx::PDescriptorSet getDescriptor() const;
protected: 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::PUniformBuffer uniformBuffer;
uint32 uniformDataSize;
uint8* uniformData;
}; };
DEFINE_REF(MaterialAsset); DEFINE_REF(MaterialAsset);
} // namespace Seele } // namespace Seele
+8 -12
View File
@@ -1,5 +1,6 @@
#include "MaterialInstance.h" #include "MaterialInstance.h"
#include "Material.h" #include "Material.h"
#include "Graphics/WindowManager.h"
using namespace Seele; using namespace Seele;
@@ -28,20 +29,15 @@ void MaterialInstance::save()
void MaterialInstance::load() void MaterialInstance::load()
{ {
baseMaterial = nullptr; // TODO: actually load the file
BulkResourceData resourceData;
resourceData.size = baseMaterial->uniformDataSize;
resourceData.data = nullptr;
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(resourceData);
descriptorSet = baseMaterial->layout->allocatedDescriptorSet();
} }
PMaterial MaterialInstance::getRenderMaterial() const Material* MaterialInstance::getRenderMaterial() const
{ {
return baseMaterial; return baseMaterial;
} }
PMaterial MaterialInstance::getBaseMaterial() const
{
return baseMaterial;
}
Gfx::PDescriptorSet MaterialInstance::getDescriptor()
{
return nullptr;
}
+2 -4
View File
@@ -14,11 +14,9 @@ public:
~MaterialInstance(); ~MaterialInstance();
virtual void save() override; virtual void save() override;
virtual void load() override; virtual void load() override;
virtual PMaterial getRenderMaterial(); virtual const Material* getRenderMaterial() const;
PMaterial getBaseMaterial() const;
Gfx::PDescriptorSet getDescriptor();
private: private:
PMaterial baseMaterial; Material* baseMaterial;
}; };
DEFINE_REF(MaterialInstance); DEFINE_REF(MaterialInstance);
} // namespace Seele } // namespace Seele
+24 -39
View File
@@ -14,65 +14,50 @@ struct ExpressionOutput
struct ShaderExpression struct ShaderExpression
{ {
}; };
DECLARE_NAME_REF(Gfx, DescriptorSet);
struct ShaderParameter : public ShaderExpression struct ShaderParameter : public ShaderExpression
{ {
std::string name; std::string name;
uint32 byteOffset;
uint32 binding;
ShaderParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~ShaderParameter();
// update a descriptorset, in case of a uniform buffer, copy the data to the dst + byteOffset
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) = 0;
}; };
DEFINE_REF(ShaderParameter); DEFINE_REF(ShaderParameter);
struct FloatParameter : public ShaderParameter struct FloatParameter : public ShaderParameter
{ {
float defaultValue; float data;
bool setParameter(const std::string& paramName, float newDefault) FloatParameter(std::string name, uint32 byteOffset, uint32 binding);
{ virtual ~FloatParameter();
if(name.compare(paramName) == 0) virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
{
defaultValue = newDefault;
return true;
}
return false;
}
}; };
DEFINE_REF(FloatParameter); DEFINE_REF(FloatParameter);
struct VectorParameter : public ShaderParameter struct VectorParameter : public ShaderParameter
{ {
Vector defaultValue; Vector data;
bool setParameter(const std::string& paramName, Vector newDefault) VectorParameter(std::string name, uint32 byteOffset, uint32 binding);
{ virtual ~VectorParameter();
if(name.compare(paramName) == 0) virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
{
defaultValue = newDefault;
return true;
}
return false;
}
}; };
DEFINE_REF(VectorParameter); DEFINE_REF(VectorParameter);
DECLARE_NAME_REF(Gfx, Texture2D); DECLARE_REF(TextureAsset);
struct TextureParameter : public ShaderParameter struct TextureParameter : public ShaderParameter
{ {
Gfx::PTexture2D defaultValue; PTextureAsset data;
bool setParameter(const std::string& paramName, Gfx::PTexture2D newDefault) TextureParameter(std::string name, uint32 byteOffset, uint32 binding);
{ virtual ~TextureParameter();
if(name.compare(paramName) == 0) virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
{
return true;
}
return false;
}
}; };
DEFINE_REF(TextureParameter); DEFINE_REF(TextureParameter);
DECLARE_NAME_REF(Gfx, SamplerState); DECLARE_NAME_REF(Gfx, SamplerState);
struct SamplerParameter : public ShaderParameter struct SamplerParameter : public ShaderParameter
{ {
Gfx::PSamplerState defaultValue; Gfx::PSamplerState data;
bool setParameter(const std::string& paramName, Gfx::PSamplerState newDefault) SamplerParameter(std::string name, uint32 byteOffset, uint32 binding);
{ virtual ~SamplerParameter();
if(name.compare(paramName) == 0) virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
{
return true;
}
return false;
}
}; };
DEFINE_REF(SamplerParameter); DEFINE_REF(SamplerParameter);
+1
View File
@@ -136,6 +136,7 @@ public:
{ {
object = (RefObject<T> *)registeredObj->value; object = (RefObject<T> *)registeredObj->value;
} }
object->addRef();
} }
explicit RefPtr(RefObject<T> *other) explicit RefPtr(RefObject<T> *other)
: object(other) : object(other)
+1 -1
View File
@@ -12,7 +12,7 @@ int main()
mainWindowInfo.height = 720; mainWindowInfo.height = 720;
mainWindowInfo.bFullscreen = false; mainWindowInfo.bFullscreen = false;
mainWindowInfo.numSamples = 1; mainWindowInfo.numSamples = 1;
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_R8G8B8_UNORM; mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
auto window = core.getWindowManager()->addWindow(mainWindowInfo); auto window = core.getWindowManager()->addWindow(mainWindowInfo);
ViewportCreateInfo sceneViewInfo; ViewportCreateInfo sceneViewInfo;
sceneViewInfo.sizeX = 1280; sceneViewInfo.sizeX = 1280;