Trying to fix invalid descriptorlayout
This commit is contained in:
Vendored
+9
-2
@@ -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
|
||||||
|
|||||||
Vendored
+3
-1
@@ -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
@@ -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
@@ -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",
|
||||||
|
|||||||
@@ -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
@@ -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}
|
||||||
|
|||||||
Vendored
+1
-1
Submodule external/slang updated: bc0d0f9e2a...83514bd251
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -44,4 +44,3 @@ struct MaterialFragmentParameter
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user