Refactoring graphics

This commit is contained in:
Dynamitos
2023-10-26 18:37:29 +02:00
parent 28e5c9ff01
commit 1ca861459c
113 changed files with 3131 additions and 3221 deletions
+21 -29
View File
@@ -8,36 +8,28 @@ struct ComputeShaderInput
uint3 dispatchThreadID : SV_DispatchThreadID; uint3 dispatchThreadID : SV_DispatchThreadID;
uint groupIndex : SV_GroupIndex; uint groupIndex : SV_GroupIndex;
}; };
layout(set = INDEX_VIEW_PARAMS, binding = 1) struct CullingParams
cbuffer DispatchParams
{ {
uint3 numThreadGroups; uint3 numThreadGroups;
uint pad0; uint pad0;
uint3 numThreads; uint3 numThreads;
uint pad1; uint pad1;
}
layout(set = INDEX_VIEW_PARAMS, binding = 2) Texture2D depthTextureVS;
Texture2D depthTextureVS;
layout(set = INDEX_VIEW_PARAMS, binding = 3) globallycoherent RWStructuredBuffer<uint> oLightIndexCounter;
globallycoherent RWShaderBuffer<uint> oLightIndexCounter; globallycoherent RWStructuredBuffer<uint> tLightIndexCounter;
layout(set = INDEX_VIEW_PARAMS, binding = 4)
globallycoherent RWShaderBuffer<uint> tLightIndexCounter;
layout(set = INDEX_VIEW_PARAMS, binding = 5) RWStructuredBuffer<uint> oLightIndexList;
RWShaderBuffer<uint> oLightIndexList; RWStructuredBuffer<uint> tLightIndexList;
layout(set = INDEX_VIEW_PARAMS, binding = 6)
RWShaderBuffer<uint> tLightIndexList;
layout(set = INDEX_VIEW_PARAMS, binding = 7) RWTexture2D<uint2> oLightGrid;
RWTexture2D<uint2> oLightGrid; RWTexture2D<uint2> tLightGrid;
layout(set = INDEX_VIEW_PARAMS, binding = 8)
RWTexture2D<uint2> tLightGrid;
layout(set = INDEX_VIEW_PARAMS, binding = 9) StructuredBuffer<Frustum> frustums;
ShaderBuffer<Frustum> frustums;
};
ParameterBlock<CullingParams> gCullingParams;
// Debug // Debug
//layout(set = INDEX_VIEW_PARAMS, binding = 10) //layout(set = INDEX_VIEW_PARAMS, binding = 10)
//Texture2D lightCountHeatMap; //Texture2D lightCountHeatMap;
@@ -83,7 +75,7 @@ void tAppendLight(uint lightIndex)
void cullLights(ComputeShaderInput in) void cullLights(ComputeShaderInput in)
{ {
int2 texCoord = int2(in.dispatchThreadID.xy); int2 texCoord = int2(in.dispatchThreadID.xy);
float fDepth = depthTextureVS.Load(int3(texCoord, 0)).r; float fDepth = gCullingParams.depthTextureVS.Load(int3(texCoord, 0)).r;
uint uDepth = asuint(fDepth); uint uDepth = asuint(fDepth);
if(in.groupIndex == 0) if(in.groupIndex == 0)
@@ -92,7 +84,7 @@ void cullLights(ComputeShaderInput in)
uMaxDepth = 0x0; uMaxDepth = 0x0;
oLightCount = 0; oLightCount = 0;
tLightCount = 0; tLightCount = 0;
groupFrustum = frustums[in.groupID.x + (in.groupID.y * numThreadGroups.x)]; groupFrustum = gCullingParams.frustums[in.groupID.x + (in.groupID.y * gCullingParams.numThreadGroups.x)];
} }
GroupMemoryBarrierWithGroupSync(); GroupMemoryBarrierWithGroupSync();
@@ -111,9 +103,9 @@ void cullLights(ComputeShaderInput in)
Plane minPlane = {float3(0, 0, -1), -minDepthVS}; Plane minPlane = {float3(0, 0, -1), -minDepthVS};
for ( uint i = in.groupIndex; i < numPointLights; i += BLOCK_SIZE * BLOCK_SIZE ) for ( uint i = in.groupIndex; i < gLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
{ {
PointLight light = pointLights[i]; PointLight light = gLightEnv.pointLights[i];
//TODO: why doesn't this check go through? //TODO: why doesn't this check go through?
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS)) //if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
{ {
@@ -129,23 +121,23 @@ void cullLights(ComputeShaderInput in)
if(in.groupIndex == 0) if(in.groupIndex == 0)
{ {
InterlockedAdd(oLightIndexCounter[0], oLightCount, oLightIndexStartOffset); InterlockedAdd(gCullingParams.oLightIndexCounter[0], oLightCount, oLightIndexStartOffset);
oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount); gCullingParams.oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount);
InterlockedAdd(tLightIndexCounter[0], tLightCount, tLightIndexStartOffset); InterlockedAdd(gCullingParams.tLightIndexCounter[0], tLightCount, tLightIndexStartOffset);
tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount); gCullingParams.tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount);
} }
GroupMemoryBarrierWithGroupSync(); GroupMemoryBarrierWithGroupSync();
for (uint j = in.groupIndex; j < oLightCount; j += BLOCK_SIZE * BLOCK_SIZE) for (uint j = in.groupIndex; j < oLightCount; j += BLOCK_SIZE * BLOCK_SIZE)
{ {
oLightIndexList[oLightIndexStartOffset + j] = oLightList[j]; gCullingParams.oLightIndexList[oLightIndexStartOffset + j] = oLightList[j];
} }
// For transparent geometry. // For transparent geometry.
for ( uint k = in.groupIndex; k < tLightCount; k += BLOCK_SIZE * BLOCK_SIZE ) for ( uint k = in.groupIndex; k < tLightCount; k += BLOCK_SIZE * BLOCK_SIZE )
{ {
tLightIndexList[tLightIndexStartOffset + k] = tLightList[k]; gCullingParams.tLightIndexList[tLightIndexStartOffset + k] = tLightList[k];
} }
+8 -8
View File
@@ -4,7 +4,7 @@ import Common;
interface ILightEnv interface ILightEnv
{ {
float3 illuminate<B:IBRDF>(MaterialFragmentParameter input, B brdf); float3 illuminate<B:IBRDF>(MaterialParameter input, B brdf);
}; };
struct DirectionalLight : ILightEnv struct DirectionalLight : ILightEnv
@@ -12,9 +12,9 @@ struct DirectionalLight : ILightEnv
float4 color; float4 color;
float4 direction; float4 direction;
float3 illuminate<B:IBRDF>(MaterialFragmentParameter input, B brdf) float3 illuminate<B:IBRDF>(MaterialParameter input, B brdf)
{ {
float3 lightDir_TS = input.transformWorldToTangent(normalize(direction.xyz)); float3 lightDir_TS = normalize(direction.xyz);
return brdf.evaluate(input.viewDir_TS, -lightDir_TS, color.xyz); return brdf.evaluate(input.viewDir_TS, -lightDir_TS, color.xyz);
} }
}; };
@@ -24,9 +24,9 @@ struct PointLight : ILightEnv
float4 position_WS; float4 position_WS;
float4 colorRange; float4 colorRange;
float3 illuminate<B:IBRDF>(MaterialFragmentParameter input, B brdf) float3 illuminate<B:IBRDF>(MaterialParameter input, B brdf)
{ {
float3 position_TS = input.transformWorldToTangent(position_WS.xyz); float3 position_TS = position_WS.xyz;
float3 lightDir_TS = position_TS - input.position_TS; float3 lightDir_TS = position_TS - input.position_TS;
float d = length(lightDir_TS); float d = length(lightDir_TS);
float illuminance = max(1 - d / colorRange.w, 0); float illuminance = max(1 - d / colorRange.w, 0);
@@ -48,7 +48,7 @@ struct PointLight : ILightEnv
} }
for(int i = 0; i < 4 && result; ++i) for(int i = 0; i < 4 && result; ++i)
{ {
if(insidePlane(frustum.planes[i])) if(insidePlane(frustum.sides[i]))
{ {
//result = false; //result = false;
} }
@@ -57,7 +57,7 @@ struct PointLight : ILightEnv
} }
float3 getViewPos() float3 getViewPos()
{ {
return mul(gViewParams.viewMatrix, position_WS).xyz; return mul(viewParams.viewMatrix, position_WS).xyz;
} }
}; };
@@ -65,7 +65,7 @@ struct LightEnv
{ {
StructuredBuffer<DirectionalLight> directionalLights; StructuredBuffer<DirectionalLight> directionalLights;
uint numDirectionalLights; uint numDirectionalLights;
StructureBuffer<PointLight> pointLights; StructuredBuffer<PointLight> pointLights;
uint numPointLights; uint numPointLights;
}; };
+2
View File
@@ -2,11 +2,13 @@ import VertexData;
struct MaterialParameter struct MaterialParameter
{ {
float3 position_TS;
float3 worldPosition; float3 worldPosition;
float2 texCoords; float2 texCoords;
float3 normal; float3 normal;
float3 tangent; float3 tangent;
float3 biTangent; float3 biTangent;
float3 viewDir_TS;
static MaterialParameter create(VertexAttributes attrib) static MaterialParameter create(VertexAttributes attrib)
{ {
+326 -292
View File
@@ -1,73 +1,114 @@
#version 450 #version 450
#extension GL_EXT_mesh_shader : require #extension GL_EXT_samplerless_texture_functions : require
#extension GL_EXT_shader_8bit_storage : require
#extension GL_EXT_shader_explicit_arithmetic_types : require
layout(row_major) uniform; layout(row_major) uniform;
layout(row_major) buffer; layout(row_major) buffer;
#line 1 0 #line 11 0
struct InstanceData_0 struct CullingParams_0
{ {
mat4x4 transformMatrix_0; uvec3 numThreadGroups_0;
uint pad0_0;
uvec3 numThreads_0;
uint pad1_0;
}; };
#line 45 1 #line 35 1
layout(std430, binding = 0, set = 2) readonly buffer StructuredBuffer_InstanceData_t_0 { layout(binding = 0, set = 1)
InstanceData_0 _data[]; layout(std140) uniform _S1
} scene_instances_0;
#line 1 2
struct MeshletDescription_0
{ {
uint vertexCount_0; uvec3 numThreadGroups_0;
uint primitiveCount_0; uint pad0_0;
uint vertexOffset_0; uvec3 numThreads_0;
uint primitiveOffset_0; uint pad1_0;
}; }gCullingParams_0;
#line 2113 2
layout(binding = 1, set = 1)
uniform texture2D gCullingParams_depthTextureVS_0;
#line 46 1 #line 11 0
layout(std430, binding = 0, set = 1) readonly buffer StructuredBuffer_MeshletDescription_t_0 { layout(std430, binding = 2, set = 1) buffer StructuredBuffer_uint_t_0 {
MeshletDescription_0 _data[];
} meshlets_meshletInfos_0;
#line 9 2
layout(std430, binding = 1, set = 1) readonly buffer StructuredBuffer_uint8_t_0 {
uint8_t _data[];
} meshlets_primitiveIndices_0;
#line 9
layout(std430, binding = 2, set = 1) readonly buffer StructuredBuffer_uint_t_0 {
uint _data[]; uint _data[];
} meshlets_vertexIndices_0; } gCullingParams_oLightIndexCounter_0;
#line 35 3 #line 11
layout(std430, binding = 0, set = 3) readonly buffer StructuredBuffer_float3_t_0 { layout(std430, binding = 3, set = 1) buffer StructuredBuffer_uint_t_1 {
vec3 _data[]; uint _data[];
} vertexData_positions_0; } gCullingParams_tLightIndexCounter_0;
#line 35 #line 11
layout(std430, binding = 1, set = 3) readonly buffer StructuredBuffer_float2_t_0 { layout(std430, binding = 4, set = 1) buffer StructuredBuffer_uint_t_2 {
vec2 _data[]; uint _data[];
} vertexData_texCoords_0; } gCullingParams_oLightIndexList_0;
#line 35 #line 11
layout(std430, binding = 2, set = 3) readonly buffer StructuredBuffer_float3_t_1 { layout(std430, binding = 5, set = 1) buffer StructuredBuffer_uint_t_3 {
vec3 _data[]; uint _data[];
} vertexData_normals_0; } gCullingParams_tLightIndexList_0;
#line 35 #line 1572 2
layout(std430, binding = 3, set = 3) readonly buffer StructuredBuffer_float3_t_2 { layout(rg32ui)
vec3 _data[]; layout(binding = 6, set = 1)
} vertexData_tangents_0; uniform uimage2D gCullingParams_oLightGrid_0;
#line 35
layout(std430, binding = 4, set = 3) readonly buffer StructuredBuffer_float3_t_3 {
vec3 _data[];
} vertexData_biTangents_0;
#line 5 4 #line 1572
layout(rg32ui)
layout(binding = 7, set = 1)
uniform uimage2D gCullingParams_tLightGrid_0;
#line 26 1
struct Plane_0
{
vec3 n_0;
float d_0;
};
struct Frustum_0
{
Plane_0 sides_0[4];
Plane_0 basePlane_0;
};
#line 11 0
layout(std430, binding = 8, set = 1) readonly buffer StructuredBuffer_Frustum_t_0 {
Frustum_0 _data[];
} gCullingParams_frustums_0;
#line 64 3
struct LightEnv_0
{
uint numDirectionalLights_0;
uint numPointLights_0;
};
#line 25
layout(binding = 0, set = 2)
layout(std140) uniform _S2
{
uint numDirectionalLights_0;
uint numPointLights_0;
}gLightEnv_0;
#line 22
struct PointLight_0
{
vec4 position_WS_0;
vec4 colorRange_0;
};
#line 64
layout(std430, binding = 2, set = 2) readonly buffer StructuredBuffer_PointLight_t_0 {
PointLight_0 _data[];
} gLightEnv_pointLights_0;
#line 5 1
struct ViewParameter_0 struct ViewParameter_0
{ {
mat4x4 viewMatrix_0; mat4x4 viewMatrix_0;
@@ -77,7 +118,7 @@ struct ViewParameter_0
}; };
layout(binding = 0) layout(binding = 0)
layout(std140) uniform _S1 layout(std140) uniform _S3
{ {
mat4x4 viewMatrix_0; mat4x4 viewMatrix_0;
mat4x4 projectionMatrix_0; mat4x4 projectionMatrix_0;
@@ -85,264 +126,257 @@ layout(std140) uniform _S1
vec2 screenDimensions_0; vec2 screenDimensions_0;
}viewParams_0; }viewParams_0;
#line 1267 5 #line 39 0
out gl_MeshPerVertexEXT shared uint uMinDepth_0;
{
vec4 gl_Position;
} gl_MeshVerticesEXT[64];
#line 24 1 #line 40
shared uint gs_numVertices_0; shared uint uMaxDepth_0;
#line 5 3
struct StaticMeshVertexAttributes_0 shared uint oLightCount_0;
{
vec4 clipPosition_0;
vec3 worldPosition_0;
vec2 texCoords_0;
vec3 normal_0;
vec3 tangent_0;
vec3 biTangent_0;
};
#line 22 1
shared StaticMeshVertexAttributes_0 gs_vertices_0[64]; shared uint tLightCount_0;
shared uint gs_numPrimitives_0; #line 42
shared Frustum_0 groupFrustum_0;
#line 23 #line 50
shared uvec3 gs_indices_0[126]; shared uint tLightList_0[1024];
#line 7910 6
layout(location = 0)
out vec3 _S2[64];
#line 7910
layout(location = 1)
out vec2 _S3[64];
#line 7910
layout(location = 2)
out vec3 _S4[64];
#line 7910
layout(location = 3)
out vec3 _S5[64];
#line 7910
layout(location = 4)
out vec3 _S6[64];
#line 7910
out uvec3 gl_PrimitiveTriangleIndicesEXT[126];
#line 900 7
StaticMeshVertexAttributes_0 StaticMeshVertexData_getAttributes_0(uint _S7, InstanceData_0 _S8)
{
#line 41 3
vec4 worldPos_0 = (((vec4(vertexData_positions_0._data[_S7], 1.0)) * (_S8.transformMatrix_0)));
#line 39
StaticMeshVertexAttributes_0 attr_0;
#line 44
attr_0.clipPosition_0 = ((((((worldPos_0) * (viewParams_0.viewMatrix_0)))) * (viewParams_0.projectionMatrix_0)));
attr_0.worldPosition_0 = worldPos_0.xyz;
attr_0.texCoords_0 = vertexData_texCoords_0._data[_S7];
attr_0.normal_0 = vertexData_normals_0._data[_S7];
attr_0.tangent_0 = vertexData_tangents_0._data[_S7];
attr_0.biTangent_0 = vertexData_biTangents_0._data[_S7];
return attr_0;
}
#line 39 1
layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
layout(max_vertices = 64) out;
layout(max_primitives = 126) out;
layout(triangles) out;
void main()
{
InstanceData_0 _S9 = scene_instances_0._data[gl_LocalInvocationIndex];
MeshletDescription_0 m_0 = meshlets_meshletInfos_0._data[gl_WorkGroupID.x];
#line 51
uint _S10 = m_0.vertexCount_0 - 1U;
#line 63 #line 63
uint _S11 = m_0.primitiveCount_0 - 1U; void tAppendLight_0(uint lightIndex_0)
{
#line 82 uint index_0;
uint v_0 = min(gl_LocalInvocationIndex, _S10); ((index_0) = atomicAdd((tLightCount_0), (1U)));
if(index_0 < 1024U)
uint v_1 = gl_LocalInvocationIndex + 32U;
uint v_2 = min(v_1, _S10);
#line 92
uint p_0 = min(gl_LocalInvocationIndex, _S11);
#line 98
uint p_1 = min(v_1, _S11);
#line 104
uint p_2 = min(gl_LocalInvocationIndex + 64U, _S11);
#line 110
uint p_3 = min(gl_LocalInvocationIndex + 96U, _S11);
#line 110
uint loop_0 = 0U;
#line 110
for(;;)
{ {
tLightList_0[index_0] = lightIndex_0;
#line 51 #line 67
uint v_3 = min(gl_LocalInvocationIndex + loop_0 * 32U, _S10);
atomicMax((gs_numVertices_0), (v_3 + 1U));
gs_vertices_0[v_3] = StaticMeshVertexData_getAttributes_0(uint(int(meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + v_3])), _S9);
#line 48
uint loop_1 = loop_0 + 1U;
#line 48
if(loop_1 < 2U)
{
}
else
{
#line 48
break;
} }
#line 48
loop_0 = loop_1;
#line 48
}
#line 48
loop_0 = 0U;
#line 48
for(;;)
{
#line 63
uint p_4 = min(gl_LocalInvocationIndex + loop_0 * 32U, _S11);
atomicMax((gs_numPrimitives_0), (p_4 + 1U));
uint _S12 = p_4 * 3U;
#line 66
uint _S13 = m_0.primitiveOffset_0 + _S12;
uint idx1_0 = meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13 + 1U])];
uint idx2_0 = meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13 + 2U])];
gs_indices_0[_S12] = uvec3(meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13])]);
gs_indices_0[_S12 + 1U] = uvec3(idx1_0);
gs_indices_0[_S12 + 2U] = uvec3(idx2_0);
#line 60
uint loop_2 = loop_0 + 1U;
#line 60
if(loop_2 < 4U)
{
}
else
{
#line 60
break;
}
#line 60
loop_0 = loop_2;
#line 60
}
#line 77
barrier();
SetMeshOutputsEXT(gs_numVertices_0, gs_numPrimitives_0);
barrier();
StaticMeshVertexAttributes_0 _S14 = gs_vertices_0[v_0];
#line 83
gl_MeshVerticesEXT[v_0].gl_Position = gs_vertices_0[v_0].clipPosition_0;
#line 83
_S2[v_0] = _S14.worldPosition_0;
#line 83
_S3[v_0] = _S14.texCoords_0;
#line 83
_S4[v_0] = _S14.normal_0;
#line 83
_S5[v_0] = _S14.tangent_0;
#line 83
_S6[v_0] = _S14.biTangent_0;
#line 88
StaticMeshVertexAttributes_0 _S15 = gs_vertices_0[v_2];
#line 88
gl_MeshVerticesEXT[v_2].gl_Position = gs_vertices_0[v_2].clipPosition_0;
#line 88
_S2[v_2] = _S15.worldPosition_0;
#line 88
_S3[v_2] = _S15.texCoords_0;
#line 88
_S4[v_2] = _S15.normal_0;
#line 88
_S5[v_2] = _S15.tangent_0;
#line 88
_S6[v_2] = _S15.biTangent_0;
#line 93
gl_PrimitiveTriangleIndicesEXT[p_0] = gs_indices_0[p_0];
#line 99
gl_PrimitiveTriangleIndicesEXT[p_1] = gs_indices_0[p_1];
#line 105
gl_PrimitiveTriangleIndicesEXT[p_2] = gs_indices_0[p_2];
#line 111
gl_PrimitiveTriangleIndicesEXT[p_3] = gs_indices_0[p_3];
return; return;
} }
#line 58 3
vec3 PointLight_getViewPos_0(PointLight_0 this_0)
{
return (((this_0.position_WS_0) * (viewParams_0.viewMatrix_0))).xyz;
}
#line 36
bool PointLight_insidePlane_0(PointLight_0 this_1, Plane_0 plane_0)
{
return dot(plane_0.n_0, PointLight_getViewPos_0(this_1).xyz) - plane_0.d_0 < - this_1.colorRange_0.w;
}
#line 46 0
shared uint oLightList_0[1024];
#line 53
void oAppendLight_0(uint lightIndex_1)
{
uint index_1;
((index_1) = atomicAdd((oLightCount_0), (1U)));
if(index_1 < 1024U)
{
oLightList_0[index_1] = lightIndex_1;
#line 57
}
return;
}
#line 45
shared uint oLightIndexStartOffset_0;
shared uint tLightIndexStartOffset_0;
#line 75
layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
void main()
{
ivec3 _S4 = ivec3(ivec2(gl_GlobalInvocationID.xy), 0);
uint uDepth_0 = floatBitsToUint((texelFetch((gCullingParams_depthTextureVS_0), ((_S4)).xy, ((_S4)).z)).x);
bool _S5 = gl_LocalInvocationIndex == 0U;
#line 81
if(_S5)
{
uMinDepth_0 = 4294967295U;
uMaxDepth_0 = 0U;
oLightCount_0 = 0U;
tLightCount_0 = 0U;
groupFrustum_0 = gCullingParams_frustums_0._data[gl_WorkGroupID.x + gl_WorkGroupID.y * gCullingParams_0.numThreadGroups_0.x];
#line 81
}
#line 90
barrier();
atomicMin((uMinDepth_0), (uDepth_0));
atomicMax((uMaxDepth_0), (uDepth_0));
barrier();
#line 104
Plane_0 _S6 = { vec3(0.0, 0.0, -1.0), - uintBitsToFloat(uMinDepth_0) };
#line 125
uvec2 _S7 = gl_WorkGroupID.xy;
#line 125
uint i_0 = gl_LocalInvocationIndex;
#line 125
for(;;)
{
#line 106
if(i_0 < gLightEnv_0.numPointLights_0)
{
}
else
{
#line 106
break;
}
PointLight_0 light_0 = gLightEnv_pointLights_0._data[i_0];
tAppendLight_0(i_0);
if(!PointLight_insidePlane_0(light_0, _S6))
{
oAppendLight_0(i_0);
#line 113
}
#line 106
i_0 = i_0 + 1024U;
#line 106
}
#line 120
barrier();
if(_S5)
{
((oLightIndexStartOffset_0) = atomicAdd((gCullingParams_oLightIndexCounter_0._data[0U]), (oLightCount_0)));
imageStore((gCullingParams_oLightGrid_0), ivec2((_S7)), uvec4(uvec2(oLightIndexStartOffset_0, oLightCount_0), uint(0), uint(0)));
((tLightIndexStartOffset_0) = atomicAdd((gCullingParams_tLightIndexCounter_0._data[0U]), (tLightCount_0)));
imageStore((gCullingParams_tLightGrid_0), ivec2((_S7)), uvec4(uvec2(tLightIndexStartOffset_0, tLightCount_0), uint(0), uint(0)));
#line 122
}
#line 130
barrier();
#line 130
uint k_0;
#line 130
if(gl_LocalInvocationIndex < oLightCount_0)
{
#line 130
k_0 = gl_LocalInvocationIndex;
#line 130
for(;;)
{
gCullingParams_oLightIndexList_0._data[oLightIndexStartOffset_0 + k_0] = oLightList_0[k_0];
#line 132
uint j_0 = k_0 + 1024U;
#line 132
if(j_0 < oLightCount_0)
{
}
else
{
#line 132
break;
}
#line 132
k_0 = j_0;
#line 132
}
#line 132
}
#line 132
if(gl_LocalInvocationIndex < tLightCount_0)
{
#line 132
k_0 = gl_LocalInvocationIndex;
#line 132
for(;;)
{
#line 140
gCullingParams_tLightIndexList_0._data[tLightIndexStartOffset_0 + k_0] = tLightList_0[k_0];
#line 138
uint k_1 = k_0 + 1024U;
#line 138
if(k_1 < tLightCount_0)
{
}
else
{
#line 138
break;
}
#line 138
k_0 = k_1;
#line 138
}
#line 138
}
#line 144
return;
}
+2 -1
View File
@@ -1,6 +1,7 @@
#include "FontAsset.h" #include "FontAsset.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/Vulkan/VulkanGraphicsEnums.h" #include "Graphics/Vulkan/Enums.h"
#include "Graphics/Texture.h"
#include <ktx.h> #include <ktx.h>
using namespace Seele; using namespace Seele;
-3
View File
@@ -2,9 +2,6 @@
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/Mesh.h" #include "Graphics/Mesh.h"
#include "AssetRegistry.h" #include "AssetRegistry.h"
#include "Graphics/VertexShaderInput.h"
#include "Material/MaterialInterface.h"
#include "Graphics/StaticMeshVertexInput.h"
using namespace Seele; using namespace Seele;
+1 -2
View File
@@ -1,8 +1,7 @@
#include "TextureAsset.h" #include "TextureAsset.h"
#include "Graphics/GraphicsResources.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Window/WindowManager.h" #include "Window/WindowManager.h"
#include "Graphics/Vulkan/VulkanGraphicsEnums.h" #include "Graphics/Vulkan/Enums.h"
#include "ktx.h" #include "ktx.h"
using namespace Seele; using namespace Seele;
-1
View File
@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Component.h" #include "Component.h"
#include "Math/Matrix.h" #include "Math/Matrix.h"
#include "Graphics/GraphicsResources.h"
#include "Transform.h" #include "Transform.h"
namespace Seele namespace Seele
+1 -1
View File
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "Graphics/GraphicsResources.h" #include "Graphics/Resources.h"
namespace Seele namespace Seele
{ {
-1
View File
@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Asset/MeshAsset.h" #include "Asset/MeshAsset.h"
#include "Graphics/VertexData.h" #include "Graphics/VertexData.h"
#include "Graphics/TopologyData.h"
#include "Material/MaterialInstance.h" #include "Material/MaterialInstance.h"
namespace Seele namespace Seele
+1 -1
View File
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "Graphics/GraphicsResources.h" #include "Graphics/Texture.h"
namespace Seele namespace Seele
{ {
+14
View File
@@ -310,6 +310,20 @@ public:
} }
return end(); return end();
} }
template<class Pred>
requires std::predicate<Pred, value_type>
constexpr iterator find(Pred pred) noexcept
{
for (size_type i = 0; i < arraySize; ++i)
{
if (pred(_data[i]))
{
return const_iterator(&_data[i]);
}
}
return end();
}
constexpr allocator_type get_allocator() const noexcept constexpr allocator_type get_allocator() const noexcept
{ {
return allocator; return allocator;
+91
View File
@@ -0,0 +1,91 @@
#include "Buffer.h"
using namespace Seele;
using namespace Seele::Gfx;
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
: QueueOwnedResource(mapping, startQueue)
{
}
Buffer::~Buffer()
{
}
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData)
: Buffer(mapping, resourceData.owner)
, contents(resourceData.size)
{
if (resourceData.data != nullptr)
{
std::memcpy(contents.data(), resourceData.data, contents.size());
}
}
UniformBuffer::~UniformBuffer()
{
}
bool UniformBuffer::updateContents(const BulkResourceData& resourceData)
{
assert(contents.size() == resourceData.size);
if (std::memcmp(contents.data(), resourceData.data, contents.size()) == 0)
{
return false;
}
std::memcpy(contents.data(), resourceData.data, contents.size());
return true;
}
ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& resourceData)
: Buffer(mapping, resourceData.owner)
, contents(resourceData.size)
, stride(stride)
, numElements(numElements)
{
if (resourceData.data != nullptr)
{
std::memcpy(contents.data(), resourceData.data, resourceData.size);
}
}
ShaderBuffer::~ShaderBuffer()
{
}
bool ShaderBuffer::updateContents(const BulkResourceData& resourceData)
{
assert(contents.size() >= resourceData.size);
if (std::memcmp(contents.data(), resourceData.data, resourceData.size) == 0)
{
return false;
}
std::memcpy(contents.data(), resourceData.data, resourceData.size);
return true;
}
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
: Buffer(mapping, startQueueType)
, numVertices(numVertices)
, vertexSize(vertexSize)
{
}
VertexBuffer::~VertexBuffer()
{
}
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType)
: Buffer(mapping, startQueueType)
, indexType(indexType)
{
switch (indexType)
{
case SE_INDEX_TYPE_UINT16:
numIndices = size / sizeof(uint16);
break;
case SE_INDEX_TYPE_UINT32:
numIndices = size / sizeof(uint32);
default:
break;
}
}
IndexBuffer::~IndexBuffer()
{
}
+153
View File
@@ -0,0 +1,153 @@
#pragma once
#include "Resources.h"
namespace Seele
{
namespace Gfx
{
// IMPORTANT!!
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
// This is because the refcounting object is unique per allocation, so
// the base address of both the Gfx:: and the implementation class
// need to match for it to work
class Buffer : public QueueOwnedResource
{
public:
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Buffer();
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
};
class UniformBuffer : public Buffer
{
public:
UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData);
virtual ~UniformBuffer();
// returns true if an update was performed, false if the old contents == new contents
virtual bool updateContents(const BulkResourceData& resourceData);
bool isDataEquals(UniformBuffer* other)
{
if(other == nullptr)
{
return false;
}
if(contents.size() != other->contents.size())
{
return false;
}
if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0)
{
return false;
}
return true;
}
protected:
Array<uint8> contents;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(UniformBuffer)
class VertexBuffer : public Buffer
{
public:
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
virtual ~VertexBuffer();
constexpr uint32 getNumVertices() const
{
return numVertices;
}
// Size of one vertex in bytes
constexpr uint32 getVertexSize() const
{
return vertexSize;
}
virtual void updateRegion(BulkResourceData update) = 0;
virtual void download(Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
uint32 numVertices;
uint32 vertexSize;
};
DEFINE_REF(VertexBuffer)
class IndexBuffer : public Buffer
{
public:
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType);
virtual ~IndexBuffer();
constexpr uint64 getNumIndices() const
{
return numIndices;
}
constexpr Gfx::SeIndexType getIndexType() const
{
return indexType;
}
virtual void download(Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Gfx::SeIndexType indexType;
uint64 numIndices;
};
DEFINE_REF(IndexBuffer)
class ShaderBuffer : public Buffer
{
public:
ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& bulkResourceData);
virtual ~ShaderBuffer();
virtual bool updateContents(const BulkResourceData& resourceData);
bool isDataEquals(ShaderBuffer* other)
{
if(other == nullptr)
{
return false;
}
if(contents.size() != other->contents.size())
{
return false;
}
if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0)
{
return false;
}
return true;
}
constexpr uint32 getNumElements() const
{
return numElements;
}
constexpr uint32 getStride() const
{
return stride;
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Array<uint8> contents;
uint32 numElements;
uint32 stride;
};
DEFINE_REF(ShaderBuffer)
}
}
+22 -8
View File
@@ -1,33 +1,47 @@
target_sources(Engine target_sources(Engine
PRIVATE PRIVATE
Buffer.h
Buffer.cpp
DebugVertex.h DebugVertex.h
GraphicsResources.h Descriptor.h
GraphicsResources.cpp Descriptor.cpp
GraphicsInitializer.h Enums.h
GraphicsEnums.h Enums.cpp
GraphicsEnums.cpp
Graphics.h Graphics.h
Graphics.cpp Graphics.cpp
Initializer.h
Mesh.h Mesh.h
Mesh.cpp Mesh.cpp
RenderTarget.h
RenderTarget.cpp
Resources.h
Resources.cpp
Shader.h
Shader.cpp
ShaderCompiler.h ShaderCompiler.h
ShaderCompiler.cpp ShaderCompiler.cpp
StaticMeshVertexData.h StaticMeshVertexData.h
StaticMeshVertexData.cpp StaticMeshVertexData.cpp
Texture.h
Texture.cpp
VertexData.h VertexData.h
VertexData.cpp) VertexData.cpp)
target_sources(Engine target_sources(Engine
PUBLIC FILE_SET HEADERS PUBLIC FILE_SET HEADERS
FILES FILES
Buffer.h
DebugVertex.h DebugVertex.h
GraphicsResources.h Descriptor.h
GraphicsInitializer.h
GraphicsEnums.h
Graphics.h Graphics.h
Initializer.h
Mesh.h Mesh.h
RenderTarget.h
Resources.h
Shader.h
ShaderCompiler.h ShaderCompiler.h
StaticMeshVertexData.h StaticMeshVertexData.h
Texture.h
VertexData.h) VertexData.h)
add_subdirectory(RenderPass/) add_subdirectory(RenderPass/)
+47
View File
@@ -0,0 +1,47 @@
#include "Descriptor.h"
using namespace Seele;
using namespace Seele::Gfx;
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages)
{
if (descriptorBindings.size() <= bindingIndex)
{
descriptorBindings.resize(bindingIndex + 1);
}
DescriptorBinding& binding = descriptorBindings[bindingIndex];
binding.binding = bindingIndex;
binding.descriptorType = type;
binding.descriptorCount = arrayCount;
binding.bindingFlags = bindingFlags;
binding.shaderStages = shaderStages;
}
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
{
std::scoped_lock lock(allocatorLock);
PDescriptorSet result;
allocator->allocateDescriptorSet(result);
return result;
}
void DescriptorLayout::reset()
{
std::scoped_lock lock(allocatorLock);
allocator->reset();
}
void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout)
{
if (descriptorSetLayouts.size() <= setIndex)
{
descriptorSetLayouts.resize(setIndex + 1);
}
descriptorSetLayouts[setIndex] = layout;
layout->setIndex = setIndex;
}
void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant)
{
pushConstants.add(pushConstant);
}
+122
View File
@@ -0,0 +1,122 @@
#pragma once
#include "Enums.h"
#include "Resources.h"
namespace Seele
{
namespace Gfx
{
class DescriptorBinding
{
public:
DescriptorBinding()
: binding(0), descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM), descriptorCount(0x7fff), shaderStages(SE_SHADER_STAGE_ALL)
{
}
DescriptorBinding(const DescriptorBinding& other)
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
{
}
uint32 binding;
SeDescriptorType descriptorType;
uint32 descriptorCount;
SeDescriptorBindingFlags bindingFlags = 0;
SeShaderStageFlags shaderStages;
};
DEFINE_REF(DescriptorBinding)
DECLARE_REF(DescriptorSet)
class DescriptorAllocator
{
public:
DescriptorAllocator() {}
virtual ~DescriptorAllocator() {}
virtual void allocateDescriptorSet(PDescriptorSet& descriptorSet) = 0;
virtual void reset() = 0;
};
DEFINE_REF(DescriptorAllocator)
DECLARE_REF(UniformBuffer)
DECLARE_REF(ShaderBuffer)
DECLARE_REF(Texture)
DECLARE_REF(SamplerState)
class DescriptorSet
{
public:
virtual ~DescriptorSet() {}
virtual void writeChanges() = 0;
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
virtual void updateTextureArray(uint32_t binding, Array<PTexture> texture) = 0;
virtual bool operator<(PDescriptorSet other) = 0;
virtual uint32 getSetIndex() const = 0;
};
DEFINE_REF(DescriptorSet)
class DescriptorLayout
{
public:
DescriptorLayout(const std::string& name)
: setIndex(0)
, name(name)
{
}
virtual ~DescriptorLayout() {}
DescriptorLayout& operator=(const DescriptorLayout& other)
{
if (this != &other)
{
descriptorBindings.resize(other.descriptorBindings.size());
for (uint32 i = 0; i < descriptorBindings.size(); ++i)
{
descriptorBindings[i] = other.descriptorBindings[i];
}
}
return *this;
}
virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0, SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL);
virtual void reset();
virtual PDescriptorSet allocateDescriptorSet();
const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
constexpr uint32 getSetIndex() const { return setIndex; }
constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; }
protected:
Array<DescriptorBinding> descriptorBindings;
PDescriptorAllocator allocator;
std::mutex allocatorLock;
uint32 setIndex;
std::string name;
friend class PipelineLayout;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorLayout)
class PipelineLayout
{
public:
PipelineLayout(PPipelineLayout baseLayout)
{
if (baseLayout != nullptr)
{
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
pushConstants = baseLayout->pushConstants;
}
}
virtual ~PipelineLayout() {}
virtual void create() = 0;
virtual void reset() = 0;
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
void addPushConstants(const SePushConstantRange& pushConstants);
virtual uint32 getHash() const = 0;
protected:
Array<PDescriptorLayout> descriptorSetLayouts;
Array<SePushConstantRange> pushConstants;
};
DEFINE_REF(PipelineLayout)
}
}
+24 -6
View File
@@ -1,13 +1,31 @@
#pragma once #pragma once
#include "MinimalEngine.h" #include "MinimalEngine.h"
#include "GraphicsResources.h" #include "Resources.h"
#include "Containers/Array.h" #include "Containers/Array.h"
#include "ShaderCompiler.h"
namespace Seele namespace Seele
{ {
namespace Gfx namespace Gfx
{ {
DECLARE_REF(Window)
DECLARE_REF(Viewport)
DECLARE_REF(RenderTargetLayout)
DECLARE_REF(ShaderCompiler)
DECLARE_REF(Texture)
DECLARE_REF(Texture2D)
DECLARE_REF(Texture3D)
DECLARE_REF(TextureCube)
DECLARE_REF(DescriptorLayout)
DECLARE_REF(VertexShader)
DECLARE_REF(FragmentShader)
DECLARE_REF(ComputeShader)
DECLARE_REF(TaskShader)
DECLARE_REF(MeshShader)
DECLARE_REF(ShaderBuffer)
DECLARE_REF(VertexBuffer)
DECLARE_REF(IndexBuffer)
DECLARE_REF(UniformBuffer)
DECLARE_REF(PipelineLayout)
class Graphics class Graphics
{ {
public: public:
@@ -46,12 +64,12 @@ public:
virtual PComputeCommand createComputeCommand(const std::string& name = "") = 0; virtual PComputeCommand createComputeCommand(const std::string& name = "") = 0;
virtual PVertexDeclaration createVertexDeclaration(const Array<VertexElement>& element) = 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 PEvaluationShader createEvaluationShader(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 PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0; virtual PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0; virtual PMeshShader createMeshShader(const ShaderCreateInfo& createInfo) = 0;
virtual PTaskShader createTaskShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGraphicsPipeline createGraphicsPipeline(const LegacyPipelineCreateInfo& createInfo) = 0;
virtual PGraphicsPipeline createGraphicsPipeline(const MeshPipelineCreateInfo& createInfo) = 0;
virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0; virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0;
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0; virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
-549
View File
@@ -1,549 +0,0 @@
#include "GraphicsResources.h"
#include "Graphics.h"
#include "RenderPass/DepthPrepass.h"
#include "RenderPass/BasePass.h"
#include "Material/Material.h"
using namespace Seele;
using namespace Seele::Gfx;
std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type)
{
switch (type)
{
case Gfx::RenderPassType::DepthPrepass:
return "DepthPrepass";
case Gfx::RenderPassType::BasePass:
return "ForwardPlus";
default:
return "";
}
}
void modifyRenderPassMacros(Gfx::RenderPassType type, Map<const char*, const char*>& defines)
{
switch (type)
{
case Gfx::RenderPassType::DepthPrepass:
DepthPrepass::modifyRenderPassMacros(defines);
break;
case Gfx::RenderPassType::BasePass:
BasePass::modifyRenderPassMacros(defines);
break;
}
}
ShaderMap::ShaderMap()
{
}
ShaderMap::~ShaderMap()
{
}
const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const
{
for(uint32 i = 0; i < shaders.size(); ++i)
{
if(shaders[i].id == id)
{
return &(shaders[i]);
}
}
return nullptr;
}
ShaderCollection& ShaderMap::createShaders(
PGraphics graphics,
RenderPassType renderPass,
PMaterial material,
VertexInputType* vertexInput,
bool /*bPositionOnly*/)
{
std::scoped_lock lock(shadersLock);
ShaderCollection& collection = shaders.add();
//collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
ShaderCreateInfo createInfo;
createInfo.entryPoint = "vertexMain";
createInfo.typeParameter = {material->getName().c_str()};
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1";
createInfo.defines["USE_INSTANCING"] = "0";
modifyRenderPassMacros(renderPass, createInfo.defines);
createInfo.name = getShaderNameFromRenderPassType(renderPass) + " Material " + material->getName();
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass));
createInfo.mainModule = getShaderNameFromRenderPassType(renderPass);
createInfo.additionalModules.add(vertexInput->getShaderFilename());
createInfo.additionalModules.add(material->getName());
collection.vertexShader = graphics->createVertexShader(createInfo);
if(renderPass != RenderPassType::DepthPrepass)
{
createInfo.entryPoint = "fragmentMain";
collection.fragmentShader = graphics->createFragmentShader(createInfo);
}
ShaderPermutation permutation;
std::string materialName = material->getName();
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;
}
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages)
{
if (descriptorBindings.size() <= bindingIndex)
{
descriptorBindings.resize(bindingIndex + 1);
}
DescriptorBinding& binding = descriptorBindings[bindingIndex];
binding.binding = bindingIndex;
binding.descriptorType = type;
binding.descriptorCount = arrayCount;
binding.bindingFlags = bindingFlags;
binding.shaderStages = shaderStages;
}
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
{
std::scoped_lock lock(allocatorLock);
PDescriptorSet result;
allocator->allocateDescriptorSet(result);
return result;
}
void DescriptorLayout::reset()
{
std::scoped_lock lock(allocatorLock);
allocator->reset();
}
void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout)
{
if (descriptorSetLayouts.size() <= setIndex)
{
descriptorSetLayouts.resize(setIndex + 1);
}
descriptorSetLayouts[setIndex] = layout;
layout->setIndex = setIndex;
}
void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant)
{
pushConstants.add(pushConstant);
}
QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType)
: currentOwner(startQueueType)
, mapping(mapping)
{
}
QueueOwnedResource::~QueueOwnedResource()
{
}
void QueueOwnedResource::transferOwnership(QueueType newOwner)
{
if(mapping.needsTransfer(currentOwner, newOwner))
{
executeOwnershipBarrier(newOwner);
}
currentOwner = newOwner;
}
void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage)
{
// maybe add some checks
executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
: QueueOwnedResource(mapping, startQueue)
{
}
Buffer::~Buffer()
{
}
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData)
: Buffer(mapping, resourceData.owner)
, contents(resourceData.size)
{
if(resourceData.data != nullptr)
{
std::memcpy(contents.data(), resourceData.data, contents.size());
}
}
UniformBuffer::~UniformBuffer()
{
}
bool UniformBuffer::updateContents(const BulkResourceData& resourceData)
{
assert(contents.size() == resourceData.size);
if(std::memcmp(contents.data(), resourceData.data, contents.size()) == 0)
{
return false;
}
std::memcpy(contents.data(), resourceData.data, contents.size());
return true;
}
ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& resourceData)
: Buffer(mapping, resourceData.owner)
, contents(resourceData.size)
, stride(stride)
, numElements(numElements)
{
if(resourceData.data != nullptr)
{
std::memcpy(contents.data(), resourceData.data, resourceData.size);
}
}
ShaderBuffer::~ShaderBuffer()
{
}
bool ShaderBuffer::updateContents(const BulkResourceData& resourceData)
{
assert(contents.size() >= resourceData.size);
if(std::memcmp(contents.data(), resourceData.data, resourceData.size) == 0)
{
return false;
}
std::memcpy(contents.data(), resourceData.data, resourceData.size);
return true;
}
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
: Buffer(mapping, startQueueType)
, numVertices(numVertices)
, vertexSize(vertexSize)
{
}
VertexBuffer::~VertexBuffer()
{
}
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType)
: Buffer(mapping, startQueueType)
, indexType(indexType)
{
switch (indexType)
{
case SE_INDEX_TYPE_UINT16:
numIndices = size / sizeof(uint16);
break;
case SE_INDEX_TYPE_UINT32:
numIndices = size / sizeof(uint32);
default:
break;
}
}
IndexBuffer::~IndexBuffer()
{
}
VertexStream::VertexStream()
{}
VertexStream::VertexStream(uint32 stride, uint32 offset, uint8 instanced)
: stride(stride)
, offset(offset)
, instanced(instanced)
{
}
VertexStream::~VertexStream()
{
}
void VertexStream::addVertexElement(VertexElement element)
{
vertexDescription.add(element);
}
const Array<VertexElement> VertexStream::getVertexDescriptions() const
{
return vertexDescription;
}
VertexDataManager::VertexDataManager(PGraphics graphics)
: currentSize(8 * 1024 * 1024)
, inUse(0)
, graphics(graphics)
{
VertexBufferCreateInfo defaultInfo = {
.resourceData = {
.size = currentSize,
.data = nullptr,
}
};
buffer = graphics->createVertexBuffer(defaultInfo);
}
VertexDataManager::~VertexDataManager()
{
}
VertexDataAllocation VertexDataManager::createVertexBuffer(const VertexBufferCreateInfo& vbInfo)
{
VertexDataAllocation data = allocateData(vbInfo.resourceData.size);
buffer->updateRegion(BulkResourceData{
.size = data.size,
.offset = data.offset,
.data = vbInfo.resourceData.data
});
activeAllocations[data.offset] = data;
return data;
}
void VertexDataManager::freeAllocation(VertexDataAllocation alloc)
{
uint64 lowerBound = alloc.offset;
uint64 upperBound = alloc.offset + alloc.size;
bool joinedLower = false;
uint64 lowerOffset = 0;
//Join lower bound
for (auto& [offset, freeAlloc] : freeRanges)
{
if (freeAlloc.offset <= lowerBound
&& freeAlloc.offset + freeAlloc.size >= upperBound)
{
// allocation is already in a free region
return;
}
if (freeAlloc.offset + freeAlloc.size == lowerBound)
{
//extend freeAlloc by the allocatedSize
freeAlloc.size += alloc.size;
joinedLower = true;
lowerOffset = freeAlloc.offset;
break;
}
}
//Join upper bound
auto foundAlloc = freeRanges.find(upperBound);
if (foundAlloc != freeRanges.end())
{
// There is a free allocation ending where the new free one ends
if (joinedLower)
{
// extend allocHandle by another foundAlloc->allocatedSize bytes
freeRanges[lowerOffset].size += foundAlloc->value.size;
freeRanges.erase(upperBound);
}
else
{
// set foundAlloc back by size amount
freeRanges[upperBound].offset -= alloc.size;
freeRanges[upperBound].size += alloc.size;
// place back at correct offset
freeRanges[freeRanges[upperBound].offset] = freeRanges[upperBound];
// remove from offset map since key changes
freeRanges.erase(upperBound);
}
}
else
{
// No matching upper bound found
if(!joinedLower)
{
// Lower bound also not joined, create new range
freeRanges[alloc.offset] = alloc;
}
}
activeAllocations.erase(alloc.offset);
inUse -= alloc.size;
}
VertexDataAllocation VertexDataManager::allocateData(uint64 size)
{
for (auto& [offset, freeAllocation] : freeRanges)
{
assert(offset == freeAllocation.offset);
if (freeAllocation.size == size)
{
activeAllocations[offset] = freeAllocation;
freeRanges.erase(offset);
inUse += size;
return freeAllocation;
}
else if (size < freeAllocation.size)
{
freeAllocation.size -= size;
freeAllocation.offset += size;
VertexDataAllocation subAlloc = VertexDataAllocation(size, offset);
activeAllocations[offset] = subAlloc;
freeRanges[freeAllocation.offset] = freeAllocation;
freeRanges.erase(offset);
inUse += size;
return subAlloc;
}
}
throw std::logic_error("TODO: expand buffer");
}
VertexDeclaration::VertexDeclaration()
{
}
VertexDeclaration::~VertexDeclaration()
{
}
static std::mutex vertexDeclarationLock;
static Map<uint32, PVertexDeclaration> vertexDeclarationCache;
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList)
{
std::scoped_lock lock(vertexDeclarationLock);
uint32 key = CRC::Calculate(&elementList, sizeof(VertexElement) * elementList.size(), CRC::CRC_32());
auto found = vertexDeclarationCache[key];
if(found == nullptr)
{
return found;
}
PVertexDeclaration newDeclaration = graphics->createVertexDeclaration(elementList);
vertexDeclarationCache[key] = newDeclaration;
return newDeclaration;
}
Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: QueueOwnedResource(mapping, startQueueType)
{
}
Texture::~Texture()
{
}
Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: Texture(mapping, startQueueType)
{
}
Texture2D::~Texture2D()
{
}
Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: Texture(mapping, startQueueType)
{
}
Texture3D::~Texture3D()
{
}
TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: Texture(mapping, startQueueType)
{
}
TextureCube::~TextureCube()
{
}
RenderCommand::RenderCommand()
{
}
RenderCommand::~RenderCommand()
{
}
ComputeCommand::ComputeCommand()
{
}
ComputeCommand::~ComputeCommand()
{
}
RenderTargetLayout::RenderTargetLayout()
: inputAttachments()
, colorAttachments()
, depthAttachment()
{
}
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment)
: inputAttachments()
, colorAttachments()
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
}
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment)
: inputAttachments()
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
colorAttachments.add(colorAttachment);
}
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
: inputAttachments()
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
}
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
: inputAttachments(inputAttachments)
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
}
Window::Window(const WindowCreateInfo &createInfo)
: windowState(createInfo)
{
}
Window::~Window()
{
}
Viewport::Viewport(PWindow owner, const ViewportCreateInfo &viewportInfo)
: sizeX(viewportInfo.dimensions.size.x)
, sizeY(viewportInfo.dimensions.size.y)
, offsetX(viewportInfo.dimensions.offset.x)
, offsetY(viewportInfo.dimensions.offset.y)
, fieldOfView(viewportInfo.fieldOfView)
, owner(owner)
{
}
Viewport::~Viewport()
{
}
Matrix4 Viewport::getProjectionMatrix() const
{
if(fieldOfView > 0.0f)
{
return glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
}
else
{
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
}
}
-851
View File
@@ -1,851 +0,0 @@
#pragma once
#include "Math/Math.h"
#include "GraphicsEnums.h"
#include "Containers/Array.h"
#include "Containers/List.h"
#include "GraphicsInitializer.h"
#include "CRC.h"
#include <functional>
#ifndef ENABLE_VALIDATION
#define ENABLE_VALIDATION 0
#endif
namespace Seele
{
struct VertexInputStream;
struct VertexStreamComponent;
class VertexInputType;
struct MeshBatchElement;
DECLARE_REF(Material)
namespace Gfx
{
DECLARE_REF(Graphics)
class SamplerState
{
public:
virtual ~SamplerState()
{
}
};
DEFINE_REF(SamplerState)
class Shader
{};
DEFINE_REF(Shader)
class VertexShader
{
public:
VertexShader() {}
virtual ~VertexShader() {}
};
DEFINE_REF(VertexShader)
class ControlShader
{
public:
ControlShader() : numPatchPoints(0) {}
virtual ~ControlShader() {}
uint32 getNumPatches() const { return numPatchPoints; }
protected:
uint32 numPatchPoints;
};
DEFINE_REF(ControlShader)
class EvaluationShader
{
public:
EvaluationShader() {}
virtual ~EvaluationShader() {}
};
DEFINE_REF(EvaluationShader)
class GeometryShader
{
public:
GeometryShader() {}
virtual ~GeometryShader() {}
};
DEFINE_REF(GeometryShader)
class FragmentShader
{
public:
FragmentShader() {}
virtual ~FragmentShader() {}
};
DEFINE_REF(FragmentShader)
class ComputeShader
{
public:
ComputeShader() {}
virtual ~ComputeShader() {}
};
DEFINE_REF(ComputeShader)
//Uniquely identifies a permutation of shaders
//using the type parameters used to generate it
struct ShaderPermutation
{
RenderPassType passType;
char vertexInputName[15];
char materialName[16];
//TODO: lightmapping etc
};
//Hashed ShaderPermutation for fast lookup
struct PermutationId
{
uint32 hash;
PermutationId()
: hash(0)
{}
PermutationId(ShaderPermutation permutation)
: hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32()))
{}
friend inline bool operator==(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash == rhs.hash;
}
friend inline bool operator!=(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash != rhs.hash;
}
friend inline bool operator<(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash < rhs.hash;
}
friend inline bool operator>(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash > rhs.hash;
}
};
struct ShaderCollection
{
PermutationId id;
//PVertexDeclaration vertexDeclaration;
PVertexShader vertexShader;
PControlShader controlShader;
PEvaluationShader evalutionShader;
PGeometryShader geometryShader;
PFragmentShader fragmentShader;
};
class ShaderMap
{
public:
ShaderMap();
~ShaderMap();
const ShaderCollection* findShaders(PermutationId&& id) const;
ShaderCollection& createShaders(
PGraphics graphics,
RenderPassType passName,
PMaterial material,
VertexInputType* vertexInput,
bool bPositionOnly);
private:
std::mutex shadersLock;
Array<ShaderCollection> shaders;
};
DEFINE_REF(ShaderMap)
class DescriptorBinding
{
public:
DescriptorBinding()
: binding(0), descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM), descriptorCount(0x7fff), shaderStages(SE_SHADER_STAGE_ALL)
{
}
DescriptorBinding(const DescriptorBinding &other)
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
{
}
uint32 binding;
SeDescriptorType descriptorType;
uint32 descriptorCount;
SeDescriptorBindingFlags bindingFlags = 0;
SeShaderStageFlags shaderStages;
};
DEFINE_REF(DescriptorBinding)
DECLARE_REF(DescriptorSet)
class DescriptorAllocator
{
public:
DescriptorAllocator() {}
virtual ~DescriptorAllocator() {}
virtual void allocateDescriptorSet(PDescriptorSet &descriptorSet) = 0;
virtual void reset() = 0;
};
DEFINE_REF(DescriptorAllocator)
DECLARE_REF(UniformBuffer)
DECLARE_REF(ShaderBuffer)
DECLARE_REF(Texture)
class DescriptorSet
{
public:
virtual ~DescriptorSet() {}
virtual void writeChanges() = 0;
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
virtual void updateTextureArray(uint32_t binding, Array<PTexture> texture) = 0;
virtual bool operator<(PDescriptorSet other) = 0;
virtual uint32 getSetIndex() const = 0;
};
DEFINE_REF(DescriptorSet)
class DescriptorLayout
{
public:
DescriptorLayout(const std::string& name)
: setIndex(0)
, name(name)
{
}
virtual ~DescriptorLayout() {}
DescriptorLayout& operator=(const DescriptorLayout &other)
{
if(this != &other)
{
descriptorBindings.resize(other.descriptorBindings.size());
for(uint32 i = 0; i < descriptorBindings.size(); ++i)
{
descriptorBindings[i] = other.descriptorBindings[i];
}
}
return *this;
}
virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0, SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL);
virtual void reset();
virtual PDescriptorSet allocateDescriptorSet();
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
constexpr uint32 getSetIndex() const { return setIndex; }
constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; }
protected:
Array<DescriptorBinding> descriptorBindings;
PDescriptorAllocator allocator;
std::mutex allocatorLock;
uint32 setIndex;
std::string name;
friend class PipelineLayout;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorLayout)
class PipelineLayout
{
public:
PipelineLayout(PPipelineLayout baseLayout)
{
if(baseLayout != nullptr)
{
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
pushConstants = baseLayout->pushConstants;
}
}
virtual ~PipelineLayout() {}
virtual void create() = 0;
virtual void reset() = 0;
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
void addPushConstants(const SePushConstantRange &pushConstants);
virtual uint32 getHash() const = 0;
protected:
Array<PDescriptorLayout> descriptorSetLayouts;
Array<SePushConstantRange> pushConstants;
};
DEFINE_REF(PipelineLayout)
struct QueueFamilyMapping
{
uint32 graphicsFamily;
uint32 computeFamily;
uint32 transferFamily;
uint32 dedicatedTransferFamily;
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const
{
switch (type)
{
case Gfx::QueueType::GRAPHICS:
return graphicsFamily;
case Gfx::QueueType::COMPUTE:
return computeFamily;
case Gfx::QueueType::TRANSFER:
return transferFamily;
case Gfx::QueueType::DEDICATED_TRANSFER:
return dedicatedTransferFamily;
default:
return 0x7fff;
}
}
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const
{
uint32 srcIndex = getQueueTypeFamilyIndex(src);
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
return srcIndex != dstIndex;
}
};
class QueueOwnedResource
{
public:
QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~QueueOwnedResource();
//Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner);
void pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage);
protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Gfx::QueueType currentOwner;
QueueFamilyMapping mapping;
};
DEFINE_REF(QueueOwnedResource)
// IMPORTANT!!
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
// This is because the refcounting object is unique per allocation, so
// the base address of both the Gfx:: and the implementation class
// need to match for it to work
class Buffer : public QueueOwnedResource
{
public:
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Buffer();
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
};
class UniformBuffer : public Buffer
{
public:
UniformBuffer(QueueFamilyMapping mapping, const BulkResourceData& resourceData);
virtual ~UniformBuffer();
// returns true if an update was performed, false if the old contents == new contents
virtual bool updateContents(const BulkResourceData& resourceData);
bool isDataEquals(UniformBuffer* other)
{
if(other == nullptr)
{
return false;
}
if(contents.size() != other->contents.size())
{
return false;
}
if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0)
{
return false;
}
return true;
}
protected:
Array<uint8> contents;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(UniformBuffer)
class VertexBuffer : public Buffer
{
public:
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
virtual ~VertexBuffer();
constexpr uint32 getNumVertices() const
{
return numVertices;
}
// Size of one vertex in bytes
constexpr uint32 getVertexSize() const
{
return vertexSize;
}
virtual void updateRegion(BulkResourceData update) = 0;
virtual void download(Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
uint32 numVertices;
uint32 vertexSize;
};
DEFINE_REF(VertexBuffer)
class IndexBuffer : public Buffer
{
public:
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType);
virtual ~IndexBuffer();
constexpr uint64 getNumIndices() const
{
return numIndices;
}
constexpr Gfx::SeIndexType getIndexType() const
{
return indexType;
}
virtual void download(Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Gfx::SeIndexType indexType;
uint64 numIndices;
};
DEFINE_REF(IndexBuffer)
class ShaderBuffer : public Buffer
{
public:
ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const BulkResourceData& bulkResourceData);
virtual ~ShaderBuffer();
virtual bool updateContents(const BulkResourceData& resourceData);
bool isDataEquals(ShaderBuffer* other)
{
if(other == nullptr)
{
return false;
}
if(contents.size() != other->contents.size())
{
return false;
}
if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0)
{
return false;
}
return true;
}
constexpr uint32 getNumElements() const
{
return numElements;
}
constexpr uint32 getStride() const
{
return stride;
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Array<uint8> contents;
uint32 numElements;
uint32 stride;
};
DEFINE_REF(ShaderBuffer)
class VertexStream
{
public:
VertexStream();
VertexStream(uint32 stride, uint32 offset, uint8 instanced);
~VertexStream();
void addVertexElement(VertexElement element);
const Array<VertexElement> getVertexDescriptions() const;
inline uint8 isInstanced() const { return instanced; }
uint32 stride;
uint32 offset;
Array<VertexElement> vertexDescription;
uint8 instanced;
};
DEFINE_REF(VertexStream)
struct VertexDataAllocation
{
uint64 size;
uint64 offset;
};
class VertexDataManager
{
public:
VertexDataManager(PGraphics graphics);
virtual ~VertexDataManager();
VertexDataAllocation createVertexBuffer(const VertexBufferCreateInfo& vbInfo);
void freeAllocation(VertexDataAllocation alloc);
PVertexBuffer getVertexBuffer() const { return buffer; }
private:
VertexDataAllocation allocateData(uint64 size);
Map<uint64, VertexDataAllocation> freeRanges;
Map<uint64, VertexDataAllocation> activeAllocations;
uint64 currentSize;
uint64 inUse;
PVertexBuffer buffer;
PGraphics graphics;
};
DEFINE_REF(VertexDataManager)
class VertexDeclaration
{
public:
VertexDeclaration();
~VertexDeclaration();
static PVertexDeclaration createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList);
private:
};
DEFINE_REF(VertexDeclaration)
class GraphicsPipeline
{
public:
GraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo, PPipelineLayout layout) : createInfo(createInfo) , layout(layout) {}
virtual ~GraphicsPipeline(){}
const GraphicsPipelineCreateInfo& getCreateInfo() const {return createInfo;}
PPipelineLayout getPipelineLayout() const { return layout; }
protected:
GraphicsPipelineCreateInfo createInfo;
PPipelineLayout layout;
};
DEFINE_REF(GraphicsPipeline)
class ComputePipeline
{
public:
ComputePipeline(const ComputePipelineCreateInfo& createInfo, PPipelineLayout layout) : createInfo(createInfo), layout(layout) {}
virtual ~ComputePipeline(){}
const ComputePipelineCreateInfo& getCreateInfo() const { return createInfo; }
PPipelineLayout getPipelineLayout() const { return layout; }
protected:
ComputePipelineCreateInfo createInfo;
PPipelineLayout layout;
};
DEFINE_REF(ComputePipeline)
// IMPORTANT!!
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
// This is because the refcounting object is unique per allocation, so
// the base address of both the Gfx:: and the implementation class
// need to match for it to work
class Texture : public QueueOwnedResource
{
public:
Texture(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual uint32 getNumFaces() const { return 1; }
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture2D* getTexture2D() { return nullptr; }
virtual class Texture3D* getTexture3D() { return nullptr; }
virtual class TextureCube* getTextureCube() { return nullptr; }
virtual void* getNativeHandle() { return nullptr; }
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(Texture)
class Texture2D : public Texture
{
public:
Texture2D(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture2D();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture2D* getTexture2D() { return this; }
protected:
//Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(Texture2D)
class Texture3D : public Texture
{
public:
Texture3D(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture3D();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture3D* getTexture3D() { return this; }
protected:
//Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(Texture3D)
class TextureCube : public Texture
{
public:
TextureCube(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~TextureCube();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual uint32 getNumFaces() const { return 6; }
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class TextureCube* getTextureCube() { return this; }
protected:
//Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(TextureCube)
DECLARE_REF(Viewport)
class RenderCommand
{
public:
RenderCommand();
virtual ~RenderCommand();
virtual bool isReady() = 0;
virtual void setViewport(Gfx::PViewport viewport) = 0;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0;
virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ);
std::string name;
};
DEFINE_REF(RenderCommand)
class ComputeCommand
{
public:
ComputeCommand();
virtual ~ComputeCommand();
virtual bool isReady() = 0;
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
std::string name;
};
DEFINE_REF(ComputeCommand)
class Window
{
public:
Window(const WindowCreateInfo &createInfo);
virtual ~Window();
virtual void beginFrame() = 0;
virtual void endFrame() = 0;
virtual void onWindowCloseEvent() = 0;
virtual PTexture2D getBackBuffer() const = 0;
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) = 0;
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) = 0;
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) = 0;
virtual void setScrollCallback(std::function<void(double, double)> callback) = 0;
virtual void setFileCallback(std::function<void(int, const char**)> callback) = 0;
virtual void setCloseCallback(std::function<void()> callback) = 0;
SeFormat getSwapchainFormat() const
{
return windowState.pixelFormat;
}
SeSampleCountFlags getNumSamples() const
{
return windowState.numSamples;
}
uint32 getSizeX() const
{
return windowState.width;
}
uint32 getSizeY() const
{
return windowState.height;
}
protected:
WindowCreateInfo windowState;
};
DEFINE_REF(Window)
class Viewport
{
public:
Viewport(PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY) = 0;
virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0;
constexpr PWindow getOwner() const {return owner;}
constexpr uint32 getSizeX() const {return sizeX;}
constexpr uint32 getSizeY() const {return sizeY;}
constexpr uint32 getOffsetX() const {return offsetX;}
constexpr uint32 getOffsetY() const {return offsetY;}
Matrix4 getProjectionMatrix() const;
protected:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
float fieldOfView;
PWindow owner;
};
DEFINE_REF(Viewport)
class RenderTargetAttachment
{
public:
RenderTargetAttachment(PTexture2D texture,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
: loadOp(loadOp)
, storeOp(storeOp)
, stencilLoadOp(stencilLoadOp)
, stencilStoreOp(stencilStoreOp)
, texture(texture)
, clear()
, componentFlags(0)
{
}
virtual ~RenderTargetAttachment()
{
}
virtual PTexture2D getTexture()
{
return texture;
}
virtual SeFormat getFormat() const
{
return texture->getFormat();
}
virtual SeSampleCountFlags getNumSamples() const
{
return texture->getNumSamples();
}
virtual uint32 getSizeX() const
{
return texture->getSizeX();
}
virtual uint32 getSizeY() const
{
return texture->getSizeY();
}
inline SeAttachmentLoadOp getLoadOp() const { return loadOp; }
inline SeAttachmentStoreOp getStoreOp() const { return storeOp; }
inline SeAttachmentLoadOp getStencilLoadOp() const { return stencilLoadOp; }
inline SeAttachmentStoreOp getStencilStoreOp() const { return stencilStoreOp; }
SeClearValue clear;
SeColorComponentFlags componentFlags;
SeAttachmentLoadOp loadOp;
SeAttachmentStoreOp storeOp;
SeAttachmentLoadOp stencilLoadOp;
SeAttachmentStoreOp stencilStoreOp;
protected:
PTexture2D texture;
};
DEFINE_REF(RenderTargetAttachment)
class SwapchainAttachment : public RenderTargetAttachment
{
public:
SwapchainAttachment(PWindow owner,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
: RenderTargetAttachment(nullptr, loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner)
{
clear.color.float32[0] = 0.0f;
clear.color.float32[1] = 0.0f;
clear.color.float32[2] = 0.0f;
clear.color.float32[3] = 1.0f;
componentFlags = SE_COLOR_COMPONENT_R_BIT | SE_COLOR_COMPONENT_G_BIT | SE_COLOR_COMPONENT_B_BIT | SE_COLOR_COMPONENT_A_BIT;
}
virtual PTexture2D getTexture() override
{
return owner->getBackBuffer();
}
virtual SeFormat getFormat() const override
{
return owner->getSwapchainFormat();
}
virtual SeSampleCountFlags getNumSamples() const override
{
return owner->getNumSamples();
}
virtual uint32 getSizeX() const
{
return owner->getSizeX();
}
virtual uint32 getSizeY() const
{
return owner->getSizeY();
}
private:
PWindow owner;
};
DEFINE_REF(SwapchainAttachment)
class RenderTargetLayout
{
public:
RenderTargetLayout();
RenderTargetLayout(PRenderTargetAttachment depthAttachment);
RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment);
RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet);
RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment);
Array<PRenderTargetAttachment> inputAttachments;
Array<PRenderTargetAttachment> colorAttachments;
PRenderTargetAttachment depthAttachment;
uint32 width;
uint32 height;
};
DEFINE_REF(RenderTargetLayout)
class RenderPass
{
public:
RenderPass(PRenderTargetLayout layout) : layout(layout) {}
virtual ~RenderPass() {}
inline PRenderTargetLayout getLayout() const { return layout; }
protected:
PRenderTargetLayout layout;
};
DEFINE_REF(RenderPass)
} // namespace Gfx
} // namespace Seele
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "GraphicsEnums.h" #include "Enums.h"
#include "Containers/Map.h" #include "Containers/Map.h"
#include "Math/Math.h"
namespace Seele namespace Seele
{ {
@@ -129,7 +130,7 @@ struct SePushConstantRange
}; };
struct VertexElement struct VertexElement
{ {
uint8 streamIndex; uint8 binding;
uint8 offset; uint8 offset;
SeFormat vertexFormat; SeFormat vertexFormat;
uint8 attributeIndex; uint8 attributeIndex;
@@ -188,56 +189,116 @@ struct ColorBlendState
} blendAttachments[16]; } blendAttachments[16];
float blendConstants[4]; float blendConstants[4];
}; };
} // namespace Gfx
DECLARE_NAME_REF(Gfx, VertexDeclaration) DECLARE_REF(VertexDeclaration)
DECLARE_NAME_REF(Gfx, VertexShader) DECLARE_REF(VertexShader)
DECLARE_NAME_REF(Gfx, ControlShader) DECLARE_REF(FragmentShader)
DECLARE_NAME_REF(Gfx, EvaluationShader) DECLARE_REF(TaskShader)
DECLARE_NAME_REF(Gfx, GeometryShader) DECLARE_REF(MeshShader)
DECLARE_NAME_REF(Gfx, FragmentShader) DECLARE_REF(ComputeShader)
DECLARE_NAME_REF(Gfx, ComputeShader) DECLARE_REF(PipelineLayout)
DECLARE_NAME_REF(Gfx, PipelineLayout) DECLARE_REF(RenderPass)
DECLARE_NAME_REF(Gfx, RenderPass) struct LegacyPipelineCreateInfo
struct GraphicsPipelineCreateInfo
{ {
Gfx::PVertexDeclaration vertexDeclaration; PVertexDeclaration vertexDeclaration;
Gfx::PVertexShader vertexShader; SePrimitiveTopology topology;
Gfx::PControlShader controlShader; PVertexShader vertexShader;
Gfx::PEvaluationShader evalShader; PFragmentShader fragmentShader;
Gfx::PGeometryShader geometryShader; PRenderPass renderPass;
Gfx::PFragmentShader fragmentShader; PPipelineLayout pipelineLayout;
Gfx::PRenderPass renderPass; MultisampleState multisampleState;
Gfx::PPipelineLayout pipelineLayout; RasterizationState rasterizationState;
Gfx::SePrimitiveTopology topology; DepthStencilState depthStencilState;
Gfx::RasterizationState rasterizationState; ColorBlendState colorBlend;
Gfx::DepthStencilState depthStencilState; LegacyPipelineCreateInfo()
Gfx::MultisampleState multisampleState; : topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
Gfx::ColorBlendState colorBlend; , rasterizationState(RasterizationState{
GraphicsPipelineCreateInfo() .polygonMode = Gfx::SE_POLYGON_MODE_FILL,
{ .cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
std::memset((void*)this, 0, sizeof(*this)); .frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; })
rasterizationState.cullMode = Gfx::SE_CULL_MODE_BACK_BIT; , depthStencilState(DepthStencilState{
rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL; .depthTestEnable = true,
rasterizationState.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE; .depthWriteEnable = true,
depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; .stencilTestEnable = false,
depthStencilState.minDepthBounds = 0.0f; .depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
depthStencilState.maxDepthBounds = 1.0f; .minDepthBounds = 0.0f,
depthStencilState.stencilTestEnable = false; .maxDepthBounds = 1.0f,
depthStencilState.depthWriteEnable = true; })
depthStencilState.depthTestEnable = true; , multisampleState(MultisampleState{
multisampleState.samples = 1; .samples = 1,
colorBlend.attachmentCount = 0; })
colorBlend.logicOpEnable = false; , colorBlend(ColorBlendState{
colorBlend.blendConstants[0] = 1.0f; .logicOpEnable = false,
colorBlend.blendConstants[1] = 1.0f; .attachmentCount = 0,
colorBlend.blendConstants[2] = 1.0f; .blendAttachments = {
colorBlend.blendConstants[3] = 1.0f; ColorBlendState::BlendAttachment{
colorBlend.blendAttachments[0].colorWriteMask = .colorWriteMask =
Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_R_BIT |
Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT |
Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT |
Gfx::SE_COLOR_COMPONENT_A_BIT; Gfx::SE_COLOR_COMPONENT_A_BIT,
}
},
.blendConstants = {
1.0f,
1.0f,
1.0f,
1.0f,
},
})
{
}
};
struct MeshPipelineCreateInfo
{
PTaskShader taskShader;
PMeshShader meshShader;
PFragmentShader fragmentShader;
PRenderPass renderPass;
PPipelineLayout pipelineLayout;
MultisampleState multisampleState;
RasterizationState rasterizationState;
DepthStencilState depthStencilState;
ColorBlendState colorBlend;
MeshPipelineCreateInfo()
: rasterizationState(RasterizationState{
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
})
, depthStencilState(DepthStencilState{
.depthTestEnable = true,
.depthWriteEnable = true,
.stencilTestEnable = false,
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
.minDepthBounds = 0.0f,
.maxDepthBounds = 1.0f,
})
, multisampleState(MultisampleState{
.samples = 1,
})
, colorBlend(ColorBlendState{
.logicOpEnable = false,
.attachmentCount = 0,
.blendAttachments = {
ColorBlendState::BlendAttachment{
.colorWriteMask =
Gfx::SE_COLOR_COMPONENT_R_BIT |
Gfx::SE_COLOR_COMPONENT_G_BIT |
Gfx::SE_COLOR_COMPONENT_B_BIT |
Gfx::SE_COLOR_COMPONENT_A_BIT,
}
},
.blendConstants = {
1.0f,
1.0f,
1.0f,
1.0f,
},
})
{
} }
}; };
struct ComputePipelineCreateInfo struct ComputePipelineCreateInfo
@@ -249,4 +310,5 @@ struct ComputePipelineCreateInfo
std::memset((void*)this, 0, sizeof(*this)); std::memset((void*)this, 0, sizeof(*this));
} }
}; };
} // namespace Gfx
} // namespace Seele } // namespace Seele
+1 -4
View File
@@ -1,12 +1,9 @@
#include "Mesh.h" #include "Mesh.h"
#include "VertexShaderInput.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
using namespace Seele; using namespace Seele;
Mesh::Mesh(PVertexShaderInput vertexInput, Gfx::PIndexBuffer indexBuffer) Mesh::Mesh()
: vertexInput(vertexInput)
, indexBuffer(indexBuffer)
{ {
} }
-1
View File
@@ -1,5 +1,4 @@
#pragma once #pragma once
#include "GraphicsResources.h"
#include "Asset/MaterialInstanceAsset.h" #include "Asset/MaterialInstanceAsset.h"
#include "VertexData.h" #include "VertexData.h"
+1 -8
View File
@@ -7,6 +7,7 @@
#include "Math/Vector.h" #include "Math/Vector.h"
#include "RenderGraph.h" #include "RenderGraph.h"
#include "Material/MaterialInstance.h" #include "Material/MaterialInstance.h"
#include "Graphics/Descriptor.h"
using namespace Seele; using namespace Seele;
@@ -59,14 +60,6 @@ BasePass::~BasePass()
{ {
} }
void BasePass::readScene()
{
Array<InstanceData> instances;
scene->view<Component::Transform, Component::Mesh>([]
(const Component::Transform& transform, const Component::Mesh& mesh) {
});
}
void BasePass::beginFrame(const Component::Camera& cam) void BasePass::beginFrame(const Component::Camera& cam)
{ {
BulkResourceData uniformUpdate; BulkResourceData uniformUpdate;
@@ -10,7 +10,6 @@ class BasePass : public RenderPass
public: public:
BasePass(Gfx::PGraphics graphics, PScene scene); BasePass(Gfx::PGraphics graphics, PScene scene);
virtual ~BasePass(); virtual ~BasePass();
virtual void readScene() override;
virtual void beginFrame(const Component::Camera& cam) override; virtual void beginFrame(const Component::Camera& cam) override;
virtual void render() override; virtual void render() override;
virtual void endFrame() override; virtual void endFrame() override;
@@ -1,5 +1,6 @@
#include "DebugPass.h" #include "DebugPass.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/RenderTarget.h"
using namespace Seele; using namespace Seele;
@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "RenderPass.h" #include "RenderPass.h"
#include "Graphics/GraphicsResources.h"
#include "Scene/Scene.h" #include "Scene/Scene.h"
#include "Graphics/DebugVertex.h" #include "Graphics/DebugVertex.h"
@@ -68,7 +68,7 @@ void DepthPrepass::render()
// ViewData => global, static // ViewData => global, static
// Material => per material // Material => per material
// VertexData => per meshtype // VertexData => per meshtype
// SceneData => per topology // SceneData => per material instance
Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender"); Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender");
Gfx::PPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout); Gfx::PPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout);
layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout());
@@ -7,8 +7,8 @@
using namespace Seele; using namespace Seele;
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics) LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics) : RenderPass(graphics, scene)
{ {
} }
@@ -153,7 +153,7 @@ void LightCullingPass::publishOutputs()
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0"; createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
cullingShader = graphics->createComputeShader(createInfo); cullingShader = graphics->createComputeShader(createInfo);
ComputePipelineCreateInfo pipelineInfo; Gfx::ComputePipelineCreateInfo pipelineInfo;
pipelineInfo.computeShader = cullingShader; pipelineInfo.computeShader = cullingShader;
pipelineInfo.pipelineLayout = cullingLayout; pipelineInfo.pipelineLayout = cullingLayout;
cullingPipeline = graphics->createComputePipeline(pipelineInfo); cullingPipeline = graphics->createComputePipeline(pipelineInfo);
@@ -243,7 +243,7 @@ void LightCullingPass::setupFrustums()
createInfo.defines["INDEX_VIEW_PARAMS"] = "0"; createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
frustumShader = graphics->createComputeShader(createInfo); frustumShader = graphics->createComputeShader(createInfo);
ComputePipelineCreateInfo pipelineInfo; Gfx::ComputePipelineCreateInfo pipelineInfo;
pipelineInfo.computeShader = frustumShader; pipelineInfo.computeShader = frustumShader;
pipelineInfo.pipelineLayout = frustumLayout; pipelineInfo.pipelineLayout = frustumLayout;
frustumPipeline = graphics->createComputePipeline(pipelineInfo); frustumPipeline = graphics->createComputePipeline(pipelineInfo);
@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "RenderPass.h" #include "RenderPass.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/Resources.h"
#include "Scene/Scene.h" #include "Scene/Scene.h"
namespace Seele namespace Seele
@@ -8,14 +8,10 @@ namespace Seele
DECLARE_REF(CameraActor) DECLARE_REF(CameraActor)
DECLARE_REF(Scene) DECLARE_REF(Scene)
DECLARE_REF(Viewport) DECLARE_REF(Viewport)
struct LightCullingPassData
{
LightEnv lightEnv;
};
class LightCullingPass : public RenderPass class LightCullingPass : public RenderPass
{ {
public: public:
LightCullingPass(Gfx::PGraphics graphics); LightCullingPass(Gfx::PGraphics graphics, PScene scene);
virtual ~LightCullingPass(); virtual ~LightCullingPass();
virtual void beginFrame(const Component::Camera& cam) override; virtual void beginFrame(const Component::Camera& cam) override;
virtual void render() override; virtual void render() override;
@@ -1,6 +1,8 @@
#pragma once #pragma once
#include "MinimalEngine.h" #include "MinimalEngine.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/RenderTarget.h"
#include "Graphics/Texture.h"
#include "Graphics/Buffer.h"
namespace Seele namespace Seele
{ {
@@ -3,7 +3,6 @@
#include "Math/Math.h" #include "Math/Math.h"
#include "RenderGraphResources.h" #include "RenderGraphResources.h"
#include "Component/Camera.h" #include "Component/Camera.h"
#include "Graphics/TopologyData.h"
#include "Scene/Scene.h" #include "Scene/Scene.h"
#include "Material/MaterialInstance.h" #include "Material/MaterialInstance.h"
#include "Graphics/VertexData.h" #include "Graphics/VertexData.h"
@@ -42,19 +41,6 @@ protected:
Vector2 screenDimensions; Vector2 screenDimensions;
Vector2 pad0; Vector2 pad0;
} viewParams; } viewParams;
struct DrawListId
{
DrawListId(PMaterialInstance mat, PVertexData vertex)
{
id = mat->getBaseMaterial()->getName();
}
std::strong_ordering operator<=>(const DrawListId& other) const
{
return id <=> other.id;
}
std::string id;
};
Map<DrawListId, DrawListInfo> drawList;
PRenderGraphResources resources; PRenderGraphResources resources;
Gfx::PRenderPass renderPass; Gfx::PRenderPass renderPass;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
@@ -1,11 +1,18 @@
#include "SkyboxRenderPass.h" #include "SkyboxRenderPass.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Asset/AssetRegistry.h"
using namespace Seele; using namespace Seele;
SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics) SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics) : RenderPass(graphics, scene)
{ {
skybox = Seele::Component::Skybox{
.day = AssetRegistry::findTexture("FS000_Day_01")->getTexture().cast<Gfx::TextureCube>(),
.night = AssetRegistry::findTexture("FS000_Night_01")->getTexture().cast<Gfx::TextureCube>(),
.fogColor = Vector(0.2, 0.1, 0.6),
.blendFactor = 0,
};
Array<Vector> vertices = { Array<Vector> vertices = {
// Back // Back
Vector(-512, -512, 512), Vector(-512, -512, 512),
@@ -91,8 +98,8 @@ void SkyboxRenderPass::beginFrame(const Component::Camera& cam)
descriptorLayout->reset(); descriptorLayout->reset();
descriptorSet = descriptorLayout->allocateDescriptorSet(); descriptorSet = descriptorLayout->allocateDescriptorSet();
descriptorSet->updateBuffer(0, viewParamsBuffer); descriptorSet->updateBuffer(0, viewParamsBuffer);
descriptorSet->updateTexture(1, passData.skybox.day); descriptorSet->updateTexture(1, skybox.day);
descriptorSet->updateTexture(2, passData.skybox.night); descriptorSet->updateTexture(2, skybox.night);
descriptorSet->updateSampler(3, skyboxSampler); descriptorSet->updateSampler(3, skyboxSampler);
descriptorSet->writeChanges(); descriptorSet->writeChanges();
} }
@@ -104,9 +111,9 @@ void SkyboxRenderPass::render()
renderCommand->setViewport(viewport); renderCommand->setViewport(viewport);
renderCommand->bindPipeline(pipeline); renderCommand->bindPipeline(pipeline);
renderCommand->bindDescriptor(descriptorSet); renderCommand->bindDescriptor(descriptorSet);
renderCommand->bindVertexBuffer({ VertexInputStream(0, 0, cubeBuffer) }); renderCommand->bindVertexBuffer({ cubeBuffer });
renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vector), &passData.skybox.fogColor); renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vector), &skybox.fogColor);
renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, sizeof(Vector), sizeof(float), &passData.skybox.blendFactor); renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, sizeof(Vector), sizeof(float), &skybox.blendFactor);
renderCommand->draw(36, 1, 0, 0); renderCommand->draw(36, 1, 0, 0);
graphics->executeCommands(Array{ renderCommand }); graphics->executeCommands(Array{ renderCommand });
graphics->endRenderPass(); graphics->endRenderPass();
@@ -170,7 +177,7 @@ void SkyboxRenderPass::createRenderPass()
Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({ Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({
Gfx::VertexElement { Gfx::VertexElement {
.streamIndex = 0, .binding = 0,
.offset = 0, .offset = 0,
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 0, .attributeIndex = 0,
@@ -178,7 +185,7 @@ void SkyboxRenderPass::createRenderPass()
} }
}); });
GraphicsPipelineCreateInfo gfxInfo; Gfx::LegacyPipelineCreateInfo gfxInfo;
gfxInfo.vertexDeclaration = vertexDecl; gfxInfo.vertexDeclaration = vertexDecl;
gfxInfo.vertexShader = vertexShader; gfxInfo.vertexShader = vertexShader;
gfxInfo.fragmentShader = fragmentShader; gfxInfo.fragmentShader = fragmentShader;
@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "RenderPass.h" #include "RenderPass.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/Resources.h"
#include "Component/Skybox.h" #include "Component/Skybox.h"
namespace Seele namespace Seele
@@ -11,7 +11,7 @@ DECLARE_REF(Viewport)
class SkyboxRenderPass : public RenderPass class SkyboxRenderPass : public RenderPass
{ {
public: public:
SkyboxRenderPass(Gfx::PGraphics graphics); SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene);
virtual ~SkyboxRenderPass(); virtual ~SkyboxRenderPass();
virtual void beginFrame(const Component::Camera& cam) override; virtual void beginFrame(const Component::Camera& cam) override;
virtual void render() override; virtual void render() override;
@@ -26,6 +26,7 @@ private:
Gfx::PPipelineLayout pipelineLayout; Gfx::PPipelineLayout pipelineLayout;
Gfx::PGraphicsPipeline pipeline; Gfx::PGraphicsPipeline pipeline;
Gfx::PSamplerState skyboxSampler; Gfx::PSamplerState skyboxSampler;
Component::Skybox skybox;
}; };
DEFINE_REF(SkyboxRenderPass) DEFINE_REF(SkyboxRenderPass)
} // namespace Seele } // namespace Seele
+9 -9
View File
@@ -1,12 +1,12 @@
#include "TextPass.h" #include "TextPass.h"
#include "RenderGraph.h" #include "RenderGraph.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/VertexShaderInput.h" #include "Graphics/RenderTarget.h"
using namespace Seele; using namespace Seele;
TextPass::TextPass(Gfx::PGraphics graphics) TextPass::TextPass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics) : RenderPass(graphics, scene)
{ {
} }
@@ -17,7 +17,7 @@ TextPass::~TextPass()
void TextPass::beginFrame(const Component::Camera&) void TextPass::beginFrame(const Component::Camera&)
{ {
for(TextRender& render : passData.texts) for(TextRender& render : texts)
{ {
FontData& fd = getFontData(render.font); FontData& fd = getFontData(render.font);
TextResources& res = textResources[render.font].add(); TextResources& res = textResources[render.font].add();
@@ -82,7 +82,7 @@ void TextPass::render()
for(const auto& resource : res) for(const auto& resource : res)
{ {
command->bindDescriptor({generalSet, resource.textureArraySet}); command->bindDescriptor({generalSet, resource.textureArraySet});
command->bindVertexBuffer({VertexInputStream(0, 0, resource.vertexBuffer)}); command->bindVertexBuffer({resource.vertexBuffer});
command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData); command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData);
command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0); command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
@@ -121,7 +121,7 @@ void TextPass::createRenderPass()
fragmentShader = graphics->createFragmentShader(createInfo); fragmentShader = graphics->createFragmentShader(createInfo);
Array<Gfx::VertexElement> elements; Array<Gfx::VertexElement> elements;
elements.add({ elements.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(GlyphInstanceData, position), .offset = offsetof(GlyphInstanceData, position),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 0, .attributeIndex = 0,
@@ -129,7 +129,7 @@ void TextPass::createRenderPass()
.bInstanced = 1 .bInstanced = 1
}); });
elements.add({ elements.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(GlyphInstanceData, widthHeight), .offset = offsetof(GlyphInstanceData, widthHeight),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 1, .attributeIndex = 1,
@@ -137,7 +137,7 @@ void TextPass::createRenderPass()
.bInstanced = 1 .bInstanced = 1
}); });
elements.add({ elements.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(GlyphInstanceData, glyphIndex), .offset = offsetof(GlyphInstanceData, glyphIndex),
.vertexFormat = Gfx::SE_FORMAT_R32_UINT, .vertexFormat = Gfx::SE_FORMAT_R32_UINT,
.attributeIndex = 2, .attributeIndex = 2,
@@ -187,7 +187,7 @@ void TextPass::createRenderPass()
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment); Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
renderPass = graphics->createRenderPass(layout, viewport); renderPass = graphics->createRenderPass(layout, viewport);
GraphicsPipelineCreateInfo pipelineInfo; Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexDeclaration = declaration; pipelineInfo.vertexDeclaration = declaration;
pipelineInfo.vertexShader = vertexShader; pipelineInfo.vertexShader = vertexShader;
pipelineInfo.fragmentShader = fragmentShader; pipelineInfo.fragmentShader = fragmentShader;
+4 -3
View File
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "RenderPass.h" #include "RenderPass.h"
#include "UI/RenderHierarchy.h" #include "UI/RenderHierarchy.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/Resources.h"
#include "Asset/FontAsset.h" #include "Asset/FontAsset.h"
namespace Seele namespace Seele
@@ -20,7 +20,7 @@ struct TextRender
class TextPass : public RenderPass class TextPass : public RenderPass
{ {
public: public:
TextPass(Gfx::PGraphics graphics); TextPass(Gfx::PGraphics graphics, PScene scene);
virtual ~TextPass(); virtual ~TextPass();
virtual void beginFrame(const Component::Camera& cam) override; virtual void beginFrame(const Component::Camera& cam) override;
virtual void render() override; virtual void render() override;
@@ -60,7 +60,7 @@ private:
Gfx::PDescriptorSet textureArraySet; Gfx::PDescriptorSet textureArraySet;
TextData textData; TextData textData;
}; };
std::map<PFontAsset, Array<TextResources>> textResources; Map<PFontAsset, Array<TextResources>> textResources;
Gfx::PRenderTargetAttachment renderTarget; Gfx::PRenderTargetAttachment renderTarget;
Gfx::PRenderTargetAttachment depthAttachment; Gfx::PRenderTargetAttachment depthAttachment;
@@ -78,6 +78,7 @@ private:
Gfx::PFragmentShader fragmentShader; Gfx::PFragmentShader fragmentShader;
Gfx::PPipelineLayout pipelineLayout; Gfx::PPipelineLayout pipelineLayout;
Gfx::PGraphicsPipeline pipeline; Gfx::PGraphicsPipeline pipeline;
Array<TextRender> texts;
}; };
DEFINE_REF(TextPass); DEFINE_REF(TextPass);
} // namespace Seele } // namespace Seele
+17 -15
View File
@@ -1,11 +1,12 @@
#include "UIPass.h" #include "UIPass.h"
#include "RenderGraph.h" #include "RenderGraph.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/RenderTarget.h"
using namespace Seele; using namespace Seele;
UIPass::UIPass(Gfx::PGraphics graphics) UIPass::UIPass(Gfx::PGraphics graphics, PScene scene)
: RenderPass(graphics) : RenderPass(graphics, scene)
{ {
} }
@@ -18,20 +19,20 @@ void UIPass::beginFrame(const Component::Camera&)
{ {
VertexBufferCreateInfo info = { VertexBufferCreateInfo info = {
.resourceData = { .resourceData = {
.size = (uint32)(sizeof(UI::RenderElementStyle) * passData.renderElements.size()), .size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()),
.data = (uint8*)passData.renderElements.data() .data = (uint8*)renderElements.data()
}, },
.vertexSize = sizeof(UI::RenderElementStyle), .vertexSize = sizeof(UI::RenderElementStyle),
.numVertices = (uint32)passData.renderElements.size(), .numVertices = (uint32)renderElements.size(),
}; };
elementBuffer = graphics->createVertexBuffer(info); elementBuffer = graphics->createVertexBuffer(info);
uint32 numTextures = static_cast<uint32>(passData.usedTextures.size()); uint32 numTextures = static_cast<uint32>(usedTextures.size());
numTexturesBuffer->updateContents({ numTexturesBuffer->updateContents({
.size = sizeof(uint32), .size = sizeof(uint32),
.data = (uint8*)&numTextures, .data = (uint8*)&numTextures,
}); });
descriptorSet->updateBuffer(2, numTexturesBuffer); descriptorSet->updateBuffer(2, numTexturesBuffer);
descriptorSet->updateTextureArray(3, passData.usedTextures); descriptorSet->updateTextureArray(3, usedTextures);
descriptorSet->writeChanges(); descriptorSet->writeChanges();
//co_return; //co_return;
} }
@@ -42,11 +43,12 @@ void UIPass::render()
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand"); Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
command->setViewport(viewport); command->setViewport(viewport);
command->bindPipeline(pipeline); command->bindPipeline(pipeline);
command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)}); command->bindVertexBuffer({elementBuffer});
command->bindDescriptor(descriptorSet); command->bindDescriptor(descriptorSet);
command->draw(4, static_cast<uint32>(passData.renderElements.size()), 0, 0); command->draw(4, static_cast<uint32>(renderElements.size()), 0, 0);
graphics->executeCommands(Array<Gfx::PRenderCommand>({command})); graphics->executeCommands(Array<Gfx::PRenderCommand>({command}));
graphics->endRenderPass(); graphics->endRenderPass();
//co_return; //co_return;
} }
@@ -96,7 +98,7 @@ void UIPass::createRenderPass()
fragmentShader = graphics->createFragmentShader(createInfo); fragmentShader = graphics->createFragmentShader(createInfo);
Array<Gfx::VertexElement> decl; Array<Gfx::VertexElement> decl;
decl.add({ decl.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(UI::RenderElementStyle, position), .offset = offsetof(UI::RenderElementStyle, position),
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 0, .attributeIndex = 0,
@@ -104,7 +106,7 @@ void UIPass::createRenderPass()
.bInstanced = 1 .bInstanced = 1
}); });
decl.add({ decl.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(UI::RenderElementStyle, backgroundImageIndex), .offset = offsetof(UI::RenderElementStyle, backgroundImageIndex),
.vertexFormat = Gfx::SE_FORMAT_R32_UINT, .vertexFormat = Gfx::SE_FORMAT_R32_UINT,
.attributeIndex = 1, .attributeIndex = 1,
@@ -112,7 +114,7 @@ void UIPass::createRenderPass()
.bInstanced = 1 .bInstanced = 1
}); });
decl.add({ decl.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(UI::RenderElementStyle, backgroundColor), .offset = offsetof(UI::RenderElementStyle, backgroundColor),
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 2, .attributeIndex = 2,
@@ -120,7 +122,7 @@ void UIPass::createRenderPass()
.bInstanced = 1 .bInstanced = 1
}); });
decl.add({ decl.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(UI::RenderElementStyle, opacity), .offset = offsetof(UI::RenderElementStyle, opacity),
.vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT, .vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT,
.attributeIndex = 3, .attributeIndex = 3,
@@ -128,7 +130,7 @@ void UIPass::createRenderPass()
.bInstanced = 1 .bInstanced = 1
}); });
decl.add({ decl.add({
.streamIndex = 0, .binding = 0,
.offset = offsetof(UI::RenderElementStyle, dimensions), .offset = offsetof(UI::RenderElementStyle, dimensions),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT, .vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 4, .attributeIndex = 4,
@@ -177,7 +179,7 @@ void UIPass::createRenderPass()
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment); Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
renderPass = graphics->createRenderPass(layout, viewport); renderPass = graphics->createRenderPass(layout, viewport);
GraphicsPipelineCreateInfo pipelineInfo; Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexDeclaration = declaration; pipelineInfo.vertexDeclaration = declaration;
pipelineInfo.vertexShader = vertexShader; pipelineInfo.vertexShader = vertexShader;
pipelineInfo.fragmentShader = fragmentShader; pipelineInfo.fragmentShader = fragmentShader;
+6 -8
View File
@@ -1,21 +1,16 @@
#pragma once #pragma once
#include "RenderPass.h" #include "RenderPass.h"
#include "UI/RenderHierarchy.h" #include "UI/RenderHierarchy.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/Resources.h"
namespace Seele namespace Seele
{ {
DECLARE_NAME_REF(Gfx, Texture2D) DECLARE_NAME_REF(Gfx, Texture2D)
DECLARE_NAME_REF(Gfx, RenderTargetAttachment) DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
struct UIPassData class UIPass : public RenderPass
{
Array<UI::RenderElementStyle> renderElements;
Array<Gfx::PTexture> usedTextures;
};
class UIPass : public RenderPass<UIPassData>
{ {
public: public:
UIPass(Gfx::PGraphics graphics); UIPass(Gfx::PGraphics graphics, PScene scene);
virtual ~UIPass(); virtual ~UIPass();
virtual void beginFrame(const Component::Camera& cam) override; virtual void beginFrame(const Component::Camera& cam) override;
virtual void render() override; virtual void render() override;
@@ -39,6 +34,9 @@ private:
Gfx::PFragmentShader fragmentShader; Gfx::PFragmentShader fragmentShader;
Gfx::PPipelineLayout pipelineLayout; Gfx::PPipelineLayout pipelineLayout;
Gfx::PGraphicsPipeline pipeline; Gfx::PGraphicsPipeline pipeline;
Array<UI::RenderElementStyle> renderElements;
Array<Gfx::PTexture> usedTextures;
}; };
DEFINE_REF(UIPass); DEFINE_REF(UIPass);
} // namespace Seele } // namespace Seele
+81
View File
@@ -0,0 +1,81 @@
#include "RenderTarget.h"
using namespace Seele;
using namespace Seele::Gfx;
RenderTargetLayout::RenderTargetLayout()
: inputAttachments()
, colorAttachments()
, depthAttachment()
{
}
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment)
: inputAttachments()
, colorAttachments()
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
}
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment)
: inputAttachments()
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
colorAttachments.add(colorAttachment);
}
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
: inputAttachments()
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
}
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
: inputAttachments(inputAttachments)
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
, width(depthAttachment->getTexture()->getSizeX())
, height(depthAttachment->getTexture()->getSizeY())
{
}
Window::Window(const WindowCreateInfo& createInfo)
: windowState(createInfo)
{
}
Window::~Window()
{
}
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
: sizeX(viewportInfo.dimensions.size.x)
, sizeY(viewportInfo.dimensions.size.y)
, offsetX(viewportInfo.dimensions.offset.x)
, offsetY(viewportInfo.dimensions.offset.y)
, fieldOfView(viewportInfo.fieldOfView)
, owner(owner)
{
}
Viewport::~Viewport()
{
}
Matrix4 Viewport::getProjectionMatrix() const
{
if (fieldOfView > 0.0f)
{
return glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
}
else
{
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
}
}
+194
View File
@@ -0,0 +1,194 @@
#pragma once
#include "Resources.h"
#include "Texture.h"
namespace Seele
{
namespace Gfx
{
class Window
{
public:
Window(const WindowCreateInfo &createInfo);
virtual ~Window();
virtual void beginFrame() = 0;
virtual void endFrame() = 0;
virtual void onWindowCloseEvent() = 0;
virtual PTexture2D getBackBuffer() const = 0;
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) = 0;
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) = 0;
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) = 0;
virtual void setScrollCallback(std::function<void(double, double)> callback) = 0;
virtual void setFileCallback(std::function<void(int, const char**)> callback) = 0;
virtual void setCloseCallback(std::function<void()> callback) = 0;
SeFormat getSwapchainFormat() const
{
return windowState.pixelFormat;
}
SeSampleCountFlags getNumSamples() const
{
return windowState.numSamples;
}
uint32 getSizeX() const
{
return windowState.width;
}
uint32 getSizeY() const
{
return windowState.height;
}
protected:
WindowCreateInfo windowState;
};
DEFINE_REF(Window)
class Viewport
{
public:
Viewport(PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY) = 0;
virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0;
constexpr PWindow getOwner() const {return owner;}
constexpr uint32 getSizeX() const {return sizeX;}
constexpr uint32 getSizeY() const {return sizeY;}
constexpr uint32 getOffsetX() const {return offsetX;}
constexpr uint32 getOffsetY() const {return offsetY;}
Matrix4 getProjectionMatrix() const;
protected:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
float fieldOfView;
PWindow owner;
};
DEFINE_REF(Viewport)
class RenderTargetAttachment
{
public:
RenderTargetAttachment(PTexture2D texture,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
: loadOp(loadOp)
, storeOp(storeOp)
, stencilLoadOp(stencilLoadOp)
, stencilStoreOp(stencilStoreOp)
, texture(texture)
, clear()
, componentFlags(0)
{
}
virtual ~RenderTargetAttachment()
{
}
virtual PTexture2D getTexture()
{
return texture;
}
virtual SeFormat getFormat() const
{
return texture->getFormat();
}
virtual SeSampleCountFlags getNumSamples() const
{
return texture->getNumSamples();
}
virtual uint32 getSizeX() const
{
return texture->getSizeX();
}
virtual uint32 getSizeY() const
{
return texture->getSizeY();
}
inline SeAttachmentLoadOp getLoadOp() const { return loadOp; }
inline SeAttachmentStoreOp getStoreOp() const { return storeOp; }
inline SeAttachmentLoadOp getStencilLoadOp() const { return stencilLoadOp; }
inline SeAttachmentStoreOp getStencilStoreOp() const { return stencilStoreOp; }
SeClearValue clear;
SeColorComponentFlags componentFlags;
SeAttachmentLoadOp loadOp;
SeAttachmentStoreOp storeOp;
SeAttachmentLoadOp stencilLoadOp;
SeAttachmentStoreOp stencilStoreOp;
protected:
PTexture2D texture;
};
DEFINE_REF(RenderTargetAttachment)
class SwapchainAttachment : public RenderTargetAttachment
{
public:
SwapchainAttachment(PWindow owner,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
: RenderTargetAttachment(nullptr, loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner)
{
clear.color.float32[0] = 0.0f;
clear.color.float32[1] = 0.0f;
clear.color.float32[2] = 0.0f;
clear.color.float32[3] = 1.0f;
componentFlags = SE_COLOR_COMPONENT_R_BIT | SE_COLOR_COMPONENT_G_BIT | SE_COLOR_COMPONENT_B_BIT | SE_COLOR_COMPONENT_A_BIT;
}
virtual PTexture2D getTexture() override
{
return owner->getBackBuffer();
}
virtual SeFormat getFormat() const override
{
return owner->getSwapchainFormat();
}
virtual SeSampleCountFlags getNumSamples() const override
{
return owner->getNumSamples();
}
virtual uint32 getSizeX() const
{
return owner->getSizeX();
}
virtual uint32 getSizeY() const
{
return owner->getSizeY();
}
private:
PWindow owner;
};
DEFINE_REF(SwapchainAttachment)
class RenderTargetLayout
{
public:
RenderTargetLayout();
RenderTargetLayout(PRenderTargetAttachment depthAttachment);
RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment);
RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet);
RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment);
Array<PRenderTargetAttachment> inputAttachments;
Array<PRenderTargetAttachment> colorAttachments;
PRenderTargetAttachment depthAttachment;
uint32 width;
uint32 height;
};
DEFINE_REF(RenderTargetLayout)
class RenderPass
{
public:
RenderPass(PRenderTargetLayout layout) : layout(layout) {}
virtual ~RenderPass() {}
inline PRenderTargetLayout getLayout() const { return layout; }
protected:
PRenderTargetLayout layout;
};
DEFINE_REF(RenderPass)
}
}
+77
View File
@@ -0,0 +1,77 @@
#include "GraphicsResources.h"
#include "Graphics.h"
#include "RenderPass/DepthPrepass.h"
#include "RenderPass/BasePass.h"
#include "Material/Material.h"
QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType)
: currentOwner(startQueueType)
, mapping(mapping)
{
}
QueueOwnedResource::~QueueOwnedResource()
{
}
void QueueOwnedResource::transferOwnership(QueueType newOwner)
{
if(mapping.needsTransfer(currentOwner, newOwner))
{
executeOwnershipBarrier(newOwner);
}
currentOwner = newOwner;
}
void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage)
{
// maybe add some checks
executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VertexDeclaration::VertexDeclaration()
{
}
VertexDeclaration::~VertexDeclaration()
{
}
static std::mutex vertexDeclarationLock;
static Map<uint32, PVertexDeclaration> vertexDeclarationCache;
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList)
{
std::scoped_lock lock(vertexDeclarationLock);
uint32 key = CRC::Calculate(&elementList, sizeof(VertexElement) * elementList.size(), CRC::CRC_32());
auto found = vertexDeclarationCache[key];
if(found == nullptr)
{
return found;
}
PVertexDeclaration newDeclaration = graphics->createVertexDeclaration(elementList);
vertexDeclarationCache[key] = newDeclaration;
return newDeclaration;
}
RenderCommand::RenderCommand()
{
}
RenderCommand::~RenderCommand()
{
}
ComputeCommand::ComputeCommand()
{
}
ComputeCommand::~ComputeCommand()
{
}
+150
View File
@@ -0,0 +1,150 @@
#pragma once
#include "Math/Math.h"
#include "Enums.h"
#include "Containers/Array.h"
#include "Containers/List.h"
#include "Initializer.h"
#include "Buffer.h"
#include "CRC.h"
#include <functional>
#ifndef ENABLE_VALIDATION
#define ENABLE_VALIDATION 0
#endif
namespace Seele
{
DECLARE_REF(Material)
namespace Gfx
{
DECLARE_REF(DescriptorSet)
DECLARE_REF(Graphics)
DECLARE_REF(VertexBuffer)
DECLARE_REF(IndexBuffer)
class SamplerState
{
public:
virtual ~SamplerState()
{
}
};
DEFINE_REF(SamplerState)
struct QueueFamilyMapping
{
uint32 graphicsFamily;
uint32 computeFamily;
uint32 transferFamily;
uint32 dedicatedTransferFamily;
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const
{
switch (type)
{
case Gfx::QueueType::GRAPHICS:
return graphicsFamily;
case Gfx::QueueType::COMPUTE:
return computeFamily;
case Gfx::QueueType::TRANSFER:
return transferFamily;
case Gfx::QueueType::DEDICATED_TRANSFER:
return dedicatedTransferFamily;
default:
return 0x7fff;
}
}
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const
{
uint32 srcIndex = getQueueTypeFamilyIndex(src);
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
return srcIndex != dstIndex;
}
};
class QueueOwnedResource
{
public:
QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~QueueOwnedResource();
//Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner);
void pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage);
protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Gfx::QueueType currentOwner;
QueueFamilyMapping mapping;
};
DEFINE_REF(QueueOwnedResource)
class VertexDeclaration
{
public:
VertexDeclaration();
~VertexDeclaration();
static PVertexDeclaration createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList);
private:
};
DEFINE_REF(VertexDeclaration)
class GraphicsPipeline
{
public:
GraphicsPipeline(PPipelineLayout layout) : layout(layout) {}
virtual ~GraphicsPipeline(){}
PPipelineLayout getPipelineLayout() const { return layout; }
protected:
PPipelineLayout layout;
};
DEFINE_REF(GraphicsPipeline)
class ComputePipeline
{
public:
ComputePipeline(PPipelineLayout layout) : layout(layout) {}
virtual ~ComputePipeline(){}
PPipelineLayout getPipelineLayout() const { return layout; }
protected:
PPipelineLayout layout;
};
DEFINE_REF(ComputePipeline)
DECLARE_REF(Viewport)
class RenderCommand
{
public:
RenderCommand();
virtual ~RenderCommand();
virtual bool isReady() = 0;
virtual void setViewport(Gfx::PViewport viewport) = 0;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
virtual void bindVertexBuffer(const Array<PVertexBuffer>& buffer) = 0;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0;
virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ);
std::string name;
};
DEFINE_REF(RenderCommand)
class ComputeCommand
{
public:
ComputeCommand();
virtual ~ComputeCommand();
virtual bool isReady() = 0;
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
std::string name;
};
DEFINE_REF(ComputeCommand)
} // namespace Gfx
} // namespace Seele
+92
View File
@@ -0,0 +1,92 @@
#include "Shader.h"
using namespace Seele;
using namespace Seele::Gfx;
std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type)
{
switch (type)
{
case Gfx::RenderPassType::DepthPrepass:
return "DepthPrepass";
case Gfx::RenderPassType::BasePass:
return "ForwardPlus";
default:
return "";
}
}
void modifyRenderPassMacros(Gfx::RenderPassType type, Map<const char*, const char*>& defines)
{
switch (type)
{
case Gfx::RenderPassType::DepthPrepass:
DepthPrepass::modifyRenderPassMacros(defines);
break;
case Gfx::RenderPassType::BasePass:
BasePass::modifyRenderPassMacros(defines);
break;
}
}
ShaderMap::ShaderMap()
{
}
ShaderMap::~ShaderMap()
{
}
const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const
{
for (uint32 i = 0; i < shaders.size(); ++i)
{
if (shaders[i].id == id)
{
return &(shaders[i]);
}
}
return nullptr;
}
ShaderCollection& ShaderMap::createShaders(
PGraphics graphics,
RenderPassType renderPass,
PMaterial material,
VertexInputType* vertexInput,
bool /*bPositionOnly*/)
{
std::scoped_lock lock(shadersLock);
ShaderCollection& collection = shaders.add();
//collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
ShaderCreateInfo createInfo;
createInfo.entryPoint = "vertexMain";
createInfo.typeParameter = { material->getName().c_str() };
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1";
createInfo.defines["USE_INSTANCING"] = "0";
modifyRenderPassMacros(renderPass, createInfo.defines);
createInfo.name = getShaderNameFromRenderPassType(renderPass) + " Material " + material->getName();
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass));
createInfo.mainModule = getShaderNameFromRenderPassType(renderPass);
createInfo.additionalModules.add(vertexInput->getShaderFilename());
createInfo.additionalModules.add(material->getName());
collection.vertexShader = graphics->createVertexShader(createInfo);
if (renderPass != RenderPassType::DepthPrepass)
{
createInfo.entryPoint = "fragmentMain";
collection.fragmentShader = graphics->createFragmentShader(createInfo);
}
ShaderPermutation permutation;
std::string materialName = material->getName();
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;
}
+108
View File
@@ -0,0 +1,108 @@
#pragma once
#include "Enums.h"
namespace Seele
{
namespace Gfx
{
class Shader
{};
DEFINE_REF(Shader)
class TaskShader
{
public:
TaskShader() {}
virtual ~TaskShader() {}
};
DEFINE_REF(TaskShader)
class MeshShader
{
public:
MeshShader() {}
virtual ~MeshShader() {}
};
DEFINE_REF(MeshShader)
class VertexShader
{
public:
VertexShader() {}
virtual ~VertexShader() {}
};
DEFINE_REF(VertexShader)
class FragmentShader
{
public:
FragmentShader() {}
virtual ~FragmentShader() {}
};
DEFINE_REF(FragmentShader)
class ComputeShader
{
public:
ComputeShader() {}
virtual ~ComputeShader() {}
};
DEFINE_REF(ComputeShader)
//Uniquely identifies a permutation of shaders
//using the type parameters used to generate it
struct ShaderPermutation
{
RenderPassType passType;
char vertexInputName[15];
char materialName[16];
//TODO: lightmapping etc
};
//Hashed ShaderPermutation for fast lookup
struct PermutationId
{
uint32 hash;
PermutationId()
: hash(0)
{}
PermutationId(ShaderPermutation permutation)
: hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32()))
{}
friend inline bool operator==(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash == rhs.hash;
}
friend inline bool operator!=(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash != rhs.hash;
}
friend inline bool operator<(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash < rhs.hash;
}
friend inline bool operator>(const PermutationId& lhs, const PermutationId& rhs)
{
return lhs.hash > rhs.hash;
}
};
struct ShaderCollection
{
PermutationId id;
//PVertexDeclaration vertexDeclaration;
PVertexShader vertexShader;
PFragmentShader fragmentShader;
};
class ShaderMap
{
public:
ShaderMap();
~ShaderMap();
const ShaderCollection* findShaders(PermutationId&& id) const;
ShaderCollection& createShaders(
PGraphics graphics,
RenderPassType passName,
bool bPositionOnly);
private:
std::mutex shadersLock;
Array<ShaderCollection> shaders;
};
DEFINE_REF(ShaderMap)
}
} // namespace Seele
-1
View File
@@ -1,5 +1,4 @@
#include "ShaderCompiler.h" #include "ShaderCompiler.h"
#include "VertexShaderInput.h"
#include "Graphics.h" #include "Graphics.h"
using namespace Seele; using namespace Seele;
-1
View File
@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "Material/Material.h" #include "Material/Material.h"
#include "GraphicsResources.h"
namespace Seele namespace Seele
{ {
+7 -2
View File
@@ -2,8 +2,13 @@
using namespace Seele; using namespace Seele;
StaticMeshVertexData::StaticMeshVertexData() extern List<VertexData*> vertexDataList;
{}
StaticMeshVertexData::StaticMeshVertexData(Gfx::PGraphics graphics)
: VertexData(graphics)
{
vertexDataList.add(this);
}
StaticMeshVertexData::~StaticMeshVertexData() StaticMeshVertexData::~StaticMeshVertexData()
{} {}
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Seele
class StaticMeshVertexData : public VertexData class StaticMeshVertexData : public VertexData
{ {
public: public:
StaticMeshVertexData(); StaticMeshVertexData(Gfx::PGraphics graphics);
virtual ~StaticMeshVertexData(); virtual ~StaticMeshVertexData();
private: private:
}; };
+41
View File
@@ -0,0 +1,41 @@
#include "Texture.h"
using namespace Seele;
using namespace Seele::Gfx;
Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: QueueOwnedResource(mapping, startQueueType)
{
}
Texture::~Texture()
{
}
Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: Texture(mapping, startQueueType)
{
}
Texture2D::~Texture2D()
{
}
Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: Texture(mapping, startQueueType)
{
}
Texture3D::~Texture3D()
{
}
TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: Texture(mapping, startQueueType)
{
}
TextureCube::~TextureCube()
{
}
+110
View File
@@ -0,0 +1,110 @@
#pragma once
#include "Resources.h"
namespace Seele
{
namespace Gfx
{
// IMPORTANT!!
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
// This is because the refcounting object is unique per allocation, so
// the base address of both the Gfx:: and the implementation class
// need to match for it to work
class Texture : public QueueOwnedResource
{
public:
Texture(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual uint32 getNumFaces() const { return 1; }
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture2D* getTexture2D() { return nullptr; }
virtual class Texture3D* getTexture3D() { return nullptr; }
virtual class TextureCube* getTextureCube() { return nullptr; }
virtual void* getNativeHandle() { return nullptr; }
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(Texture)
class Texture2D : public Texture
{
public:
Texture2D(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture2D();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture2D* getTexture2D() { return this; }
protected:
//Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(Texture2D)
class Texture3D : public Texture
{
public:
Texture3D(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture3D();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture3D* getTexture3D() { return this; }
protected:
//Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(Texture3D)
class TextureCube : public Texture
{
public:
TextureCube(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~TextureCube();
virtual SeFormat getFormat() const = 0;
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual uint32 getNumFaces() const { return 6; }
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class TextureCube* getTextureCube() { return this; }
protected:
//Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
};
DEFINE_REF(TextureCube)
}
}
-1
View File
@@ -1 +0,0 @@
#include "TopologyData.h"
-17
View File
@@ -1,17 +0,0 @@
#pragma once
#include "GraphicsResources.h"
#include "VertexData.h"
namespace Seele
{
class TopologyData
{
public:
TopologyData();
virtual ~TopologyData();
virtual void bind() = 0;
protected:
VertexData* vertexData;
};
DEFINE_REF(TopologyData)
} // namespace Seele
+2
View File
@@ -1,6 +1,8 @@
#include "VertexData.h" #include "VertexData.h"
#include "Material/Material.h" #include "Material/Material.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/Descriptor.h"
#include "Component/Mesh.h"
using namespace Seele; using namespace Seele;
+8 -2
View File
@@ -1,11 +1,17 @@
#pragma once #pragma once
#include "GraphicsResources.h"
#include "Material/MaterialInstance.h" #include "Material/MaterialInstance.h"
#include "Component/Mesh.h"
#include "Component/Transform.h" #include "Component/Transform.h"
#include "Containers/List.h"
#include "Graphics/Resources.h"
#include "Graphics/Descriptor.h"
#include "Graphics/Buffer.h"
namespace Seele namespace Seele
{ {
namespace Component
{
struct Mesh;
}
struct MeshId struct MeshId
{ {
uint64 id; uint64 id;
@@ -1,6 +1,6 @@
#include "VulkanAllocator.h" #include "Allocator.h"
#include "VulkanGraphics.h" #include "Graphics.h"
#include "VulkanInitializer.h" #include "Initializer.h"
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "MinimalEngine.h" #include "MinimalEngine.h"
#include "VulkanGraphicsEnums.h" #include "Enums.h"
#include "Containers/Map.h" #include "Containers/Map.h"
#include "Containers/Array.h" #include "Containers/Array.h"
#include <mutex> #include <mutex>
@@ -1,8 +1,4 @@
#include "VulkanGraphicsResources.h" #include "Buffer.h"
#include "VulkanInitializer.h"
#include "VulkanGraphics.h"
#include "VulkanCommandBuffer.h"
#include "VulkanAllocator.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -16,7 +12,7 @@ struct PendingBuffer
bool bWriteOnly; bool bWriteOnly;
}; };
static std::map<ShaderBuffer *, PendingBuffer> pendingBuffers; static std::map<Vulkan::ShaderBuffer *, PendingBuffer> pendingBuffers;
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic) ShaderBuffer::ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
: graphics(graphics) : graphics(graphics)
+145
View File
@@ -0,0 +1,145 @@
#pragma once
#include "Graphics/Buffer.h"
#include "Graphics.h"
#include "Allocator.h"
namespace Seele
{
namespace Vulkan
{
class ShaderBuffer
{
public:
ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
virtual ~ShaderBuffer();
VkBuffer getHandle() const
{
return buffers[currentBuffer].buffer;
}
uint64 getSize() const
{
return size;
}
VkDeviceSize getOffset() const;
void advanceBuffer()
{
currentBuffer = (currentBuffer + 1) % numBuffers;
}
virtual void *lock(bool bWriteOnly = true);
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
virtual void unlock();
protected:
struct BufferAllocation
{
VkBuffer buffer;
PSubAllocation allocation;
};
PGraphics graphics;
uint32 currentBuffer;
uint64 size;
Gfx::QueueType& owner;
BufferAllocation buffers[Gfx::numFramesBuffered];
uint32 numBuffers;
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
};
DEFINE_REF(ShaderBuffer)
DECLARE_REF(StagingBuffer)
class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer
{
public:
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData);
virtual ~UniformBuffer();
virtual bool updateContents(const BulkResourceData &resourceData);
virtual void* lock(bool bWriteOnly = true) override;
virtual void unlock() override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
};
DEFINE_REF(UniformBuffer)
class ShaderBuffer : public Gfx::ShaderBuffer, public ShaderBuffer
{
public:
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &resourceData);
virtual ~ShaderBuffer();
virtual bool updateContents(const BulkResourceData &resourceData);
virtual void* lock(bool bWriteOnly = true) override;
virtual void unlock() override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
};
DEFINE_REF(ShaderBuffer)
class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer
{
public:
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
virtual ~VertexBuffer();
virtual void updateRegion(BulkResourceData update) override;
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(VertexBuffer)
class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer
{
public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
virtual ~IndexBuffer();
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(IndexBuffer)
}
}
+48 -42
View File
@@ -1,49 +1,55 @@
target_sources(Engine target_sources(Engine
PRIVATE PRIVATE
VulkanAllocator.h Allocator.h
VulkanAllocator.cpp Allocator.cpp
VulkanBuffer.cpp Buffer.h
VulkanCommandBuffer.h Buffer.cpp
VulkanCommandBuffer.cpp CommandBuffer.h
VulkanFramebuffer.h CommandBuffer.cpp
VulkanFramebuffer.cpp DescriptorSets.h
VulkanGraphics.h DescriptorSets.cpp
VulkanGraphics.cpp Enums.h
VulkanGraphicsResources.h Enums.cpp
VulkanGraphicsResources.cpp Framebuffer.h
VulkanDescriptorSets.h Framebuffer.cpp
VulkanDescriptorSets.cpp Graphics.h
VulkanGraphicsEnums.h Graphics.cpp
VulkanGraphicsEnums.cpp Initializer.h
VulkanInitializer.h Initializer.cpp
VulkanInitializer.cpp Pipeline.h
VulkanRenderPass.h Pipeline.cpp
VulkanRenderPass.cpp PipelineCache.h
VulkanPipeline.h PipelineCache.cpp
VulkanPipeline.cpp Queue.h
VulkanPipelineCache.h Queue.cpp
VulkanPipelineCache.cpp RenderPass.h
VulkanShader.h RenderPass.cpp
VulkanShader.cpp RenderTarget.h
VulkanTexture.cpp RenderTarget.cpp
VulkanQueue.h Resources.h
VulkanQueue.cpp Resources.cpp
VulkanViewport.cpp) Shader.h
Shader.cpp
Texture.h
Texture.cpp)
target_sources(Engine target_sources(Engine
PUBLIC FILE_SET HEADERS PUBLIC FILE_SET HEADERS
FILES FILES
VulkanAllocator.h Allocator.h
VulkanCommandBuffer.h Buffer.h
VulkanFramebuffer.h CommandBuffer.h
VulkanGraphics.h DescriptorSets.h
VulkanGraphicsResources.h Enums.h
VulkanDescriptorSets.h Framebuffer.h
VulkanGraphicsEnums.h Graphics.h
VulkanInitializer.h Initializer.h
VulkanRenderPass.h Pipeline.h
VulkanPipeline.h PipelineCache.h
VulkanPipelineCache.h Queue.h
VulkanShader.h RenderPass.h
VulkanQueue.h) RenderTarget.h
Resources.h
Shader.h
Texture.h)
@@ -1,13 +1,12 @@
#include "VulkanCommandBuffer.h" #include "CommandBuffer.h"
#include "VulkanInitializer.h" #include "Initializer.h"
#include "VulkanGraphics.h" #include "Graphics.h"
#include "VulkanPipeline.h" #include "Pipeline.h"
#include "VulkanGraphicsEnums.h" #include "Enums.h"
#include "VulkanFramebuffer.h" #include "Framebuffer.h"
#include "VulkanRenderPass.h" #include "RenderPass.h"
#include "VulkanPipeline.h" #include "Pipeline.h"
#include "VulkanDescriptorSets.h" #include "DescriptorSets.h"
#include "Graphics/MeshBatch.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Queue.h"
#include "VulkanQueue.h" #include "DescriptorSets.h"
#include "Buffer.h"
namespace Seele namespace Seele
{ {
@@ -87,7 +88,7 @@ public:
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(const Array<Gfx::PDescriptorSet>& descriptorSets) override; virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override;
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) override; virtual void bindVertexBuffer(const Array<PVertexBuffer>& buffers) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
@@ -1,9 +1,7 @@
#include "VulkanDescriptorSets.h" #include "DescriptorSets.h"
#include "VulkanGraphicsResources.h" #include "Graphics.h"
#include "VulkanGraphicsEnums.h" #include "Initializer.h"
#include "VulkanGraphics.h" #include "CommandBuffer.h"
#include "VulkanInitializer.h"
#include "VulkanCommandBuffer.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -1,5 +1,8 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Enums.h"
#include "Graphics/Descriptor.h"
#include "Containers/List.h"
#include "Resources.h"
namespace Seele namespace Seele
{ {
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "Graphics/GraphicsEnums.h" #include "Graphics/Enums.h"
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <iostream> #include <iostream>
@@ -25,11 +25,10 @@ namespace Vulkan
enum class ShaderType enum class ShaderType
{ {
VERTEX = 0, VERTEX = 0,
CONTROL = 1, FRAGMENT = 1,
EVALUATION = 2, COMPUTE = 2,
GEOMETRY = 3, TASK = 3,
FRAGMENT = 4, MESH = 4,
COMPUTE = 5,
}; };
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType); VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
@@ -1,8 +1,9 @@
#include "VulkanFramebuffer.h" #include "Framebuffer.h"
#include "VulkanGraphicsEnums.h" #include "Enums.h"
#include "VulkanInitializer.h" #include "Initializer.h"
#include "VulkanRenderPass.h" #include "RenderPass.h"
#include "VulkanGraphics.h" #include "Graphics.h"
#include "Texture.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -1,5 +1,7 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Enums.h"
#include "Graphics.h"
#include "Graphics/RenderTarget.h"
namespace Seele namespace Seele
{ {
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Enums.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
namespace Seele namespace Seele
@@ -14,6 +14,9 @@ DECLARE_REF(RenderPass)
DECLARE_REF(Framebuffer) DECLARE_REF(Framebuffer)
DECLARE_REF(RenderCommand) DECLARE_REF(RenderCommand)
DECLARE_REF(PipelineCache) DECLARE_REF(PipelineCache)
DECLARE_REF(Window)
DECLARE_REF(RenderTargetLayout)
DECLARE_REF(Viewport)
class Graphics : public Gfx::Graphics class Graphics : public Gfx::Graphics
{ {
public: public:
@@ -55,13 +58,13 @@ public:
virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override; virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override;
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) 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::PEvaluationShader createEvaluationShader(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::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override; virtual Gfx::PTaskShader createTaskShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override; virtual Gfx::PMeshShader createMeshShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo) override;
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo) override;
virtual Gfx::PComputePipeline createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo) override;
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override; virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override; virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
@@ -1,4 +1,4 @@
#include "VulkanInitializer.h" #include "Initializer.h"
#include <iostream> #include <iostream>
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -1,12 +1,12 @@
#include "VulkanPipeline.h" #include "Pipeline.h"
#include "VulkanDescriptorSets.h" #include "DescriptorSets.h"
#include "VulkanGraphics.h" #include "Graphics.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo) GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout)
: Gfx::GraphicsPipeline(createInfo, pipelineLayout) : Gfx::GraphicsPipeline(pipelineLayout)
, graphics(graphics) , graphics(graphics)
, pipeline(handle) , pipeline(handle)
{ {
@@ -26,8 +26,8 @@ VkPipelineLayout GraphicsPipeline::getLayout() const
return layout.cast<PipelineLayout>()->getHandle(); return layout.cast<PipelineLayout>()->getHandle();
} }
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo) ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout)
: Gfx::ComputePipeline(createInfo, pipelineLayout) : Gfx::ComputePipeline(pipelineLayout)
, graphics(graphics) , graphics(graphics)
, pipeline(handle) , pipeline(handle)
{ {
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Enums.h"
#include "Graphics/Resources.h"
namespace Seele namespace Seele
{ {
@@ -10,7 +11,7 @@ DECLARE_REF(Graphics)
class GraphicsPipeline : public Gfx::GraphicsPipeline class GraphicsPipeline : public Gfx::GraphicsPipeline
{ {
public: public:
GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo); GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout);
virtual ~GraphicsPipeline(); virtual ~GraphicsPipeline();
void bind(VkCommandBuffer handle); void bind(VkCommandBuffer handle);
VkPipelineLayout getLayout() const; VkPipelineLayout getLayout() const;
@@ -22,7 +23,7 @@ DEFINE_REF(GraphicsPipeline)
class ComputePipeline : public Gfx::ComputePipeline class ComputePipeline : public Gfx::ComputePipeline
{ {
public: public:
ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo); ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout);
virtual ~ComputePipeline(); virtual ~ComputePipeline();
void bind(VkCommandBuffer handle); void bind(VkCommandBuffer handle);
VkPipelineLayout getLayout() const; VkPipelineLayout getLayout() const;
@@ -0,0 +1,393 @@
#include "PipelineCache.h"
#include "Graphics.h"
#include "Enums.h"
#include "Initializer.h"
#include "RenderPass.h"
#include "DescriptorSets.h"
#include "Shader.h"
#include <fstream>
using namespace Seele;
using namespace Seele::Vulkan;
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath)
: graphics(graphics)
, cacheFile(cacheFilePath)
{
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
VkPipelineCacheCreateInfo cacheCreateInfo;
cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
cacheCreateInfo.pNext = nullptr;
cacheCreateInfo.flags = 0;
cacheCreateInfo.initialDataSize = 0;
if(stream.good())
{
Array<uint8> cacheData;
uint32 fileSize = static_cast<uint32>(stream.tellg());
cacheData.resize(fileSize);
stream.seekg(0);
stream.read((char*)cacheData.data(), fileSize);
cacheCreateInfo.initialDataSize = fileSize;
cacheCreateInfo.pInitialData = cacheData.data();
std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl;
}
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
}
PipelineCache::~PipelineCache()
{
VkDeviceSize cacheSize;
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr);
Array<uint8> cacheData;
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data());
std::ofstream stream(cacheFile, std::ios::binary);
stream.write((char*)cacheData.data(), cacheSize);
stream.flush();
stream.close();
vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr);
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
}
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo)
{
uint32 stageCount = 0;
VkPipelineShaderStageCreateInfo stageInfos[2];
std::memset(stageInfos, 0, sizeof(stageInfos));
PVertexShader vertexShader = gfxInfo.vertexShader.cast<VertexShader>();
stageInfos[stageCount++] = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_VERTEX_BIT,
.module = vertexShader->getModuleHandle(),
.pName = vertexShader->getEntryPointName(),
};
if(gfxInfo.fragmentShader != nullptr)
{
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
stageInfos[stageCount++] = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = fragment->getModuleHandle(),
.pName = fragment->getEntryPointName(),
};
}
VkPipelineVertexInputStateCreateInfo vertexInput =
init::PipelineVertexInputStateCreateInfo();
Array<VkVertexInputBindingDescription> bindings;
Array<VkVertexInputAttributeDescription> attributes;
if (gfxInfo.vertexDeclaration != nullptr)
{
PVertexDeclaration decl = gfxInfo.vertexDeclaration.cast<VertexDeclaration>();
for (const auto& elem : decl->elementList)
{
attributes.add(VkVertexInputAttributeDescription{
.location = elem.attributeIndex,
.binding = elem.binding,
.format = cast(elem.vertexFormat),
.offset = elem.offset,
});
auto res = bindings.find([elem](const VkVertexInputBindingDescription& b) {return b.binding == elem.binding; });
if (res == bindings.end())
{
bindings.add({});
res = bindings.end();
}
*res = VkVertexInputBindingDescription{
.binding = elem.binding,
.stride = elem.stride,
.inputRate = elem.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
};
}
vertexInput.pVertexAttributeDescriptions = attributes.data();
vertexInput.vertexAttributeDescriptionCount = attributes.size();
vertexInput.pVertexBindingDescriptions = bindings.data();
vertexInput.vertexBindingDescriptionCount = bindings.size();
}
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
init::PipelineInputAssemblyStateCreateInfo(
cast(gfxInfo.topology),
0,
false
);
VkPipelineViewportStateCreateInfo viewportInfo =
init::PipelineViewportStateCreateInfo(
1,
1,
0
);
VkPipelineRasterizationStateCreateInfo rasterizationState =
init::PipelineRasterizationStateCreateInfo(
cast(gfxInfo.rasterizationState.polygonMode),
gfxInfo.rasterizationState.cullMode,
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
0
);
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor;
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
VkPipelineMultisampleStateCreateInfo multisampleState =
init::PipelineMultisampleStateCreateInfo(
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
0);
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
VkPipelineDepthStencilStateCreateInfo depthStencilState =
init::PipelineDepthStencilStateCreateInfo(
gfxInfo.depthStencilState.depthTestEnable,
gfxInfo.depthStencilState.depthWriteEnable,
cast(gfxInfo.depthStencilState.depthCompareOp)
);
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
Array<VkPipelineColorBlendAttachmentState> blendAttachments(colorAttachments.size());
for(uint32 i = 0; i < colorAttachments.size(); ++i)
{
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
blendAttachments[i] = {
.blendEnable = attachment.blendEnable,
.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor,
.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor,
.colorBlendOp = (VkBlendOp)attachment.colorBlendOp,
.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor,
.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor,
.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp,
.colorWriteMask = attachment.colorWriteMask,
};
}
VkPipelineColorBlendStateCreateInfo blendState =
init::PipelineColorBlendStateCreateInfo(
(uint32)blendAttachments.size(),
blendAttachments.data()
);
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants));
uint32 numDynamicEnabled = 0;
StaticArray<VkDynamicState, 2> dynamicEnabled;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
VkPipelineDynamicStateCreateInfo dynamicState =
init::PipelineDynamicStateCreateInfo(
dynamicEnabled.data(),
numDynamicEnabled,
0
);
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
VkPipeline pipelineHandle;
VkGraphicsPipelineCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = 0,
.flags = 0,
.stageCount = stageCount,
.pStages = stageInfos,
.pVertexInputState = &vertexInput,
.pInputAssemblyState = &assemblyInfo,
.pViewportState = &viewportInfo,
.pRasterizationState = &rasterizationState,
.pMultisampleState = &multisampleState,
.pDepthStencilState = &depthStencilState,
.pColorBlendState = &blendState,
.pDynamicState = &dynamicState,
.layout = layout->getHandle(),
.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle(),
.subpass = 0,
};
auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Gfx creation time: " << delta << std::endl;
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
return result;
}
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo)
{
uint32 stageCount = 0;
VkPipelineShaderStageCreateInfo stageInfos[3];
std::memset(stageInfos, 0, sizeof(stageInfos));
if (gfxInfo.taskShader != nullptr)
{
PTaskShader taskShader = gfxInfo.taskShader.cast<TaskShader>();
stageInfos[stageCount++] = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_TASK_BIT_EXT,
.module = taskShader->getModuleHandle(),
.pName = taskShader->getEntryPointName(),
};
}
PMeshShader meshShader = gfxInfo.meshShader.cast<MeshShader>();
stageInfos[stageCount++] = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_MESH_BIT_EXT,
.module = meshShader->getModuleHandle(),
.pName = meshShader->getEntryPointName(),
};
if (gfxInfo.fragmentShader != nullptr)
{
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
stageInfos[stageCount++] = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
.module = fragment->getModuleHandle(),
.pName = fragment->getEntryPointName(),
};
}
VkPipelineViewportStateCreateInfo viewportInfo =
init::PipelineViewportStateCreateInfo(
1,
1,
0
);
VkPipelineRasterizationStateCreateInfo rasterizationState =
init::PipelineRasterizationStateCreateInfo(
cast(gfxInfo.rasterizationState.polygonMode),
gfxInfo.rasterizationState.cullMode,
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
0
);
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor;
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
VkPipelineMultisampleStateCreateInfo multisampleState =
init::PipelineMultisampleStateCreateInfo(
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
0);
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
VkPipelineDepthStencilStateCreateInfo depthStencilState =
init::PipelineDepthStencilStateCreateInfo(
gfxInfo.depthStencilState.depthTestEnable,
gfxInfo.depthStencilState.depthWriteEnable,
cast(gfxInfo.depthStencilState.depthCompareOp)
);
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
Array<VkPipelineColorBlendAttachmentState> blendAttachments(colorAttachments.size());
for (uint32 i = 0; i < colorAttachments.size(); ++i)
{
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
blendAttachments[i] = {
.blendEnable = attachment.blendEnable,
.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor,
.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor,
.colorBlendOp = (VkBlendOp)attachment.colorBlendOp,
.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor,
.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor,
.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp,
.colorWriteMask = attachment.colorWriteMask,
};
}
VkPipelineColorBlendStateCreateInfo blendState =
init::PipelineColorBlendStateCreateInfo(
(uint32)blendAttachments.size(),
blendAttachments.data()
);
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants));
uint32 numDynamicEnabled = 0;
StaticArray<VkDynamicState, 2> dynamicEnabled;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
VkPipelineDynamicStateCreateInfo dynamicState =
init::PipelineDynamicStateCreateInfo(
dynamicEnabled.data(),
numDynamicEnabled,
0
);
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
VkPipeline pipelineHandle;
VkGraphicsPipelineCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = 0,
.flags = 0,
.stageCount = stageCount,
.pStages = stageInfos,
.pVertexInputState = nullptr,
.pInputAssemblyState = nullptr,
.pViewportState = &viewportInfo,
.pRasterizationState = &rasterizationState,
.pMultisampleState = &multisampleState,
.pDepthStencilState = &depthStencilState,
.pColorBlendState = &blendState,
.pDynamicState = &dynamicState,
.layout = layout->getHandle(),
.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle(),
.subpass = 0,
};
auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Gfx creation time: " << delta << std::endl;
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
return result;
}
PComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo)
{
VkComputePipelineCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
createInfo.pNext = 0;
createInfo.flags = 0;
createInfo.basePipelineIndex = 0;
createInfo.basePipelineHandle = VK_NULL_HANDLE;
auto layout = computeInfo.pipelineLayout.cast<PipelineLayout>();
createInfo.layout = layout->getHandle();
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
createInfo.stage = init::PipelineShaderStageCreateInfo(
VK_SHADER_STAGE_COMPUTE_BIT,
computeStage->getModuleHandle(),
computeStage->getEntryPointName());
VkPipeline pipelineHandle;
auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Compute creation time: " << delta << std::endl;
PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout);
return result;
}
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "VulkanPipeline.h" #include "Pipeline.h"
namespace Seele namespace Seele
{ {
@@ -10,14 +10,13 @@ class PipelineCache
public: public:
PipelineCache(PGraphics graphics, const std::string& cacheFilePath); PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
~PipelineCache(); ~PipelineCache();
PGraphicsPipeline createPipeline(const GraphicsPipelineCreateInfo& createInfo); PGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo);
PComputePipeline createPipeline(const ComputePipelineCreateInfo& createInfo); PGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo);
PComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo);
private: private:
VkPipelineCache cache; VkPipelineCache cache;
PGraphics graphics; PGraphics graphics;
std::string cacheFile; std::string cacheFile;
std::mutex createdPipelinesLock;
Map<uint32, VkPipeline> createdPipelines;
}; };
DEFINE_REF(PipelineCache) DEFINE_REF(PipelineCache)
} // namespace Vulkan } // namespace Vulkan
@@ -1,9 +1,8 @@
#include "VulkanQueue.h" #include "Queue.h"
#include "VulkanInitializer.h" #include "Initializer.h"
#include "VulkanGraphics.h" #include "Graphics.h"
#include "VulkanAllocator.h" #include "Allocator.h"
#include "VulkanCommandBuffer.h" #include "CommandBuffer.h"
#include "VulkanGraphicsEnums.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Resources.h"
namespace Seele namespace Seele
{ {
@@ -1,8 +1,8 @@
#include "VulkanRenderPass.h" #include "RenderPass.h"
#include "VulkanInitializer.h" #include "Initializer.h"
#include "VulkanGraphicsEnums.h" #include "Graphics.h"
#include "VulkanGraphics.h" #include "Framebuffer.h"
#include "VulkanFramebuffer.h" #include "Texture.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Graphics/RenderTarget.h"
#include "Graphics.h"
namespace Seele namespace Seele
{ {
+83
View File
@@ -0,0 +1,83 @@
#pragma once
#include "Graphics/RenderTarget.h"
#include "Graphics.h"
#include "Texture.h"
#include "Resources.h"
namespace Seele
{
namespace Vulkan
{
class Window : public Gfx::Window
{
public:
Window(PGraphics graphics, const WindowCreateInfo &createInfo);
virtual ~Window();
virtual void beginFrame() override;
virtual void endFrame() override;
virtual Gfx::PTexture2D getBackBuffer() const override;
virtual void onWindowCloseEvent() override;
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) override;
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) override;
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
virtual void setCloseCallback(std::function<void()> callback);
VkFormat getPixelFormat() const
{
return cast(windowState.pixelFormat);
}
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
std::function<void(double, double)> mouseMoveCallback;
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
std::function<void(double, double)> scrollCallback;
std::function<void(int, const char**)> fileCallback;
std::function<void()> closeCallback;
protected:
void advanceBackBuffer();
void recreateSwapchain(const WindowCreateInfo &createInfo);
void present();
void destroySwapchain();
void createSwapchain();
void chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred);
void choosePresentMode(const Array<VkPresentModeKHR> &modes);
PTexture2D backBufferImages[Gfx::numFramesBuffered];
PSemaphore renderFinished[Gfx::numFramesBuffered];
PSemaphore imageAcquired[Gfx::numFramesBuffered];
PSemaphore imageAcquiredSemaphore;
PGraphics graphics;
VkInstance instance;
VkSwapchainKHR swapchain;
VkSampleCountFlags numSamples;
VkPresentModeKHR presentMode;
VkSurfaceKHR surface;
VkSurfaceFormatKHR surfaceFormat;
void *windowHandle;
int32 currentImageIndex;
int32 acquiredImageIndex;
int32 preAcquiredImageIndex;
int32 semaphoreIndex;
};
DEFINE_REF(Window)
class Viewport : public Gfx::Viewport
{
public:
Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY);
virtual void move(uint32 newOffsetX, uint32 newOffsetY);
VkViewport getHandle() const { return handle; }
private:
VkViewport handle;
PGraphics graphics;
friend class Graphics;
};
DECLARE_REF(Viewport)
}
}
+80
View File
@@ -0,0 +1,80 @@
#pragma once
#include <vulkan/vulkan.h>
#include <functional>
#include "Graphics/Resources.h"
#include "Allocator.h"
namespace Seele
{
namespace Vulkan
{
DECLARE_REF(DescriptorAllocator)
DECLARE_REF(CommandBufferManager)
DECLARE_REF(CmdBuffer)
DECLARE_REF(Graphics)
DECLARE_REF(SubAllocation)
class Semaphore
{
public:
Semaphore(PGraphics graphics);
virtual ~Semaphore();
inline VkSemaphore getHandle() const
{
return handle;
}
private:
VkSemaphore handle;
PGraphics graphics;
};
DEFINE_REF(Semaphore)
class Fence
{
public:
Fence(PGraphics graphics);
~Fence();
bool isSignaled();
void reset();
inline VkFence getHandle() const
{
return fence;
}
void wait(uint32 timeout);
/*Event& operator co_await()
{
return signaled;
}*/
bool operator<(const Fence &other) const
{
return fence < other.fence;
}
private:
PGraphics graphics;
bool signaled;
VkFence 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 SamplerState : public Gfx::SamplerState
{
public:
VkSampler sampler;
};
DEFINE_REF(SamplerState)
} // namespace Vulkan
} // namespace Seele
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "VulkanGraphicsResources.h" #include "Resources.h"
#include "VulkanGraphicsEnums.h" #include "Enums.h"
#include "Graphics/Shader.h"
namespace Seele namespace Seele
{ {
@@ -51,18 +52,16 @@ public:
} }
}; };
typedef ShaderBase<Gfx::VertexShader, ShaderType::VERTEX, VK_SHADER_STAGE_VERTEX_BIT> VertexShader; typedef ShaderBase<Gfx::VertexShader, ShaderType::VERTEX, VK_SHADER_STAGE_VERTEX_BIT> VertexShader;
typedef ShaderBase<Gfx::ControlShader, ShaderType::CONTROL, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT> ControlShader;
typedef ShaderBase<Gfx::EvaluationShader, ShaderType::EVALUATION, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT> EvaluationShader;
typedef ShaderBase<Gfx::GeometryShader, ShaderType::GEOMETRY, VK_SHADER_STAGE_GEOMETRY_BIT> GeometryShader;
typedef ShaderBase<Gfx::FragmentShader, ShaderType::FRAGMENT, VK_SHADER_STAGE_FRAGMENT_BIT> FragmentShader; typedef ShaderBase<Gfx::FragmentShader, ShaderType::FRAGMENT, VK_SHADER_STAGE_FRAGMENT_BIT> FragmentShader;
typedef ShaderBase<Gfx::ComputeShader, ShaderType::COMPUTE, VK_SHADER_STAGE_COMPUTE_BIT> ComputeShader; typedef ShaderBase<Gfx::ComputeShader, ShaderType::COMPUTE, VK_SHADER_STAGE_COMPUTE_BIT> ComputeShader;
typedef ShaderBase<Gfx::TaskShader, ShaderType::TASK, VK_SHADER_STAGE_TASK_BIT_EXT> TaskShader;
typedef ShaderBase<Gfx::MeshShader, ShaderType::MESH, VK_SHADER_STAGE_MESH_BIT_EXT> MeshShader;
DEFINE_REF(VertexShader) DEFINE_REF(VertexShader)
DEFINE_REF(ControlShader)
DEFINE_REF(EvaluationShader)
DEFINE_REF(GeometryShader)
DEFINE_REF(FragmentShader) DEFINE_REF(FragmentShader)
DEFINE_REF(ComputeShader) DEFINE_REF(ComputeShader)
DEFINE_REF(TaskShader)
DEFINE_REF(MeshShader)
} // namespace Vulkan } // namespace Vulkan
} }
+264
View File
@@ -0,0 +1,264 @@
#pragma once
#include "Graphics/Texture.h"
#include "Graphics.h"
#include "Allocator.h"
namespace Seele
{
namespace Vulkan
{
class TextureHandle
{
public:
TextureHandle(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureHandle();
inline VkImage getImage() const
{
return image;
}
inline VkImageView getView() const
{
return defaultView;
}
inline Gfx::SeImageLayout getLayout() const
{
return layout;
}
inline VkImageAspectFlags getAspect() const
{
return aspect;
}
inline VkImageUsageFlags getUsage() const
{
return usage;
}
inline Gfx::SeFormat getFormat() const
{
return format;
}
inline Gfx::SeSampleCountFlags getNumSamples() const
{
return samples;
}
inline uint32 getMipLevels() const
{
return mipLevels;
}
inline bool isDepthStencil() const
{
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
}
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
void changeLayout(Gfx::SeImageLayout newLayout);
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
private:
//Updates via reference
Gfx::QueueType& currentOwner;
PGraphics graphics;
PSubAllocation allocation;
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 arrayCount;
uint32 layerCount;
uint32 mipLevels;
uint32 samples;
Gfx::SeFormat format;
Gfx::SeImageUsageFlags usage;
VkImage image;
VkImageView defaultView;
VkImageAspectFlags aspect;
Gfx::SeImageLayout layout;
friend class TextureBase;
friend class Texture2D;
friend class Texture3D;
friend class TextureCube;
friend class Graphics;
};
class TextureBase
{
public:
static TextureHandle* cast(Gfx::PTexture texture);
protected:
TextureHandle* textureHandle;
friend class Graphics;
};
DECLARE_REF(TextureBase)
class Texture2D : public Gfx::Texture2D, public TextureBase
{
public:
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture2D();
virtual uint32 getSizeX() const override
{
return textureHandle->sizeX;
}
virtual uint32 getSizeY() const override
{
return textureHandle->sizeY;
}
virtual uint32 getSizeZ() const override
{
return textureHandle->sizeZ;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(Texture2D)
class Texture3D : public Gfx::Texture3D, public TextureBase
{
public:
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture3D();
virtual uint32 getSizeX() const override
{
return textureHandle->sizeX;
}
virtual uint32 getSizeY() const override
{
return textureHandle->sizeY;
}
virtual uint32 getSizeZ() const override
{
return textureHandle->sizeZ;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(Texture3D)
class TextureCube : public Gfx::TextureCube, public TextureBase
{
public:
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureCube();
virtual uint32 getSizeX() const override
{
return textureHandle->sizeX;
}
virtual uint32 getSizeY() const override
{
return textureHandle->sizeY;
}
virtual uint32 getSizeZ() const override
{
return textureHandle->sizeZ;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(TextureCube)
}
}
@@ -1,535 +0,0 @@
#pragma once
#include <vulkan/vulkan.h>
#include <functional>
#include "Graphics/GraphicsResources.h"
#include "VulkanAllocator.h"
namespace Seele
{
namespace Vulkan
{
DECLARE_REF(DescriptorAllocator)
DECLARE_REF(CommandBufferManager)
DECLARE_REF(CmdBuffer)
DECLARE_REF(Graphics)
DECLARE_REF(SubAllocation)
class Semaphore
{
public:
Semaphore(PGraphics graphics);
virtual ~Semaphore();
inline VkSemaphore getHandle() const
{
return handle;
}
private:
VkSemaphore handle;
PGraphics graphics;
};
DEFINE_REF(Semaphore)
class Fence
{
public:
Fence(PGraphics graphics);
~Fence();
bool isSignaled();
void reset();
inline VkFence getHandle() const
{
return fence;
}
void wait(uint32 timeout);
/*Event& operator co_await()
{
return signaled;
}*/
bool operator<(const Fence &other) const
{
return fence < other.fence;
}
private:
PGraphics graphics;
bool signaled;
VkFence 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 ShaderBuffer
{
public:
ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
virtual ~ShaderBuffer();
VkBuffer getHandle() const
{
return buffers[currentBuffer].buffer;
}
uint64 getSize() const
{
return size;
}
VkDeviceSize getOffset() const;
void advanceBuffer()
{
currentBuffer = (currentBuffer + 1) % numBuffers;
}
virtual void *lock(bool bWriteOnly = true);
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
virtual void unlock();
protected:
struct BufferAllocation
{
VkBuffer buffer;
PSubAllocation allocation;
};
PGraphics graphics;
uint32 currentBuffer;
uint64 size;
Gfx::QueueType& owner;
BufferAllocation buffers[Gfx::numFramesBuffered];
uint32 numBuffers;
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
};
DEFINE_REF(ShaderBuffer)
DECLARE_REF(StagingBuffer)
class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer
{
public:
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData);
virtual ~UniformBuffer();
virtual bool updateContents(const BulkResourceData &resourceData);
virtual void* lock(bool bWriteOnly = true) override;
virtual void unlock() override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
};
DEFINE_REF(UniformBuffer)
class ShaderBuffer : public Gfx::ShaderBuffer, public ShaderBuffer
{
public:
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &resourceData);
virtual ~ShaderBuffer();
virtual bool updateContents(const BulkResourceData &resourceData);
virtual void* lock(bool bWriteOnly = true) override;
virtual void unlock() override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
};
DEFINE_REF(ShaderBuffer)
class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer
{
public:
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
virtual ~VertexBuffer();
virtual void updateRegion(BulkResourceData update) override;
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(VertexBuffer)
class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer
{
public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
virtual ~IndexBuffer();
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(IndexBuffer)
class TextureHandle
{
public:
TextureHandle(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureHandle();
inline VkImage getImage() const
{
return image;
}
inline VkImageView getView() const
{
return defaultView;
}
inline Gfx::SeImageLayout getLayout() const
{
return layout;
}
inline VkImageAspectFlags getAspect() const
{
return aspect;
}
inline VkImageUsageFlags getUsage() const
{
return usage;
}
inline Gfx::SeFormat getFormat() const
{
return format;
}
inline Gfx::SeSampleCountFlags getNumSamples() const
{
return samples;
}
inline uint32 getMipLevels() const
{
return mipLevels;
}
inline bool isDepthStencil() const
{
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
}
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
void changeLayout(Gfx::SeImageLayout newLayout);
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
private:
//Updates via reference
Gfx::QueueType& currentOwner;
PGraphics graphics;
PSubAllocation allocation;
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 arrayCount;
uint32 layerCount;
uint32 mipLevels;
uint32 samples;
Gfx::SeFormat format;
Gfx::SeImageUsageFlags usage;
VkImage image;
VkImageView defaultView;
VkImageAspectFlags aspect;
Gfx::SeImageLayout layout;
friend class TextureBase;
friend class Texture2D;
friend class Texture3D;
friend class TextureCube;
friend class Graphics;
};
class TextureBase
{
public:
static TextureHandle* cast(Gfx::PTexture texture);
protected:
TextureHandle* textureHandle;
friend class Graphics;
};
DECLARE_REF(TextureBase)
class Texture2D : public Gfx::Texture2D, public TextureBase
{
public:
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture2D();
virtual uint32 getSizeX() const override
{
return textureHandle->sizeX;
}
virtual uint32 getSizeY() const override
{
return textureHandle->sizeY;
}
virtual uint32 getSizeZ() const override
{
return textureHandle->sizeZ;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(Texture2D)
class Texture3D : public Gfx::Texture3D, public TextureBase
{
public:
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture3D();
virtual uint32 getSizeX() const override
{
return textureHandle->sizeX;
}
virtual uint32 getSizeY() const override
{
return textureHandle->sizeY;
}
virtual uint32 getSizeZ() const override
{
return textureHandle->sizeZ;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(Texture3D)
class TextureCube : public Gfx::TextureCube, public TextureBase
{
public:
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureCube();
virtual uint32 getSizeX() const override
{
return textureHandle->sizeX;
}
virtual uint32 getSizeY() const override
{
return textureHandle->sizeY;
}
virtual uint32 getSizeZ() const override
{
return textureHandle->sizeZ;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(TextureCube)
class SamplerState : public Gfx::SamplerState
{
public:
VkSampler sampler;
};
DEFINE_REF(SamplerState)
class Window : public Gfx::Window
{
public:
Window(PGraphics graphics, const WindowCreateInfo &createInfo);
virtual ~Window();
virtual void beginFrame() override;
virtual void endFrame() override;
virtual Gfx::PTexture2D getBackBuffer() const override;
virtual void onWindowCloseEvent() override;
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) override;
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) override;
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
virtual void setCloseCallback(std::function<void()> callback);
VkFormat getPixelFormat() const
{
return cast(windowState.pixelFormat);
}
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
std::function<void(double, double)> mouseMoveCallback;
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
std::function<void(double, double)> scrollCallback;
std::function<void(int, const char**)> fileCallback;
std::function<void()> closeCallback;
protected:
void advanceBackBuffer();
void recreateSwapchain(const WindowCreateInfo &createInfo);
void present();
void destroySwapchain();
void createSwapchain();
void chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred);
void choosePresentMode(const Array<VkPresentModeKHR> &modes);
PTexture2D backBufferImages[Gfx::numFramesBuffered];
PSemaphore renderFinished[Gfx::numFramesBuffered];
PSemaphore imageAcquired[Gfx::numFramesBuffered];
PSemaphore imageAcquiredSemaphore;
PGraphics graphics;
VkInstance instance;
VkSwapchainKHR swapchain;
VkSampleCountFlags numSamples;
VkPresentModeKHR presentMode;
VkSurfaceKHR surface;
VkSurfaceFormatKHR surfaceFormat;
void *windowHandle;
int32 currentImageIndex;
int32 acquiredImageIndex;
int32 preAcquiredImageIndex;
int32 semaphoreIndex;
};
DEFINE_REF(Window)
class Viewport : public Gfx::Viewport
{
public:
Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY);
virtual void move(uint32 newOffsetX, uint32 newOffsetY);
VkViewport getHandle() const { return handle; }
private:
VkViewport handle;
PGraphics graphics;
friend class Graphics;
};
DECLARE_REF(Viewport)
} // namespace Vulkan
} // namespace Seele
@@ -1,381 +0,0 @@
#include "VulkanPipelineCache.h"
#include "VulkanGraphics.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanInitializer.h"
#include "VulkanRenderPass.h"
#include "VulkanDescriptorSets.h"
#include "VulkanShader.h"
#include <fstream>
using namespace Seele;
using namespace Seele::Vulkan;
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath)
: graphics(graphics)
, cacheFile(cacheFilePath)
{
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
VkPipelineCacheCreateInfo cacheCreateInfo;
cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
cacheCreateInfo.pNext = nullptr;
cacheCreateInfo.flags = 0;
cacheCreateInfo.initialDataSize = 0;
if(stream.good())
{
Array<uint8> cacheData;
uint32 fileSize = static_cast<uint32>(stream.tellg());
cacheData.resize(fileSize);
stream.seekg(0);
stream.read((char*)cacheData.data(), fileSize);
cacheCreateInfo.initialDataSize = fileSize;
cacheCreateInfo.pInitialData = cacheData.data();
std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl;
}
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
}
PipelineCache::~PipelineCache()
{
VkDeviceSize cacheSize;
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr);
Array<uint8> cacheData;
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data());
std::ofstream stream(cacheFile, std::ios::binary);
stream.write((char*)cacheData.data(), cacheSize);
stream.flush();
stream.close();
vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr);
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
}
struct PipelineCreateHashStruct
{
uint32 vertexHash;
uint32 controlHash;
uint32 evalHash;
uint32 geometryHash;
uint32 fragmentHash;
uint32 pipelineLayoutHash;
VkPipelineTessellationStateCreateInfo tess;
VkVertexInputAttributeDescription attribs[16];
VkVertexInputBindingDescription bindings[16];
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
VkPipelineViewportStateCreateInfo viewport;
VkPipelineRasterizationStateCreateInfo rasterization;
VkPipelineMultisampleStateCreateInfo multisample;
VkPipelineDepthStencilStateCreateInfo depthStencil;
VkPipelineColorBlendAttachmentState blendAttachments[16];
VkPipelineColorBlendStateCreateInfo blendState;
};
PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo& gfxInfo)
{
VkGraphicsPipelineCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
createInfo.pNext = 0;
createInfo.flags = 0;
createInfo.stageCount = 0;
VkPipelineTessellationStateCreateInfo tessInfo;
std::memset(&tessInfo, 0, sizeof(VkPipelineTessellationStateCreateInfo));
VkPipelineShaderStageCreateInfo stageInfos[5];
std::memset(stageInfos, 0, sizeof(stageInfos));
PipelineCreateHashStruct hashStruct;
std::memset(&hashStruct, 0, sizeof(PipelineCreateHashStruct));
PVertexShader vertexShader = gfxInfo.vertexShader.cast<VertexShader>();
VkPipelineShaderStageCreateInfo& vertInfo = stageInfos[createInfo.stageCount++];
vertInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertInfo.module = vertexShader->getModuleHandle();
vertInfo.pName = vertexShader->getEntryPointName();
hashStruct.vertexHash = vertexShader->getShaderHash();
if(gfxInfo.controlShader != nullptr)
{
assert(gfxInfo.evalShader != nullptr);
PControlShader control = gfxInfo.controlShader.cast<ControlShader>();
PEvaluationShader eval = gfxInfo.evalShader.cast<EvaluationShader>();
VkPipelineShaderStageCreateInfo& controlInfo = stageInfos[createInfo.stageCount++];
controlInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
controlInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
controlInfo.module = control->getModuleHandle();
controlInfo.pName = control->getEntryPointName();
VkPipelineShaderStageCreateInfo& evalInfo = stageInfos[createInfo.stageCount++];
evalInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
evalInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
evalInfo.module = eval->getModuleHandle();
evalInfo.pName = eval->getEntryPointName();
tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
tessInfo.pNext = 0;
tessInfo.flags = 0;
tessInfo.patchControlPoints = control->getNumPatches();
hashStruct.controlHash = control->getShaderHash();
hashStruct.evalHash = eval->getShaderHash();
hashStruct.tess = tessInfo;
}
if(gfxInfo.geometryShader != nullptr)
{
PGeometryShader geometry = gfxInfo.geometryShader.cast<GeometryShader>();
VkPipelineShaderStageCreateInfo& geometryInfo = stageInfos[createInfo.stageCount++];
geometryInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT;
geometryInfo.module = geometry->getModuleHandle();
geometryInfo.pName = geometry->getEntryPointName();
hashStruct.geometryHash = geometry->getShaderHash();
}
if(gfxInfo.fragmentShader != nullptr)
{
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
VkPipelineShaderStageCreateInfo& fragmentInfo = stageInfos[createInfo.stageCount++];
fragmentInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragmentInfo.module = fragment->getModuleHandle();
fragmentInfo.pName = fragment->getEntryPointName();
hashStruct.fragmentHash = fragment->getShaderHash();
}
VkPipelineVertexInputStateCreateInfo vertexInput =
init::PipelineVertexInputStateCreateInfo();
PVertexDeclaration vertexDecl = gfxInfo.vertexDeclaration;
auto vertexStreams = vertexDecl->elementList;
uint32 bindingNum = 0;
uint32 bindingsMask = 0;
uint32 attributesNum = 0;
Array<VkVertexInputBindingDescription> bindings;
Array<VkVertexInputAttributeDescription> attributes;
Map<uint32, uint32> bindingToStream;
Map<uint32, uint32> streamToBinding;
assert(DEFAULT_ALLOC_SIZE == 16);
std::memset(bindings.data(), 0, sizeof(VkVertexInputBindingDescription) * 16);
std::memset(attributes.data(), 0, sizeof(VkVertexInputAttributeDescription) * 16);
for(auto& element : vertexStreams)
{
//if((1 << element.attributeIndex) & vertexAttributeMask) // TODO: attribute mask
{
if(element.streamIndex >= bindings.size())
{
bindings.resize(element.streamIndex + 1); // This should not cause any actual allocations
}
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;
}
}
}
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++;
}
for(auto& element : vertexStreams)
{
//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;
}
std::memcpy(hashStruct.bindings, bindings.data(), bindings.size() * sizeof(VkVertexInputBindingDescription));
std::memcpy(hashStruct.attribs, attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription));
vertexInput.pVertexBindingDescriptions = bindings.data();
vertexInput.vertexBindingDescriptionCount = (uint32)bindings.size();
vertexInput.pVertexAttributeDescriptions = attributes.data();
vertexInput.vertexAttributeDescriptionCount = (uint32)attributes.size();
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
init::PipelineInputAssemblyStateCreateInfo(
cast(gfxInfo.topology),
0,
false
);
hashStruct.inputAssembly = assemblyInfo;
VkPipelineViewportStateCreateInfo viewportInfo =
init::PipelineViewportStateCreateInfo(
1,
1,
0
);
hashStruct.viewport = viewportInfo;
VkPipelineRasterizationStateCreateInfo rasterizationState =
init::PipelineRasterizationStateCreateInfo(
cast(gfxInfo.rasterizationState.polygonMode),
gfxInfo.rasterizationState.cullMode,
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
0
);
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor;
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
hashStruct.rasterization = rasterizationState;
VkPipelineMultisampleStateCreateInfo multisampleState =
init::PipelineMultisampleStateCreateInfo(
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
0);
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
hashStruct.multisample = multisampleState;
VkPipelineDepthStencilStateCreateInfo depthStencilState =
init::PipelineDepthStencilStateCreateInfo(
gfxInfo.depthStencilState.depthTestEnable,
gfxInfo.depthStencilState.depthWriteEnable,
cast(gfxInfo.depthStencilState.depthCompareOp)
);
hashStruct.depthStencil = depthStencilState;
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
Array<VkPipelineColorBlendAttachmentState> blendAttachments(colorAttachments.size());
for(uint32 i = 0; i < colorAttachments.size(); ++i)
{
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
VkPipelineColorBlendAttachmentState& blendAttachment = blendAttachments[i];
blendAttachment.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp;
blendAttachment.blendEnable = attachment.blendEnable;
blendAttachment.colorBlendOp = (VkBlendOp)attachment.colorBlendOp;
blendAttachment.colorWriteMask = attachment.colorWriteMask;
blendAttachment.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor;
blendAttachment.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor;
blendAttachment.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor;
blendAttachment.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor;
hashStruct.blendAttachments[i] = blendAttachment;
}
VkPipelineColorBlendStateCreateInfo blendState =
init::PipelineColorBlendStateCreateInfo(
(uint32)blendAttachments.size(),
blendAttachments.data()
);
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(float)*4);
hashStruct.blendState = blendState;
hashStruct.blendState.pAttachments = nullptr;
uint32 numDynamicEnabled = 0;
StaticArray<VkDynamicState, 2> dynamicEnabled;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
VkPipelineDynamicStateCreateInfo dynamicState =
init::PipelineDynamicStateCreateInfo(
dynamicEnabled.data(),
numDynamicEnabled,
0
);
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
hashStruct.pipelineLayoutHash = layout->getHash();
uint32 hash = CRC::Calculate(&hashStruct, sizeof(PipelineCreateHashStruct), CRC::CRC_32());
VkPipeline pipelineHandle;
std::scoped_lock lock(createdPipelinesLock);
auto foundPipeline = createdPipelines.find(hash);
if (foundPipeline != createdPipelines.end())
{
pipelineHandle = foundPipeline->value;
}
else
{
createInfo.pStages = stageInfos;
createInfo.pVertexInputState = &vertexInput;
createInfo.pInputAssemblyState = &assemblyInfo;
createInfo.pTessellationState = &tessInfo;
createInfo.pViewportState = &viewportInfo;
createInfo.pRasterizationState = &rasterizationState;
createInfo.pMultisampleState = &multisampleState;
createInfo.pDepthStencilState = &depthStencilState;
createInfo.pColorBlendState = &blendState;
createInfo.pDynamicState = &dynamicState;
createInfo.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle();
createInfo.layout = layout->getHandle();
createInfo.subpass = 0;
auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
createdPipelines[hash] = pipelineHandle;
std::cout << "Gfx creation time: " << delta << std::endl;
}
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo);
return result;
}
PComputePipeline PipelineCache::createPipeline(const ComputePipelineCreateInfo& computeInfo)
{
VkComputePipelineCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
createInfo.pNext = 0;
createInfo.flags = 0;
createInfo.basePipelineIndex = 0;
createInfo.basePipelineHandle = VK_NULL_HANDLE;
auto layout = computeInfo.pipelineLayout.cast<PipelineLayout>();
createInfo.layout = layout->getHandle();
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
createInfo.stage = init::PipelineShaderStageCreateInfo(
VK_SHADER_STAGE_COMPUTE_BIT,
computeStage->getModuleHandle(),
computeStage->getEntryPointName());
VkPipeline pipelineHandle;
auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Compute creation time: " << delta << std::endl;
PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout, computeInfo);
return result;
}
+2 -17
View File
@@ -30,24 +30,9 @@ Material::~Material()
{ {
} }
Gfx::PDescriptorSet Material::createDescriptorSet() PMaterialInstance Seele::Material::instantiate()
{ {
Gfx::PDescriptorSet descriptorSet = layout->allocateDescriptorSet(); return new MaterialInstance(instanceId++, graphics, this, layout, parameters, uniformBinding, uniformDataSize);
BulkResourceData uniformUpdate = {
.size = uniformDataSize,
.data = (uint8*)uniformData.data(),
};
for(auto param : parameters)
{
param->updateDescriptorSet(descriptorSet, uniformData.data());
}
if(uniformUpdate.size != 0)
{
uniformBuffer->updateContents(uniformUpdate);
descriptorSet->updateBuffer(uniformBinding, uniformBuffer);
}
descriptorSet->writeChanges();
return descriptorSet;
} }
void Material::save(ArchiveBuffer& buffer) const void Material::save(ArchiveBuffer& buffer) const
+1 -1
View File
@@ -1,6 +1,6 @@
#pragma once #pragma once
#include "ShaderExpression.h" #include "ShaderExpression.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/Descriptor.h"
namespace Seele namespace Seele
{ {
+6 -2
View File
@@ -4,8 +4,8 @@
using namespace Seele; using namespace Seele;
MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorSet descriptor, Array<PShaderParameter> params, uint32 uniformBinding, uint32 uniformSize) MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout descriptor, Array<PShaderParameter> params, uint32 uniformBinding, uint32 uniformSize)
: id(id), graphics(graphics), baseMaterial(baseMaterial), descriptor(descriptor), parameters(params), uniformBinding(uniformBinding) : id(id), graphics(graphics), baseMaterial(baseMaterial), layout(layout), parameters(params), uniformBinding(uniformBinding)
{ {
uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
.resourceData = { .resourceData = {
@@ -21,3 +21,7 @@ MaterialInstance::~MaterialInstance()
{ {
} }
void Seele::MaterialInstance::updateDescriptor()
{
}
+3 -1
View File
@@ -1,12 +1,13 @@
#pragma once #pragma once
#include "Material.h" #include "Material.h"
#include "Graphics/Buffer.h"
namespace Seele namespace Seele
{ {
class MaterialInstance class MaterialInstance
{ {
public: public:
MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorSet descriptor, Array<PShaderParameter> params, uint32 uniformBinding, uint32 uniformSize); MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout descriptor, Array<PShaderParameter> params, uint32 uniformBinding, uint32 uniformSize);
~MaterialInstance(); ~MaterialInstance();
void updateDescriptor(); void updateDescriptor();
Gfx::PDescriptorSet getDescriptorSet() const; Gfx::PDescriptorSet getDescriptorSet() const;
@@ -18,6 +19,7 @@ private:
uint32 uniformBinding; uint32 uniformBinding;
Gfx::PUniformBuffer uniformBuffer; Gfx::PUniformBuffer uniformBuffer;
Array<PShaderParameter> parameters; Array<PShaderParameter> parameters;
Gfx::PDescriptorLayout layout;
Gfx::PDescriptorSet descriptor; Gfx::PDescriptorSet descriptor;
PMaterial baseMaterial; PMaterial baseMaterial;
uint64 id; uint64 id;
+2 -1
View File
@@ -1,8 +1,9 @@
#include "ShaderExpression.h" #include "ShaderExpression.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/Resources.h"
#include "Asset/TextureAsset.h" #include "Asset/TextureAsset.h"
#include "Asset/AssetRegistry.h" #include "Asset/AssetRegistry.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/Descriptor.h"
using namespace Seele; using namespace Seele;
+5 -2
View File
@@ -1,13 +1,16 @@
target_sources(Engine target_sources(Engine
PRIVATE PRIVATE
EventManager.h EventManager.h
LightEnvironment.h
LightEnvironment.cpp
Util.h Util.h
Scene.cpp Scene.h
Scene.h) Scene.cpp)
target_sources(Engine target_sources(Engine
PUBLIC FILE_SET HEADERS PUBLIC FILE_SET HEADERS
FILES FILES
EventManager.h EventManager.h
LightEnvironment.h
Util.h Util.h
Scene.h) Scene.h)
+35
View File
@@ -0,0 +1,35 @@
#include "LightEnvironment.h"
#include "Graphics/Graphics.h"
using namespace Seele;
LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
: graphics(graphics)
{
layout = graphics->createDescriptorLayout("LightEnvironment");
layout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
layout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
layout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
layout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
}
LightEnvironment::~LightEnvironment()
{
}
void LightEnvironment::reset()
{
}
void LightEnvironment::addDirectionalLight(Component::DirectionalLight dirLight)
{
}
void LightEnvironment::addPointLight(Component::PointLight pointLight)
{
}
void LightEnvironment::commit()
{
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "Graphics/Descriptor.h"
#include "Graphics/Buffer.h"
#include "Component/DirectionalLight.h"
#include "Component/PointLight.h"
namespace Seele
{
class LightEnvironment
{
public:
LightEnvironment(Gfx::PGraphics graphics);
~LightEnvironment();
void reset();
void addDirectionalLight(Component::DirectionalLight dirLight);
void addPointLight(Component::PointLight pointLight);
void commit();
private:
#define MAX_DIRECTIONAL_LIGHTS 4
#define MAX_POINT_LIGHTS 256
Gfx::PShaderBuffer directionalLights;
Gfx::PUniformBuffer numDirectional;
Gfx::PShaderBuffer pointLights;
Gfx::PUniformBuffer numPoints;;
Array<Component::DirectionalLight> dirs;
Array<Component::PointLight> points;
Gfx::PDescriptorLayout layout;
Gfx::PDescriptorSet set;
Gfx::PGraphics graphics;
};
DEFINE_REF(LightEnvironment)
}
+1 -12
View File
@@ -1,7 +1,7 @@
#include "Scene.h" #include "Scene.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/Mesh.h" #include "Graphics/Mesh.h"
#include "Component/StaticMesh.h" #include "Component/Mesh.h"
#include "Component/Transform.h" #include "Component/Transform.h"
#include "Asset/AssetRegistry.h" #include "Asset/AssetRegistry.h"
#include "Asset/TextureAsset.h" #include "Asset/TextureAsset.h"
@@ -81,14 +81,3 @@ LightEnv Scene::getLightBuffer()
}); });
return lightEnv; return lightEnv;
} }
Component::Skybox Scene::getSkybox()
{
return Seele::Component::Skybox {
.day = AssetRegistry::findTexture("FS000_Day_01")->getTexture().cast<Gfx::TextureCube>(),
.night = AssetRegistry::findTexture("FS000_Night_01")->getTexture().cast<Gfx::TextureCube>(),
.fogColor = Vector(0.2, 0.1, 0.6),
.blendFactor = 0,
};
}

Some files were not shown because too many files have changed in this diff Show More