Refactoring graphics
This commit is contained in:
@@ -8,36 +8,28 @@ struct ComputeShaderInput
|
||||
uint3 dispatchThreadID : SV_DispatchThreadID;
|
||||
uint groupIndex : SV_GroupIndex;
|
||||
};
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 1)
|
||||
cbuffer DispatchParams
|
||||
struct CullingParams
|
||||
{
|
||||
uint3 numThreadGroups;
|
||||
uint pad0;
|
||||
uint3 numThreads;
|
||||
uint pad1;
|
||||
}
|
||||
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 2)
|
||||
Texture2D depthTextureVS;
|
||||
Texture2D depthTextureVS;
|
||||
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 3)
|
||||
globallycoherent RWShaderBuffer<uint> oLightIndexCounter;
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 4)
|
||||
globallycoherent RWShaderBuffer<uint> tLightIndexCounter;
|
||||
globallycoherent RWStructuredBuffer<uint> oLightIndexCounter;
|
||||
globallycoherent RWStructuredBuffer<uint> tLightIndexCounter;
|
||||
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 5)
|
||||
RWShaderBuffer<uint> oLightIndexList;
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 6)
|
||||
RWShaderBuffer<uint> tLightIndexList;
|
||||
RWStructuredBuffer<uint> oLightIndexList;
|
||||
RWStructuredBuffer<uint> tLightIndexList;
|
||||
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 7)
|
||||
RWTexture2D<uint2> oLightGrid;
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 8)
|
||||
RWTexture2D<uint2> tLightGrid;
|
||||
RWTexture2D<uint2> oLightGrid;
|
||||
RWTexture2D<uint2> tLightGrid;
|
||||
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 9)
|
||||
ShaderBuffer<Frustum> frustums;
|
||||
StructuredBuffer<Frustum> frustums;
|
||||
|
||||
};
|
||||
ParameterBlock<CullingParams> gCullingParams;
|
||||
// Debug
|
||||
//layout(set = INDEX_VIEW_PARAMS, binding = 10)
|
||||
//Texture2D lightCountHeatMap;
|
||||
@@ -83,7 +75,7 @@ void tAppendLight(uint lightIndex)
|
||||
void cullLights(ComputeShaderInput in)
|
||||
{
|
||||
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);
|
||||
if(in.groupIndex == 0)
|
||||
@@ -92,7 +84,7 @@ void cullLights(ComputeShaderInput in)
|
||||
uMaxDepth = 0x0;
|
||||
oLightCount = 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();
|
||||
@@ -111,9 +103,9 @@ void cullLights(ComputeShaderInput in)
|
||||
|
||||
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?
|
||||
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
|
||||
{
|
||||
@@ -129,23 +121,23 @@ void cullLights(ComputeShaderInput in)
|
||||
|
||||
if(in.groupIndex == 0)
|
||||
{
|
||||
InterlockedAdd(oLightIndexCounter[0], oLightCount, oLightIndexStartOffset);
|
||||
oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount);
|
||||
InterlockedAdd(gCullingParams.oLightIndexCounter[0], oLightCount, oLightIndexStartOffset);
|
||||
gCullingParams.oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount);
|
||||
|
||||
InterlockedAdd(tLightIndexCounter[0], tLightCount, tLightIndexStartOffset);
|
||||
tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount);
|
||||
InterlockedAdd(gCullingParams.tLightIndexCounter[0], tLightCount, tLightIndexStartOffset);
|
||||
gCullingParams.tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
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 ( uint k = in.groupIndex; k < tLightCount; k += BLOCK_SIZE * BLOCK_SIZE )
|
||||
{
|
||||
tLightIndexList[tLightIndexStartOffset + k] = tLightList[k];
|
||||
gCullingParams.tLightIndexList[tLightIndexStartOffset + k] = tLightList[k];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import Common;
|
||||
|
||||
interface ILightEnv
|
||||
{
|
||||
float3 illuminate<B:IBRDF>(MaterialFragmentParameter input, B brdf);
|
||||
float3 illuminate<B:IBRDF>(MaterialParameter input, B brdf);
|
||||
};
|
||||
|
||||
struct DirectionalLight : ILightEnv
|
||||
@@ -12,9 +12,9 @@ struct DirectionalLight : ILightEnv
|
||||
float4 color;
|
||||
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);
|
||||
}
|
||||
};
|
||||
@@ -24,9 +24,9 @@ struct PointLight : ILightEnv
|
||||
float4 position_WS;
|
||||
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;
|
||||
float d = length(lightDir_TS);
|
||||
float illuminance = max(1 - d / colorRange.w, 0);
|
||||
@@ -48,7 +48,7 @@ struct PointLight : ILightEnv
|
||||
}
|
||||
for(int i = 0; i < 4 && result; ++i)
|
||||
{
|
||||
if(insidePlane(frustum.planes[i]))
|
||||
if(insidePlane(frustum.sides[i]))
|
||||
{
|
||||
//result = false;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ struct PointLight : ILightEnv
|
||||
}
|
||||
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;
|
||||
uint numDirectionalLights;
|
||||
StructureBuffer<PointLight> pointLights;
|
||||
StructuredBuffer<PointLight> pointLights;
|
||||
uint numPointLights;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@ import VertexData;
|
||||
|
||||
struct MaterialParameter
|
||||
{
|
||||
float3 position_TS;
|
||||
float3 worldPosition;
|
||||
float2 texCoords;
|
||||
float3 normal;
|
||||
float3 tangent;
|
||||
float3 biTangent;
|
||||
float3 viewDir_TS;
|
||||
|
||||
static MaterialParameter create(VertexAttributes attrib)
|
||||
{
|
||||
|
||||
+326
-292
@@ -1,73 +1,114 @@
|
||||
#version 450
|
||||
#extension GL_EXT_mesh_shader : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types : require
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
layout(row_major) uniform;
|
||||
layout(row_major) buffer;
|
||||
|
||||
#line 1 0
|
||||
struct InstanceData_0
|
||||
#line 11 0
|
||||
struct CullingParams_0
|
||||
{
|
||||
mat4x4 transformMatrix_0;
|
||||
uvec3 numThreadGroups_0;
|
||||
uint pad0_0;
|
||||
uvec3 numThreads_0;
|
||||
uint pad1_0;
|
||||
};
|
||||
|
||||
|
||||
#line 45 1
|
||||
layout(std430, binding = 0, set = 2) readonly buffer StructuredBuffer_InstanceData_t_0 {
|
||||
InstanceData_0 _data[];
|
||||
} scene_instances_0;
|
||||
|
||||
#line 1 2
|
||||
struct MeshletDescription_0
|
||||
#line 35 1
|
||||
layout(binding = 0, set = 1)
|
||||
layout(std140) uniform _S1
|
||||
{
|
||||
uint vertexCount_0;
|
||||
uint primitiveCount_0;
|
||||
uint vertexOffset_0;
|
||||
uint primitiveOffset_0;
|
||||
};
|
||||
uvec3 numThreadGroups_0;
|
||||
uint pad0_0;
|
||||
uvec3 numThreads_0;
|
||||
uint pad1_0;
|
||||
}gCullingParams_0;
|
||||
|
||||
#line 2113 2
|
||||
layout(binding = 1, set = 1)
|
||||
uniform texture2D gCullingParams_depthTextureVS_0;
|
||||
|
||||
|
||||
#line 46 1
|
||||
layout(std430, binding = 0, set = 1) readonly buffer StructuredBuffer_MeshletDescription_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 {
|
||||
#line 11 0
|
||||
layout(std430, binding = 2, set = 1) buffer StructuredBuffer_uint_t_0 {
|
||||
uint _data[];
|
||||
} meshlets_vertexIndices_0;
|
||||
} gCullingParams_oLightIndexCounter_0;
|
||||
|
||||
#line 35 3
|
||||
layout(std430, binding = 0, set = 3) readonly buffer StructuredBuffer_float3_t_0 {
|
||||
vec3 _data[];
|
||||
} vertexData_positions_0;
|
||||
#line 11
|
||||
layout(std430, binding = 3, set = 1) buffer StructuredBuffer_uint_t_1 {
|
||||
uint _data[];
|
||||
} gCullingParams_tLightIndexCounter_0;
|
||||
|
||||
#line 35
|
||||
layout(std430, binding = 1, set = 3) readonly buffer StructuredBuffer_float2_t_0 {
|
||||
vec2 _data[];
|
||||
} vertexData_texCoords_0;
|
||||
#line 11
|
||||
layout(std430, binding = 4, set = 1) buffer StructuredBuffer_uint_t_2 {
|
||||
uint _data[];
|
||||
} gCullingParams_oLightIndexList_0;
|
||||
|
||||
#line 35
|
||||
layout(std430, binding = 2, set = 3) readonly buffer StructuredBuffer_float3_t_1 {
|
||||
vec3 _data[];
|
||||
} vertexData_normals_0;
|
||||
#line 11
|
||||
layout(std430, binding = 5, set = 1) buffer StructuredBuffer_uint_t_3 {
|
||||
uint _data[];
|
||||
} gCullingParams_tLightIndexList_0;
|
||||
|
||||
#line 35
|
||||
layout(std430, binding = 3, set = 3) readonly buffer StructuredBuffer_float3_t_2 {
|
||||
vec3 _data[];
|
||||
} vertexData_tangents_0;
|
||||
#line 1572 2
|
||||
layout(rg32ui)
|
||||
layout(binding = 6, set = 1)
|
||||
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
|
||||
{
|
||||
mat4x4 viewMatrix_0;
|
||||
@@ -77,7 +118,7 @@ struct ViewParameter_0
|
||||
};
|
||||
|
||||
layout(binding = 0)
|
||||
layout(std140) uniform _S1
|
||||
layout(std140) uniform _S3
|
||||
{
|
||||
mat4x4 viewMatrix_0;
|
||||
mat4x4 projectionMatrix_0;
|
||||
@@ -85,264 +126,257 @@ layout(std140) uniform _S1
|
||||
vec2 screenDimensions_0;
|
||||
}viewParams_0;
|
||||
|
||||
#line 1267 5
|
||||
out gl_MeshPerVertexEXT
|
||||
{
|
||||
vec4 gl_Position;
|
||||
} gl_MeshVerticesEXT[64];
|
||||
#line 39 0
|
||||
shared uint uMinDepth_0;
|
||||
|
||||
|
||||
#line 24 1
|
||||
shared uint gs_numVertices_0;
|
||||
#line 40
|
||||
shared uint uMaxDepth_0;
|
||||
|
||||
|
||||
#line 5 3
|
||||
struct StaticMeshVertexAttributes_0
|
||||
{
|
||||
vec4 clipPosition_0;
|
||||
vec3 worldPosition_0;
|
||||
vec2 texCoords_0;
|
||||
vec3 normal_0;
|
||||
vec3 tangent_0;
|
||||
vec3 biTangent_0;
|
||||
};
|
||||
|
||||
shared uint oLightCount_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
|
||||
shared uvec3 gs_indices_0[126];
|
||||
#line 50
|
||||
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
|
||||
uint _S11 = m_0.primitiveCount_0 - 1U;
|
||||
|
||||
#line 82
|
||||
uint v_0 = min(gl_LocalInvocationIndex, _S10);
|
||||
|
||||
|
||||
|
||||
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(;;)
|
||||
void tAppendLight_0(uint lightIndex_0)
|
||||
{
|
||||
uint index_0;
|
||||
((index_0) = atomicAdd((tLightCount_0), (1U)));
|
||||
if(index_0 < 1024U)
|
||||
{
|
||||
tLightList_0[index_0] = lightIndex_0;
|
||||
|
||||
#line 51
|
||||
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 67
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "FontAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Vulkan/VulkanGraphicsEnums.h"
|
||||
#include "Graphics/Vulkan/Enums.h"
|
||||
#include "Graphics/Texture.h"
|
||||
#include <ktx.h>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "AssetRegistry.h"
|
||||
#include "Graphics/VertexShaderInput.h"
|
||||
#include "Material/MaterialInterface.h"
|
||||
#include "Graphics/StaticMeshVertexInput.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "TextureAsset.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "Graphics/Vulkan/VulkanGraphicsEnums.h"
|
||||
#include "Graphics/Vulkan/Enums.h"
|
||||
#include "ktx.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "Component.h"
|
||||
#include "Math/Matrix.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Transform.h"
|
||||
|
||||
namespace Seele
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "Asset/MeshAsset.h"
|
||||
#include "Graphics/VertexData.h"
|
||||
#include "Graphics/TopologyData.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
namespace Seele
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Texture.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
@@ -310,6 +310,20 @@ public:
|
||||
}
|
||||
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
|
||||
{
|
||||
return allocator;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,47 @@
|
||||
target_sources(Engine
|
||||
PRIVATE
|
||||
Buffer.h
|
||||
Buffer.cpp
|
||||
DebugVertex.h
|
||||
GraphicsResources.h
|
||||
GraphicsResources.cpp
|
||||
GraphicsInitializer.h
|
||||
GraphicsEnums.h
|
||||
GraphicsEnums.cpp
|
||||
Descriptor.h
|
||||
Descriptor.cpp
|
||||
Enums.h
|
||||
Enums.cpp
|
||||
Graphics.h
|
||||
Graphics.cpp
|
||||
Initializer.h
|
||||
Mesh.h
|
||||
Mesh.cpp
|
||||
RenderTarget.h
|
||||
RenderTarget.cpp
|
||||
Resources.h
|
||||
Resources.cpp
|
||||
Shader.h
|
||||
Shader.cpp
|
||||
ShaderCompiler.h
|
||||
ShaderCompiler.cpp
|
||||
StaticMeshVertexData.h
|
||||
StaticMeshVertexData.cpp
|
||||
Texture.h
|
||||
Texture.cpp
|
||||
VertexData.h
|
||||
VertexData.cpp)
|
||||
|
||||
target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
FILES
|
||||
Buffer.h
|
||||
DebugVertex.h
|
||||
GraphicsResources.h
|
||||
GraphicsInitializer.h
|
||||
GraphicsEnums.h
|
||||
Descriptor.h
|
||||
Graphics.h
|
||||
Initializer.h
|
||||
Mesh.h
|
||||
RenderTarget.h
|
||||
Resources.h
|
||||
Shader.h
|
||||
ShaderCompiler.h
|
||||
StaticMeshVertexData.h
|
||||
Texture.h
|
||||
VertexData.h)
|
||||
|
||||
add_subdirectory(RenderPass/)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,31 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "GraphicsResources.h"
|
||||
#include "Resources.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "ShaderCompiler.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -46,12 +64,12 @@ public:
|
||||
virtual PComputeCommand createComputeCommand(const std::string& name = "") = 0;
|
||||
virtual PVertexDeclaration createVertexDeclaration(const Array<VertexElement>& element) = 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 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 PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
#include "GraphicsEnums.h"
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Math/Math.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -129,7 +130,7 @@ struct SePushConstantRange
|
||||
};
|
||||
struct VertexElement
|
||||
{
|
||||
uint8 streamIndex;
|
||||
uint8 binding;
|
||||
uint8 offset;
|
||||
SeFormat vertexFormat;
|
||||
uint8 attributeIndex;
|
||||
@@ -188,56 +189,116 @@ struct ColorBlendState
|
||||
} blendAttachments[16];
|
||||
float blendConstants[4];
|
||||
};
|
||||
} // namespace Gfx
|
||||
DECLARE_NAME_REF(Gfx, VertexDeclaration)
|
||||
DECLARE_NAME_REF(Gfx, VertexShader)
|
||||
DECLARE_NAME_REF(Gfx, ControlShader)
|
||||
DECLARE_NAME_REF(Gfx, EvaluationShader)
|
||||
DECLARE_NAME_REF(Gfx, GeometryShader)
|
||||
DECLARE_NAME_REF(Gfx, FragmentShader)
|
||||
DECLARE_NAME_REF(Gfx, ComputeShader)
|
||||
DECLARE_NAME_REF(Gfx, PipelineLayout)
|
||||
DECLARE_NAME_REF(Gfx, RenderPass)
|
||||
struct GraphicsPipelineCreateInfo
|
||||
|
||||
DECLARE_REF(VertexDeclaration)
|
||||
DECLARE_REF(VertexShader)
|
||||
DECLARE_REF(FragmentShader)
|
||||
DECLARE_REF(TaskShader)
|
||||
DECLARE_REF(MeshShader)
|
||||
DECLARE_REF(ComputeShader)
|
||||
DECLARE_REF(PipelineLayout)
|
||||
DECLARE_REF(RenderPass)
|
||||
struct LegacyPipelineCreateInfo
|
||||
{
|
||||
Gfx::PVertexDeclaration vertexDeclaration;
|
||||
Gfx::PVertexShader vertexShader;
|
||||
Gfx::PControlShader controlShader;
|
||||
Gfx::PEvaluationShader evalShader;
|
||||
Gfx::PGeometryShader geometryShader;
|
||||
Gfx::PFragmentShader fragmentShader;
|
||||
Gfx::PRenderPass renderPass;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::SePrimitiveTopology topology;
|
||||
Gfx::RasterizationState rasterizationState;
|
||||
Gfx::DepthStencilState depthStencilState;
|
||||
Gfx::MultisampleState multisampleState;
|
||||
Gfx::ColorBlendState colorBlend;
|
||||
GraphicsPipelineCreateInfo()
|
||||
{
|
||||
std::memset((void*)this, 0, sizeof(*this));
|
||||
topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
rasterizationState.cullMode = Gfx::SE_CULL_MODE_BACK_BIT;
|
||||
rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL;
|
||||
rasterizationState.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL;
|
||||
depthStencilState.minDepthBounds = 0.0f;
|
||||
depthStencilState.maxDepthBounds = 1.0f;
|
||||
depthStencilState.stencilTestEnable = false;
|
||||
depthStencilState.depthWriteEnable = true;
|
||||
depthStencilState.depthTestEnable = true;
|
||||
multisampleState.samples = 1;
|
||||
colorBlend.attachmentCount = 0;
|
||||
colorBlend.logicOpEnable = false;
|
||||
colorBlend.blendConstants[0] = 1.0f;
|
||||
colorBlend.blendConstants[1] = 1.0f;
|
||||
colorBlend.blendConstants[2] = 1.0f;
|
||||
colorBlend.blendConstants[3] = 1.0f;
|
||||
colorBlend.blendAttachments[0].colorWriteMask =
|
||||
PVertexDeclaration vertexDeclaration;
|
||||
SePrimitiveTopology topology;
|
||||
PVertexShader vertexShader;
|
||||
PFragmentShader fragmentShader;
|
||||
PRenderPass renderPass;
|
||||
PPipelineLayout pipelineLayout;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
LegacyPipelineCreateInfo()
|
||||
: topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
||||
, 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;
|
||||
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
|
||||
@@ -249,4 +310,5 @@ struct ComputePipelineCreateInfo
|
||||
std::memset((void*)this, 0, sizeof(*this));
|
||||
}
|
||||
};
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -1,12 +1,9 @@
|
||||
#include "Mesh.h"
|
||||
#include "VertexShaderInput.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Mesh::Mesh(PVertexShaderInput vertexInput, Gfx::PIndexBuffer indexBuffer)
|
||||
: vertexInput(vertexInput)
|
||||
, indexBuffer(indexBuffer)
|
||||
Mesh::Mesh()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include "GraphicsResources.h"
|
||||
#include "Asset/MaterialInstanceAsset.h"
|
||||
#include "VertexData.h"
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Math/Vector.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
|
||||
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)
|
||||
{
|
||||
BulkResourceData uniformUpdate;
|
||||
|
||||
@@ -10,7 +10,6 @@ class BasePass : public RenderPass
|
||||
public:
|
||||
BasePass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~BasePass();
|
||||
virtual void readScene() override;
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "DebugPass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Graphics/DebugVertex.h"
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ void DepthPrepass::render()
|
||||
// ViewData => global, static
|
||||
// Material => per material
|
||||
// VertexData => per meshtype
|
||||
// SceneData => per topology
|
||||
// SceneData => per material instance
|
||||
Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
Gfx::PPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout);
|
||||
layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout());
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics)
|
||||
: RenderPass(graphics)
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ void LightCullingPass::publishOutputs()
|
||||
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
|
||||
cullingShader = graphics->createComputeShader(createInfo);
|
||||
|
||||
ComputePipelineCreateInfo pipelineInfo;
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = cullingLayout;
|
||||
cullingPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
@@ -243,7 +243,7 @@ void LightCullingPass::setupFrustums()
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
frustumShader = graphics->createComputeShader(createInfo);
|
||||
|
||||
ComputePipelineCreateInfo pipelineInfo;
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = frustumShader;
|
||||
pipelineInfo.pipelineLayout = frustumLayout;
|
||||
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace Seele
|
||||
@@ -8,14 +8,10 @@ namespace Seele
|
||||
DECLARE_REF(CameraActor)
|
||||
DECLARE_REF(Scene)
|
||||
DECLARE_REF(Viewport)
|
||||
struct LightCullingPassData
|
||||
{
|
||||
LightEnv lightEnv;
|
||||
};
|
||||
class LightCullingPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
LightCullingPass(Gfx::PGraphics graphics);
|
||||
LightCullingPass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~LightCullingPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "Math/Math.h"
|
||||
#include "RenderGraphResources.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Graphics/TopologyData.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Graphics/VertexData.h"
|
||||
@@ -42,19 +41,6 @@ protected:
|
||||
Vector2 screenDimensions;
|
||||
Vector2 pad0;
|
||||
} 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;
|
||||
Gfx::PRenderPass renderPass;
|
||||
Gfx::PGraphics graphics;
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
#include "SkyboxRenderPass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics)
|
||||
: RenderPass(graphics)
|
||||
SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: 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 = {
|
||||
// Back
|
||||
Vector(-512, -512, 512),
|
||||
@@ -91,8 +98,8 @@ void SkyboxRenderPass::beginFrame(const Component::Camera& cam)
|
||||
descriptorLayout->reset();
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
descriptorSet->updateTexture(1, passData.skybox.day);
|
||||
descriptorSet->updateTexture(2, passData.skybox.night);
|
||||
descriptorSet->updateTexture(1, skybox.day);
|
||||
descriptorSet->updateTexture(2, skybox.night);
|
||||
descriptorSet->updateSampler(3, skyboxSampler);
|
||||
descriptorSet->writeChanges();
|
||||
}
|
||||
@@ -104,9 +111,9 @@ void SkyboxRenderPass::render()
|
||||
renderCommand->setViewport(viewport);
|
||||
renderCommand->bindPipeline(pipeline);
|
||||
renderCommand->bindDescriptor(descriptorSet);
|
||||
renderCommand->bindVertexBuffer({ VertexInputStream(0, 0, 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, sizeof(Vector), sizeof(float), &passData.skybox.blendFactor);
|
||||
renderCommand->bindVertexBuffer({ cubeBuffer });
|
||||
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), &skybox.blendFactor);
|
||||
renderCommand->draw(36, 1, 0, 0);
|
||||
graphics->executeCommands(Array{ renderCommand });
|
||||
graphics->endRenderPass();
|
||||
@@ -170,7 +177,7 @@ void SkyboxRenderPass::createRenderPass()
|
||||
|
||||
Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({
|
||||
Gfx::VertexElement {
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = 0,
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.attributeIndex = 0,
|
||||
@@ -178,7 +185,7 @@ void SkyboxRenderPass::createRenderPass()
|
||||
}
|
||||
});
|
||||
|
||||
GraphicsPipelineCreateInfo gfxInfo;
|
||||
Gfx::LegacyPipelineCreateInfo gfxInfo;
|
||||
gfxInfo.vertexDeclaration = vertexDecl;
|
||||
gfxInfo.vertexShader = vertexShader;
|
||||
gfxInfo.fragmentShader = fragmentShader;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Component/Skybox.h"
|
||||
|
||||
namespace Seele
|
||||
@@ -11,7 +11,7 @@ DECLARE_REF(Viewport)
|
||||
class SkyboxRenderPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
SkyboxRenderPass(Gfx::PGraphics graphics);
|
||||
SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~SkyboxRenderPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -26,6 +26,7 @@ private:
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::PSamplerState skyboxSampler;
|
||||
Component::Skybox skybox;
|
||||
};
|
||||
DEFINE_REF(SkyboxRenderPass)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include "TextPass.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/VertexShaderInput.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
TextPass::TextPass(Gfx::PGraphics graphics)
|
||||
: RenderPass(graphics)
|
||||
TextPass::TextPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ TextPass::~TextPass()
|
||||
|
||||
void TextPass::beginFrame(const Component::Camera&)
|
||||
{
|
||||
for(TextRender& render : passData.texts)
|
||||
for(TextRender& render : texts)
|
||||
{
|
||||
FontData& fd = getFontData(render.font);
|
||||
TextResources& res = textResources[render.font].add();
|
||||
@@ -82,7 +82,7 @@ void TextPass::render()
|
||||
for(const auto& resource : res)
|
||||
{
|
||||
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->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
|
||||
@@ -121,7 +121,7 @@ void TextPass::createRenderPass()
|
||||
fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
Array<Gfx::VertexElement> elements;
|
||||
elements.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(GlyphInstanceData, position),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
|
||||
.attributeIndex = 0,
|
||||
@@ -129,7 +129,7 @@ void TextPass::createRenderPass()
|
||||
.bInstanced = 1
|
||||
});
|
||||
elements.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(GlyphInstanceData, widthHeight),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
|
||||
.attributeIndex = 1,
|
||||
@@ -137,7 +137,7 @@ void TextPass::createRenderPass()
|
||||
.bInstanced = 1
|
||||
});
|
||||
elements.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(GlyphInstanceData, glyphIndex),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
|
||||
.attributeIndex = 2,
|
||||
@@ -187,7 +187,7 @@ void TextPass::createRenderPass()
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
|
||||
GraphicsPipelineCreateInfo pipelineInfo;
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.vertexDeclaration = declaration;
|
||||
pipelineInfo.vertexShader = vertexShader;
|
||||
pipelineInfo.fragmentShader = fragmentShader;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "UI/RenderHierarchy.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Asset/FontAsset.h"
|
||||
|
||||
namespace Seele
|
||||
@@ -20,7 +20,7 @@ struct TextRender
|
||||
class TextPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
TextPass(Gfx::PGraphics graphics);
|
||||
TextPass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~TextPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
Gfx::PDescriptorSet textureArraySet;
|
||||
TextData textData;
|
||||
};
|
||||
std::map<PFontAsset, Array<TextResources>> textResources;
|
||||
Map<PFontAsset, Array<TextResources>> textResources;
|
||||
|
||||
Gfx::PRenderTargetAttachment renderTarget;
|
||||
Gfx::PRenderTargetAttachment depthAttachment;
|
||||
@@ -78,6 +78,7 @@ private:
|
||||
Gfx::PFragmentShader fragmentShader;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Array<TextRender> texts;
|
||||
};
|
||||
DEFINE_REF(TextPass);
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "UIPass.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
UIPass::UIPass(Gfx::PGraphics graphics)
|
||||
: RenderPass(graphics)
|
||||
UIPass::UIPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -18,20 +19,20 @@ void UIPass::beginFrame(const Component::Camera&)
|
||||
{
|
||||
VertexBufferCreateInfo info = {
|
||||
.resourceData = {
|
||||
.size = (uint32)(sizeof(UI::RenderElementStyle) * passData.renderElements.size()),
|
||||
.data = (uint8*)passData.renderElements.data()
|
||||
.size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()),
|
||||
.data = (uint8*)renderElements.data()
|
||||
},
|
||||
.vertexSize = sizeof(UI::RenderElementStyle),
|
||||
.numVertices = (uint32)passData.renderElements.size(),
|
||||
.numVertices = (uint32)renderElements.size(),
|
||||
};
|
||||
elementBuffer = graphics->createVertexBuffer(info);
|
||||
uint32 numTextures = static_cast<uint32>(passData.usedTextures.size());
|
||||
uint32 numTextures = static_cast<uint32>(usedTextures.size());
|
||||
numTexturesBuffer->updateContents({
|
||||
.size = sizeof(uint32),
|
||||
.data = (uint8*)&numTextures,
|
||||
});
|
||||
descriptorSet->updateBuffer(2, numTexturesBuffer);
|
||||
descriptorSet->updateTextureArray(3, passData.usedTextures);
|
||||
descriptorSet->updateTextureArray(3, usedTextures);
|
||||
descriptorSet->writeChanges();
|
||||
//co_return;
|
||||
}
|
||||
@@ -42,11 +43,12 @@ void UIPass::render()
|
||||
Gfx::PRenderCommand command = graphics->createRenderCommand("UIPassCommand");
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(pipeline);
|
||||
command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)});
|
||||
command->bindVertexBuffer({elementBuffer});
|
||||
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->endRenderPass();
|
||||
|
||||
//co_return;
|
||||
}
|
||||
|
||||
@@ -96,7 +98,7 @@ void UIPass::createRenderPass()
|
||||
fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
Array<Gfx::VertexElement> decl;
|
||||
decl.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(UI::RenderElementStyle, position),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.attributeIndex = 0,
|
||||
@@ -104,7 +106,7 @@ void UIPass::createRenderPass()
|
||||
.bInstanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(UI::RenderElementStyle, backgroundImageIndex),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
|
||||
.attributeIndex = 1,
|
||||
@@ -112,7 +114,7 @@ void UIPass::createRenderPass()
|
||||
.bInstanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(UI::RenderElementStyle, backgroundColor),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.attributeIndex = 2,
|
||||
@@ -120,7 +122,7 @@ void UIPass::createRenderPass()
|
||||
.bInstanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(UI::RenderElementStyle, opacity),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT,
|
||||
.attributeIndex = 3,
|
||||
@@ -128,7 +130,7 @@ void UIPass::createRenderPass()
|
||||
.bInstanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.streamIndex = 0,
|
||||
.binding = 0,
|
||||
.offset = offsetof(UI::RenderElementStyle, dimensions),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
|
||||
.attributeIndex = 4,
|
||||
@@ -177,7 +179,7 @@ void UIPass::createRenderPass()
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
|
||||
GraphicsPipelineCreateInfo pipelineInfo;
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.vertexDeclaration = declaration;
|
||||
pipelineInfo.vertexShader = vertexShader;
|
||||
pipelineInfo.fragmentShader = fragmentShader;
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "UI/RenderHierarchy.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||
DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
|
||||
struct UIPassData
|
||||
{
|
||||
Array<UI::RenderElementStyle> renderElements;
|
||||
Array<Gfx::PTexture> usedTextures;
|
||||
};
|
||||
class UIPass : public RenderPass<UIPassData>
|
||||
class UIPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
UIPass(Gfx::PGraphics graphics);
|
||||
UIPass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~UIPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -39,6 +34,9 @@ private:
|
||||
Gfx::PFragmentShader fragmentShader;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
|
||||
Array<UI::RenderElementStyle> renderElements;
|
||||
Array<Gfx::PTexture> usedTextures;
|
||||
};
|
||||
DEFINE_REF(UIPass);
|
||||
} // namespace Seele
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,5 +1,4 @@
|
||||
#include "ShaderCompiler.h"
|
||||
#include "VertexShaderInput.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include "Material/Material.h"
|
||||
#include "GraphicsResources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
StaticMeshVertexData::StaticMeshVertexData()
|
||||
{}
|
||||
extern List<VertexData*> vertexDataList;
|
||||
|
||||
StaticMeshVertexData::StaticMeshVertexData(Gfx::PGraphics graphics)
|
||||
: VertexData(graphics)
|
||||
{
|
||||
vertexDataList.add(this);
|
||||
}
|
||||
|
||||
StaticMeshVertexData::~StaticMeshVertexData()
|
||||
{}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Seele
|
||||
class StaticMeshVertexData : public VertexData
|
||||
{
|
||||
public:
|
||||
StaticMeshVertexData();
|
||||
StaticMeshVertexData(Gfx::PGraphics graphics);
|
||||
virtual ~StaticMeshVertexData();
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
@@ -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 +0,0 @@
|
||||
#include "TopologyData.h"
|
||||
@@ -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
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "VertexData.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Component/Mesh.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
#pragma once
|
||||
#include "GraphicsResources.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Component/Transform.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct Mesh;
|
||||
}
|
||||
struct MeshId
|
||||
{
|
||||
uint64 id;
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "Allocator.h"
|
||||
#include "Graphics.h"
|
||||
#include "Initializer.h"
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/Array.h"
|
||||
#include <mutex>
|
||||
@@ -1,8 +1,4 @@
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -16,7 +12,7 @@ struct PendingBuffer
|
||||
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)
|
||||
: graphics(graphics)
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,55 @@
|
||||
target_sources(Engine
|
||||
PRIVATE
|
||||
VulkanAllocator.h
|
||||
VulkanAllocator.cpp
|
||||
VulkanBuffer.cpp
|
||||
VulkanCommandBuffer.h
|
||||
VulkanCommandBuffer.cpp
|
||||
VulkanFramebuffer.h
|
||||
VulkanFramebuffer.cpp
|
||||
VulkanGraphics.h
|
||||
VulkanGraphics.cpp
|
||||
VulkanGraphicsResources.h
|
||||
VulkanGraphicsResources.cpp
|
||||
VulkanDescriptorSets.h
|
||||
VulkanDescriptorSets.cpp
|
||||
VulkanGraphicsEnums.h
|
||||
VulkanGraphicsEnums.cpp
|
||||
VulkanInitializer.h
|
||||
VulkanInitializer.cpp
|
||||
VulkanRenderPass.h
|
||||
VulkanRenderPass.cpp
|
||||
VulkanPipeline.h
|
||||
VulkanPipeline.cpp
|
||||
VulkanPipelineCache.h
|
||||
VulkanPipelineCache.cpp
|
||||
VulkanShader.h
|
||||
VulkanShader.cpp
|
||||
VulkanTexture.cpp
|
||||
VulkanQueue.h
|
||||
VulkanQueue.cpp
|
||||
VulkanViewport.cpp)
|
||||
Allocator.h
|
||||
Allocator.cpp
|
||||
Buffer.h
|
||||
Buffer.cpp
|
||||
CommandBuffer.h
|
||||
CommandBuffer.cpp
|
||||
DescriptorSets.h
|
||||
DescriptorSets.cpp
|
||||
Enums.h
|
||||
Enums.cpp
|
||||
Framebuffer.h
|
||||
Framebuffer.cpp
|
||||
Graphics.h
|
||||
Graphics.cpp
|
||||
Initializer.h
|
||||
Initializer.cpp
|
||||
Pipeline.h
|
||||
Pipeline.cpp
|
||||
PipelineCache.h
|
||||
PipelineCache.cpp
|
||||
Queue.h
|
||||
Queue.cpp
|
||||
RenderPass.h
|
||||
RenderPass.cpp
|
||||
RenderTarget.h
|
||||
RenderTarget.cpp
|
||||
Resources.h
|
||||
Resources.cpp
|
||||
Shader.h
|
||||
Shader.cpp
|
||||
Texture.h
|
||||
Texture.cpp)
|
||||
|
||||
target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
FILES
|
||||
VulkanAllocator.h
|
||||
VulkanCommandBuffer.h
|
||||
VulkanFramebuffer.h
|
||||
VulkanGraphics.h
|
||||
VulkanGraphicsResources.h
|
||||
VulkanDescriptorSets.h
|
||||
VulkanGraphicsEnums.h
|
||||
VulkanInitializer.h
|
||||
VulkanRenderPass.h
|
||||
VulkanPipeline.h
|
||||
VulkanPipelineCache.h
|
||||
VulkanShader.h
|
||||
VulkanQueue.h)
|
||||
Allocator.h
|
||||
Buffer.h
|
||||
CommandBuffer.h
|
||||
DescriptorSets.h
|
||||
Enums.h
|
||||
Framebuffer.h
|
||||
Graphics.h
|
||||
Initializer.h
|
||||
Pipeline.h
|
||||
PipelineCache.h
|
||||
Queue.h
|
||||
RenderPass.h
|
||||
RenderTarget.h
|
||||
Resources.h
|
||||
Shader.h
|
||||
Texture.h)
|
||||
|
||||
+9
-10
@@ -1,13 +1,12 @@
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "Graphics/MeshBatch.h"
|
||||
#include "CommandBuffer.h"
|
||||
#include "Initializer.h"
|
||||
#include "Graphics.h"
|
||||
#include "Pipeline.h"
|
||||
#include "Enums.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Pipeline.h"
|
||||
#include "DescriptorSets.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanQueue.h"
|
||||
#include "Queue.h"
|
||||
#include "DescriptorSets.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -87,7 +88,7 @@ public:
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) 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 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;
|
||||
+4
-6
@@ -1,9 +1,7 @@
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "DescriptorSets.h"
|
||||
#include "Graphics.h"
|
||||
#include "Initializer.h"
|
||||
#include "CommandBuffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "Graphics/GraphicsEnums.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <iostream>
|
||||
|
||||
@@ -25,11 +25,10 @@ namespace Vulkan
|
||||
enum class ShaderType
|
||||
{
|
||||
VERTEX = 0,
|
||||
CONTROL = 1,
|
||||
EVALUATION = 2,
|
||||
GEOMETRY = 3,
|
||||
FRAGMENT = 4,
|
||||
COMPUTE = 5,
|
||||
FRAGMENT = 1,
|
||||
COMPUTE = 2,
|
||||
TASK = 3,
|
||||
MESH = 4,
|
||||
};
|
||||
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
||||
+6
-5
@@ -1,8 +1,9 @@
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Enums.h"
|
||||
#include "Initializer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics.h"
|
||||
#include "Texture.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
namespace Seele
|
||||
@@ -14,6 +14,9 @@ DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(Framebuffer)
|
||||
DECLARE_REF(RenderCommand)
|
||||
DECLARE_REF(PipelineCache)
|
||||
DECLARE_REF(Window)
|
||||
DECLARE_REF(RenderTargetLayout)
|
||||
DECLARE_REF(Viewport)
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
@@ -55,13 +58,13 @@ public:
|
||||
virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override;
|
||||
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) 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::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PTaskShader createTaskShader(const ShaderCreateInfo& 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::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#include "VulkanInitializer.h"
|
||||
#include "Initializer.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
+7
-7
@@ -1,12 +1,12 @@
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "Pipeline.h"
|
||||
#include "DescriptorSets.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo)
|
||||
: Gfx::GraphicsPipeline(createInfo, pipelineLayout)
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout)
|
||||
: Gfx::GraphicsPipeline(pipelineLayout)
|
||||
, graphics(graphics)
|
||||
, pipeline(handle)
|
||||
{
|
||||
@@ -26,8 +26,8 @@ VkPipelineLayout GraphicsPipeline::getLayout() const
|
||||
return layout.cast<PipelineLayout>()->getHandle();
|
||||
}
|
||||
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo)
|
||||
: Gfx::ComputePipeline(createInfo, pipelineLayout)
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout)
|
||||
: Gfx::ComputePipeline(pipelineLayout)
|
||||
, graphics(graphics)
|
||||
, pipeline(handle)
|
||||
{
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -10,7 +11,7 @@ DECLARE_REF(Graphics)
|
||||
class GraphicsPipeline : public Gfx::GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo);
|
||||
GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout);
|
||||
virtual ~GraphicsPipeline();
|
||||
void bind(VkCommandBuffer handle);
|
||||
VkPipelineLayout getLayout() const;
|
||||
@@ -22,7 +23,7 @@ DEFINE_REF(GraphicsPipeline)
|
||||
class ComputePipeline : public Gfx::ComputePipeline
|
||||
{
|
||||
public:
|
||||
ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo);
|
||||
ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout);
|
||||
virtual ~ComputePipeline();
|
||||
void bind(VkCommandBuffer handle);
|
||||
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;
|
||||
}
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "VulkanPipeline.h"
|
||||
#include "Pipeline.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -10,14 +10,13 @@ class PipelineCache
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(const GraphicsPipelineCreateInfo& createInfo);
|
||||
PComputePipeline createPipeline(const ComputePipelineCreateInfo& createInfo);
|
||||
PGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo);
|
||||
PGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo);
|
||||
PComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo);
|
||||
private:
|
||||
VkPipelineCache cache;
|
||||
PGraphics graphics;
|
||||
std::string cacheFile;
|
||||
std::mutex createdPipelinesLock;
|
||||
Map<uint32, VkPipeline> createdPipelines;
|
||||
};
|
||||
DEFINE_REF(PipelineCache)
|
||||
} // namespace Vulkan
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "VulkanQueue.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Queue.h"
|
||||
#include "Initializer.h"
|
||||
#include "Graphics.h"
|
||||
#include "Allocator.h"
|
||||
#include "CommandBuffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Initializer.h"
|
||||
#include "Graphics.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Texture.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Resources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -51,18 +52,16 @@ public:
|
||||
}
|
||||
};
|
||||
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::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(ControlShader)
|
||||
DEFINE_REF(EvaluationShader)
|
||||
DEFINE_REF(GeometryShader)
|
||||
DEFINE_REF(FragmentShader)
|
||||
DEFINE_REF(ComputeShader)
|
||||
DEFINE_REF(TaskShader)
|
||||
DEFINE_REF(MeshShader)
|
||||
|
||||
} // namespace Vulkan
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -30,24 +30,9 @@ Material::~Material()
|
||||
{
|
||||
}
|
||||
|
||||
Gfx::PDescriptorSet Material::createDescriptorSet()
|
||||
PMaterialInstance Seele::Material::instantiate()
|
||||
{
|
||||
Gfx::PDescriptorSet descriptorSet = layout->allocateDescriptorSet();
|
||||
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;
|
||||
return new MaterialInstance(instanceId++, graphics, this, layout, parameters, uniformBinding, uniformDataSize);
|
||||
}
|
||||
|
||||
void Material::save(ArchiveBuffer& buffer) const
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "ShaderExpression.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorSet descriptor, Array<PShaderParameter> params, uint32 uniformBinding, uint32 uniformSize)
|
||||
: id(id), graphics(graphics), baseMaterial(baseMaterial), descriptor(descriptor), parameters(params), uniformBinding(uniformBinding)
|
||||
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), layout(layout), parameters(params), uniformBinding(uniformBinding)
|
||||
{
|
||||
uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.resourceData = {
|
||||
@@ -21,3 +21,7 @@ MaterialInstance::~MaterialInstance()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Seele::MaterialInstance::updateDescriptor()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
#include "Material.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class MaterialInstance
|
||||
{
|
||||
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();
|
||||
void updateDescriptor();
|
||||
Gfx::PDescriptorSet getDescriptorSet() const;
|
||||
@@ -18,6 +19,7 @@ private:
|
||||
uint32 uniformBinding;
|
||||
Gfx::PUniformBuffer uniformBuffer;
|
||||
Array<PShaderParameter> parameters;
|
||||
Gfx::PDescriptorLayout layout;
|
||||
Gfx::PDescriptorSet descriptor;
|
||||
PMaterial baseMaterial;
|
||||
uint64 id;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "ShaderExpression.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Asset/TextureAsset.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
target_sources(Engine
|
||||
PRIVATE
|
||||
EventManager.h
|
||||
LightEnvironment.h
|
||||
LightEnvironment.cpp
|
||||
Util.h
|
||||
Scene.cpp
|
||||
Scene.h)
|
||||
Scene.h
|
||||
Scene.cpp)
|
||||
|
||||
target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
FILES
|
||||
EventManager.h
|
||||
LightEnvironment.h
|
||||
Util.h
|
||||
Scene.h)
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
@@ -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,7 +1,7 @@
|
||||
#include "Scene.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Component/StaticMesh.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Component/Transform.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Asset/TextureAsset.h"
|
||||
@@ -81,14 +81,3 @@ LightEnv Scene::getLightBuffer()
|
||||
});
|
||||
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
Reference in New Issue
Block a user