Adding pretty printers
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
import sys
|
||||||
|
sys.path.insert(0, '/usr/share/gdb/python/')
|
||||||
|
import gdb.printing
|
||||||
|
import glm_pp
|
||||||
|
|
||||||
|
class ArrayPrinter:
|
||||||
|
def __init__(self, val):
|
||||||
|
self.val = val
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return f"Array(size={int(self.val['arraySize'])})"
|
||||||
|
|
||||||
|
def children(self):
|
||||||
|
data = self.val['_data']
|
||||||
|
size = int(self.val['arraySize'])
|
||||||
|
allocated = int(self.val['allocated'])
|
||||||
|
#yield f"[size]", size
|
||||||
|
#yield f"[allocated]", allocated
|
||||||
|
for i in range(size):
|
||||||
|
elem_val = (data + i).dereference()
|
||||||
|
yield f"[{i}]", elem_val
|
||||||
|
|
||||||
|
def display_hint(self):
|
||||||
|
return "array"
|
||||||
|
|
||||||
|
def build_pretty_printer():
|
||||||
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("Seele")
|
||||||
|
pp.add_printer("Array", r'^Seele::Array<.*>$', ArrayPrinter)
|
||||||
|
return pp
|
||||||
|
|
||||||
|
gdb.printing.register_pretty_printer(gdb.current_objfile(), build_pretty_printer())
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import gdb.printing
|
||||||
|
|
||||||
|
_type_letters = {
|
||||||
|
gdb.TYPE_CODE_FLT: "d", # or "f"
|
||||||
|
gdb.TYPE_CODE_INT: "i",
|
||||||
|
gdb.TYPE_CODE_BOOL: "b"
|
||||||
|
}
|
||||||
|
|
||||||
|
def _vec_info(v):
|
||||||
|
# vec contains either a union of structs or a struct of unions, depending on
|
||||||
|
# configuration. gdb can't properly access the named members, and in some
|
||||||
|
# cases the names are wrong.
|
||||||
|
# It would be simple to cast to an array, similarly to how operator[] is
|
||||||
|
# implemented, but values returned by functions called from gdb don't have
|
||||||
|
# an address.
|
||||||
|
# Instead, recursively find all fields of required type and sort by offset.
|
||||||
|
T = v.type.template_argument(0)
|
||||||
|
letter = _type_letters.get(T.code, "t")
|
||||||
|
length = v.type.sizeof // T.sizeof
|
||||||
|
items = {}
|
||||||
|
def find(v, bitpos):
|
||||||
|
t = v.type.strip_typedefs()
|
||||||
|
if t.code in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION):
|
||||||
|
for f in t.fields():
|
||||||
|
if hasattr(f, "bitpos"): # not static
|
||||||
|
find(v[f], bitpos + f.bitpos)
|
||||||
|
elif t == T:
|
||||||
|
items[bitpos] = v
|
||||||
|
find(v, 0)
|
||||||
|
assert len(items) == length
|
||||||
|
items = [str(f) for k, f in sorted(items.items())]
|
||||||
|
return letter, length, items
|
||||||
|
|
||||||
|
class VecPrinter:
|
||||||
|
def __init__(self, v):
|
||||||
|
self.v = v
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
letter, length, items = _vec_info(self.v)
|
||||||
|
return "{}vec{}({})".format(letter, length, ", ".join(items))
|
||||||
|
|
||||||
|
class MatPrinter:
|
||||||
|
def __init__(self, v):
|
||||||
|
self.v = v
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
V = self.v["value"]
|
||||||
|
columns = []
|
||||||
|
for i in range(V.type.range()[1] + 1):
|
||||||
|
letter, length, items = _vec_info(V[i])
|
||||||
|
columns.append("({})".format(", ".join(items)))
|
||||||
|
return "{}mat{}x{}({})".format(
|
||||||
|
letter, len(columns), length, ", ".join(columns))
|
||||||
|
|
||||||
|
def build_pretty_printer():
|
||||||
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("glm_pp")
|
||||||
|
pp.add_printer(
|
||||||
|
"glm::vec", r"^glm::(detail::)?tvec\d<[^<>]*>$", VecPrinter)
|
||||||
|
pp.add_printer(
|
||||||
|
"glm::mat", r"^glm::(detail::)?tmat\dx\d<[^<>]*>$", MatPrinter)
|
||||||
|
pp.add_printer(
|
||||||
|
"Seele::Vector", r"^Seele::Vector.?$", VecPrinter)
|
||||||
|
pp.add_printer(
|
||||||
|
"Seele::Matrix", r"^Seele::Matrix.?$", MatPrinter)
|
||||||
|
return pp
|
||||||
|
|
||||||
|
gdb.printing.register_pretty_printer(gdb.current_objfile(),
|
||||||
|
build_pretty_printer())
|
||||||
+12
-10
@@ -5,16 +5,18 @@ import MATERIAL_FILE_NAME;
|
|||||||
|
|
||||||
const static uint64_t NUM_CASCADES = 4;
|
const static uint64_t NUM_CASCADES = 4;
|
||||||
|
|
||||||
/*struct ShadowMappingData
|
struct ShadowMappingData
|
||||||
{
|
{
|
||||||
Texture2DArray shadowMaps[NUM_CASCADES];
|
Texture2DArray shadowMaps[NUM_CASCADES];
|
||||||
|
|
||||||
ConstantBuffer<float4x4> lightSpaceMatrices[NUM_CASCADES];
|
StructuredBuffer<float4x4> lightSpaceMatrices[NUM_CASCADES];
|
||||||
|
|
||||||
|
SamplerState shadowSampler;
|
||||||
|
|
||||||
ConstantBuffer<float[NUM_CASCADES]> cascadeSplits;
|
ConstantBuffer<float[NUM_CASCADES]> cascadeSplits;
|
||||||
};
|
};
|
||||||
ParameterBlock<ShadowMappingData> pShadowMapping;
|
ParameterBlock<ShadowMappingData> pShadowMapping;
|
||||||
*/
|
|
||||||
struct LightCullingData
|
struct LightCullingData
|
||||||
{
|
{
|
||||||
RWStructuredBuffer<uint> lightIndexList;
|
RWStructuredBuffer<uint> lightIndexList;
|
||||||
@@ -42,16 +44,16 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
float3 result = float3(0, 0, 0);
|
float3 result = float3(0, 0, 0);
|
||||||
for(int i = 0; i < pLightEnv.numDirectionalLights; ++i)
|
for(int i = 0; i < pLightEnv.numDirectionalLights; ++i)
|
||||||
{
|
{
|
||||||
/*uint cascadeIndex = 0;
|
uint cascadeIndex = 0;
|
||||||
for (uint c = 0; c < NUM_CASCADES - 1; ++c) {
|
for (uint c = 0; c < NUM_CASCADES - 1; ++c) {
|
||||||
if (params.position_VS.z < pShadowMapping.cascadeSplits[c]) {
|
if (params.position_VS.z < pShadowMapping.cascadeSplits[c]) {
|
||||||
cascadeIndex = c + 1;
|
cascadeIndex = c + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float4 lightSpacePos = mul(biasMat, mul(pShadowMapping.lightSpaceMatrices[i], float4(params.position_WS, 1)));
|
float4 lightSpacePos = mul(biasMat, mul(pShadowMapping.lightSpaceMatrices[cascadeIndex][i], float4(params.position_WS, 1)));
|
||||||
float4 shadowCoord = lightSpacePos / lightSpacePos.w;
|
float4 shadowCoord = lightSpacePos / lightSpacePos.w;
|
||||||
int2 texDim;
|
int3 texDim;
|
||||||
pLightEnv.shadowMap.GetDimensions(texDim.x, texDim.y);
|
pShadowMapping.shadowMaps[cascadeIndex].GetDimensions(texDim.x, texDim.y, texDim.z);
|
||||||
float scale = 1.5f;
|
float scale = 1.5f;
|
||||||
float dx = scale * 1.0 / float(texDim.x);
|
float dx = scale * 1.0 / float(texDim.x);
|
||||||
float dy = scale * 1.0 / float(texDim.y);
|
float dy = scale * 1.0 / float(texDim.y);
|
||||||
@@ -64,7 +66,7 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
float shadow = 1.0f;
|
float shadow = 1.0f;
|
||||||
if (shadowCoord.z > 0.0 && shadowCoord.z < 1.0)
|
if (shadowCoord.z > 0.0 && shadowCoord.z < 1.0)
|
||||||
{
|
{
|
||||||
float dist = pLightEnv.shadowMap.Sample(pLightEnv.shadowSampler, shadowCoord.xy + float2(dx * x, dy * y)).r;
|
float dist = pShadowMapping.shadowMaps[cascadeIndex].Sample(pShadowMapping.shadowSampler, float3(shadowCoord.xy + float2(dx * x, dy * y), i)).r;
|
||||||
if (shadowCoord.w > 0 && dist > shadowCoord.z)
|
if (shadowCoord.w > 0 && dist > shadowCoord.z)
|
||||||
{
|
{
|
||||||
shadow = 0;
|
shadow = 0;
|
||||||
@@ -73,9 +75,9 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
shadowFactor += shadow;
|
shadowFactor += shadow;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
result += /*(shadowFactor / count) **/ pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
|
result += (shadowFactor / count) * pLightEnv.directionalLights[i].illuminate(lightingParams, brdf);
|
||||||
}
|
}
|
||||||
for (uint i = 0; i < pLightEnv.numPointLights; ++i)
|
for (uint i = 0; i < pLightEnv.numPointLights; ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,8 +61,6 @@ struct PointLight : ILightEnv
|
|||||||
struct LightEnv
|
struct LightEnv
|
||||||
{
|
{
|
||||||
StructuredBuffer<DirectionalLight> directionalLights;
|
StructuredBuffer<DirectionalLight> directionalLights;
|
||||||
Texture2D shadowMap; // todo: not an array
|
|
||||||
SamplerState shadowSampler;
|
|
||||||
uint numDirectionalLights;
|
uint numDirectionalLights;
|
||||||
StructuredBuffer<PointLight> pointLights;
|
StructuredBuffer<PointLight> pointLights;
|
||||||
uint numPointLights;
|
uint numPointLights;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ struct DescriptorBinding {
|
|||||||
std::string name;
|
std::string name;
|
||||||
// In Metal uniforms are plain bytes, and for that we need to know the struct size
|
// In Metal uniforms are plain bytes, and for that we need to know the struct size
|
||||||
uint32 uniformLength = 0;
|
uint32 uniformLength = 0;
|
||||||
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK;
|
||||||
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
||||||
uint32 descriptorCount = 1;
|
uint32 descriptorCount = 1;
|
||||||
SeDescriptorBindingFlags bindingFlags = 0;
|
SeDescriptorBindingFlags bindingFlags = 0;
|
||||||
@@ -27,7 +27,6 @@ class DescriptorLayout {
|
|||||||
void reset();
|
void reset();
|
||||||
PDescriptorSet allocateDescriptorSet();
|
PDescriptorSet allocateDescriptorSet();
|
||||||
virtual void create() = 0;
|
virtual void create() = 0;
|
||||||
constexpr const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
|
|
||||||
constexpr uint32 getHash() const { return hash; }
|
constexpr uint32 getHash() const { return hash; }
|
||||||
constexpr const std::string& getName() const { return name; }
|
constexpr const std::string& getName() const { return name; }
|
||||||
|
|
||||||
@@ -62,8 +61,9 @@ class DescriptorSet {
|
|||||||
virtual void writeChanges() = 0;
|
virtual void writeChanges() = 0;
|
||||||
virtual void updateConstants(const std::string& name, uint32 offset, void* data) = 0;
|
virtual void updateConstants(const std::string& name, uint32 offset, void* data) = 0;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) = 0;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) = 0;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) = 0;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer vertexBuffer) = 0;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) = 0;\
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) = 0;
|
||||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0;
|
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) = 0;
|
||||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) = 0;
|
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) = 0;
|
||||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) = 0;
|
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) = 0;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ class Graphics {
|
|||||||
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
||||||
|
|
||||||
virtual OTexture2D createTexture2D(const TextureCreateInfo& createInfo) = 0;
|
virtual OTexture2D createTexture2D(const TextureCreateInfo& createInfo) = 0;
|
||||||
|
virtual OTexture2DArray createTexture2DArray(const TextureCreateInfo& createInfo) = 0;
|
||||||
virtual OTexture3D createTexture3D(const TextureCreateInfo& createInfo) = 0;
|
virtual OTexture3D createTexture3D(const TextureCreateInfo& createInfo) = 0;
|
||||||
virtual OTextureCube createTextureCube(const TextureCreateInfo& createInfo) = 0;
|
virtual OTextureCube createTextureCube(const TextureCreateInfo& createInfo) = 0;
|
||||||
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) = 0;
|
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) = 0;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "Math/Matrix.h"
|
#include "Math/Matrix.h"
|
||||||
#include "Math/Vector.h"
|
#include "Math/Vector.h"
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
|
#include "ShadowPass.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -41,7 +42,29 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
|||||||
});
|
});
|
||||||
lightCullingLayout->create();
|
lightCullingLayout->create();
|
||||||
|
|
||||||
|
shadowMappingLayout = graphics->createDescriptorLayout("pShadowMapping");
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = SHADOWMAPS_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = NUM_CASCADES,
|
||||||
|
});
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = LIGHTSPACE_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.descriptorCount = NUM_CASCADES,
|
||||||
|
});
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = SHADOWSAMPLER_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
});
|
||||||
|
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = CASCADE_SPLIT_NAME,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||||
|
});
|
||||||
|
shadowMappingLayout->create();
|
||||||
|
|
||||||
basePassLayout->addDescriptorLayout(lightCullingLayout);
|
basePassLayout->addDescriptorLayout(lightCullingLayout);
|
||||||
|
basePassLayout->addDescriptorLayout(shadowMappingLayout);
|
||||||
basePassLayout->addPushConstants(Gfx::SePushConstantRange{
|
basePassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
@@ -79,6 +102,19 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
|||||||
.fogColor = Vector(0, 0, 0),
|
.fogColor = Vector(0, 0, 0),
|
||||||
.blendFactor = 0,
|
.blendFactor = 0,
|
||||||
};
|
};
|
||||||
|
shadowSampler = graphics->createSampler(SamplerCreateInfo{
|
||||||
|
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR,
|
||||||
|
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.mipLodBias = 0.0f,
|
||||||
|
.maxAnisotropy = 1.0f,
|
||||||
|
.minLod = 0.0f,
|
||||||
|
.maxLod = 1.0f,
|
||||||
|
.borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePass::~BasePass() {}
|
BasePass::~BasePass() {}
|
||||||
@@ -140,12 +176,22 @@ void BasePass::render() {
|
|||||||
opaqueCulling->writeChanges();
|
opaqueCulling->writeChanges();
|
||||||
transparentCulling->writeChanges();
|
transparentCulling->writeChanges();
|
||||||
|
|
||||||
|
shadowMappingLayout->reset();
|
||||||
|
shadowMapping = shadowMappingLayout->allocateDescriptorSet();
|
||||||
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
|
shadowMapping->updateTexture(SHADOWMAPS_NAME, i, shadowMaps[i]->getDefaultView());
|
||||||
|
shadowMapping->updateBuffer(LIGHTSPACE_NAME, i, lightSpaceMatrices[i]);
|
||||||
|
}
|
||||||
|
shadowMapping->updateSampler(SHADOWSAMPLER_NAME, 0, shadowSampler);
|
||||||
|
shadowMapping->updateBuffer(CASCADE_SPLIT_NAME, 0, cascadeSplits);
|
||||||
|
shadowMapping->writeChanges();
|
||||||
|
|
||||||
query->beginQuery();
|
query->beginQuery();
|
||||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "BaseBegin");
|
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "BaseBegin");
|
||||||
graphics->beginRenderPass(renderPass);
|
graphics->beginRenderPass(renderPass);
|
||||||
Array<VertexData::TransparentDraw> transparentData;
|
Array<VertexData::TransparentDraw> transparentData;
|
||||||
|
// Opaque
|
||||||
{
|
{
|
||||||
graphics->beginDebugRegion("Opaque");
|
|
||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||||
permutation.setDepthCulling(true); // always use the culling info
|
permutation.setDepthCulling(true); // always use the culling info
|
||||||
@@ -176,7 +222,7 @@ void BasePass::render() {
|
|||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
assert(collection != nullptr);
|
assert(collection != nullptr);
|
||||||
|
|
||||||
//bool twoSided = materialData.material->isTwoSided();
|
// bool twoSided = materialData.material->isTwoSided();
|
||||||
|
|
||||||
if (graphics->supportMeshShading()) {
|
if (graphics->supportMeshShading()) {
|
||||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
@@ -221,7 +267,7 @@ void BasePass::render() {
|
|||||||
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
||||||
}
|
}
|
||||||
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
||||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), opaqueCulling});
|
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), shadowMapping, opaqueCulling});
|
||||||
for (const auto& drawCall : materialData.instances) {
|
for (const auto& drawCall : materialData.instances) {
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
||||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
@@ -241,7 +287,6 @@ void BasePass::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// commands.add(waterRenderer->render(viewParamsSet));
|
// commands.add(waterRenderer->render(viewParamsSet));
|
||||||
@@ -249,18 +294,15 @@ void BasePass::render() {
|
|||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
{
|
{
|
||||||
graphics->beginDebugRegion("Skybox");
|
|
||||||
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender");
|
||||||
skyboxCommand->setViewport(viewport);
|
skyboxCommand->setViewport(viewport);
|
||||||
skyboxCommand->bindPipeline(skyboxPipeline);
|
skyboxCommand->bindPipeline(skyboxPipeline);
|
||||||
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||||
skyboxCommand->draw(36, 1, 0, 0);
|
skyboxCommand->draw(36, 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(skyboxCommand));
|
graphics->executeCommands(std::move(skyboxCommand));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
// Transparent rendering
|
// Transparent rendering
|
||||||
{
|
{
|
||||||
graphics->beginDebugRegion("Transparent");
|
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||||
permutation.setPositionOnly(false);
|
permutation.setPositionOnly(false);
|
||||||
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
permutation.setDepthCulling(false); // ignore visibility infos for transparency
|
||||||
@@ -280,7 +322,7 @@ void BasePass::render() {
|
|||||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||||
assert(collection != nullptr);
|
assert(collection != nullptr);
|
||||||
|
|
||||||
//bool twoSided = t.matInst->getBaseMaterial()->isTwoSided();
|
// bool twoSided = t.matInst->getBaseMaterial()->isTwoSided();
|
||||||
|
|
||||||
if (graphics->supportMeshShading()) {
|
if (graphics->supportMeshShading()) {
|
||||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||||
@@ -343,7 +385,7 @@ void BasePass::render() {
|
|||||||
transparentCommand->bindPipeline(pipeline);
|
transparentCommand->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
transparentCommand->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(),
|
transparentCommand->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(),
|
||||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(),
|
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), shadowMapping,
|
||||||
transparentCulling});
|
transparentCulling});
|
||||||
transparentCommand->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
transparentCommand->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
||||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
@@ -360,11 +402,9 @@ void BasePass::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphics->executeCommands(std::move(transparentCommand));
|
graphics->executeCommands(std::move(transparentCommand));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
// Debug vertices
|
// Debug vertices
|
||||||
if (gDebugVertices.size() > 0) {
|
if (gDebugVertices.size() > 0) {
|
||||||
graphics->beginDebugRegion("Debug");
|
|
||||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||||
permutation.setDepthCulling(true); // always use the culling info
|
permutation.setDepthCulling(true); // always use the culling info
|
||||||
permutation.setPositionOnly(false);
|
permutation.setPositionOnly(false);
|
||||||
@@ -375,7 +415,6 @@ void BasePass::render() {
|
|||||||
debugCommand->bindVertexBuffer({debugVertices});
|
debugCommand->bindVertexBuffer({debugVertices});
|
||||||
debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
debugCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(debugCommand));
|
graphics->executeCommands(std::move(debugCommand));
|
||||||
graphics->endDebugRegion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
@@ -422,18 +461,18 @@ void BasePass::publishOutputs() {
|
|||||||
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
|
|
||||||
msDepthAttachment =
|
msDepthAttachment = Gfx::RenderTargetAttachment(msBasePassDepth->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
Gfx::RenderTargetAttachment(msBasePassDepth->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||||
msDepthAttachment.clear.depthStencil.depth = 0.0f;
|
msDepthAttachment.clear.depthStencil.depth = 0.0f;
|
||||||
|
|
||||||
colorAttachment =
|
colorAttachment = Gfx::RenderTargetAttachment(basePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
Gfx::RenderTargetAttachment(basePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
|
|
||||||
msColorAttachment =
|
msColorAttachment = Gfx::RenderTargetAttachment(msBasePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
Gfx::RenderTargetAttachment(msBasePassColor->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||||
msColorAttachment.clear.color.float32[0] = 0;
|
msColorAttachment.clear.color.float32[0] = 0;
|
||||||
msColorAttachment.clear.color.float32[1] = 1;
|
msColorAttachment.clear.color.float32[1] = 1;
|
||||||
msColorAttachment.clear.color.float32[2] = 0;
|
msColorAttachment.clear.color.float32[2] = 0;
|
||||||
@@ -452,6 +491,11 @@ void BasePass::createRenderPass() {
|
|||||||
// terrainRenderer = new TerrainRenderer(graphics, scene, viewParamsLayout, viewParamsSet);
|
// terrainRenderer = new TerrainRenderer(graphics, scene, viewParamsLayout, viewParamsSet);
|
||||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||||
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
||||||
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
|
shadowMaps[i] = resources->requestTexture(fmt::format("SHADOWMAP_TEXTURE{0}", i));
|
||||||
|
lightSpaceMatrices[i] = resources->requestBuffer(fmt::format("SHADOWMAP_LIGHTSPACE{0}", i));
|
||||||
|
}
|
||||||
|
cascadeSplits = resources->requestUniform("SHADOWMAP_CASCADESPLITS");
|
||||||
|
|
||||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
.colorAttachments = {msColorAttachment},
|
.colorAttachments = {msColorAttachment},
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Graphics/Buffer.h"
|
||||||
|
#include "Graphics/Descriptor.h"
|
||||||
|
#include "Graphics/RenderPass/ShadowPass.h"
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "WaterRenderer.h"
|
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
DECLARE_REF(CameraActor)
|
DECLARE_REF(CameraActor)
|
||||||
@@ -30,9 +32,14 @@ class BasePass : public RenderPass {
|
|||||||
Gfx::PTexture2D tLightGrid;
|
Gfx::PTexture2D tLightGrid;
|
||||||
constexpr static const char* LIGHTINDEX_NAME = "lightIndexList";
|
constexpr static const char* LIGHTINDEX_NAME = "lightIndexList";
|
||||||
constexpr static const char* LIGHTGRID_NAME = "lightGrid";
|
constexpr static const char* LIGHTGRID_NAME = "lightGrid";
|
||||||
|
constexpr static const char* SHADOWMAPS_NAME = "shadowMaps";
|
||||||
|
constexpr static const char* LIGHTSPACE_NAME = "lightSpaceMatrices";
|
||||||
|
constexpr static const char* SHADOWSAMPLER_NAME = "shadowSampler";
|
||||||
|
constexpr static const char* CASCADE_SPLIT_NAME = "cascadeSplit";
|
||||||
|
|
||||||
Gfx::PDescriptorSet opaqueCulling;
|
Gfx::PDescriptorSet opaqueCulling;
|
||||||
Gfx::PDescriptorSet transparentCulling;
|
Gfx::PDescriptorSet transparentCulling;
|
||||||
|
Gfx::PDescriptorSet shadowMapping;
|
||||||
|
|
||||||
// use a different texture here so we can do multisampling
|
// use a different texture here so we can do multisampling
|
||||||
Gfx::OTexture2D msBasePassDepth;
|
Gfx::OTexture2D msBasePassDepth;
|
||||||
@@ -49,6 +56,7 @@ class BasePass : public RenderPass {
|
|||||||
PCameraActor source;
|
PCameraActor source;
|
||||||
Gfx::OPipelineLayout basePassLayout;
|
Gfx::OPipelineLayout basePassLayout;
|
||||||
Gfx::ODescriptorLayout lightCullingLayout;
|
Gfx::ODescriptorLayout lightCullingLayout;
|
||||||
|
Gfx::ODescriptorLayout shadowMappingLayout;
|
||||||
|
|
||||||
Gfx::OPipelineStatisticsQuery query;
|
Gfx::OPipelineStatisticsQuery query;
|
||||||
Gfx::PTimestampQuery timestamps;
|
Gfx::PTimestampQuery timestamps;
|
||||||
@@ -58,6 +66,12 @@ class BasePass : public RenderPass {
|
|||||||
//OWaterRenderer waterRenderer;
|
//OWaterRenderer waterRenderer;
|
||||||
//OTerrainRenderer terrainRenderer;
|
//OTerrainRenderer terrainRenderer;
|
||||||
|
|
||||||
|
// Shadow mapping
|
||||||
|
Gfx::PTexture2D shadowMaps[NUM_CASCADES];
|
||||||
|
Gfx::PShaderBuffer lightSpaceMatrices[NUM_CASCADES];
|
||||||
|
Gfx::OSampler shadowSampler;
|
||||||
|
Gfx::PUniformBuffer cascadeSplits;
|
||||||
|
|
||||||
// Debug rendering
|
// Debug rendering
|
||||||
Gfx::OVertexInput debugVertexInput;
|
Gfx::OVertexInput debugVertexInput;
|
||||||
Gfx::OVertexBuffer debugVertices;
|
Gfx::OVertexBuffer debugVertices;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "RenderGraphResources.h"
|
#include "RenderGraphResources.h"
|
||||||
#include "Graphics/Query.h"
|
#include "Graphics/Query.h"
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ ShadowPass::ShadowPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graph
|
|||||||
ShadowPass::~ShadowPass() {}
|
ShadowPass::~ShadowPass() {}
|
||||||
|
|
||||||
void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Transform& transform) {
|
void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Transform& transform) {
|
||||||
uint32 cascadeDim = SHADOW_MAP_SIZE;
|
|
||||||
float cascadeSplits[NUM_CASCADES];
|
float cascadeSplits[NUM_CASCADES];
|
||||||
|
|
||||||
float nearClip = camera.nearPlane;
|
float nearClip = camera.nearPlane;
|
||||||
@@ -58,19 +57,6 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
float ratio = maxZ / minZ;
|
float ratio = maxZ / minZ;
|
||||||
constexpr float cascadeSplitLambda = 0.95f;
|
constexpr float cascadeSplitLambda = 0.95f;
|
||||||
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||||
cascades[i].shadowMaps = graphics->createTexture2D(TextureCreateInfo{
|
|
||||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
|
||||||
.width = cascadeDim,
|
|
||||||
.height = cascadeDim,
|
|
||||||
.elements = (uint32)scene->getLightEnvironment()->getNumDirectionalLights(),
|
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
|
||||||
.name = "ShadowMapCascade",
|
|
||||||
});
|
|
||||||
cascades[i].views.clear();
|
|
||||||
for (uint32 j = 0; j < cascades[i].shadowMaps->getNumLayers(); ++j) {
|
|
||||||
cascades[i].views.add(cascades[i].shadowMaps->createTextureView(0, 1, j, 1));
|
|
||||||
}
|
|
||||||
cascadeDim /= 2;
|
|
||||||
float p = (i + 1) / static_cast<float>(NUM_CASCADES);
|
float p = (i + 1) / static_cast<float>(NUM_CASCADES);
|
||||||
float log = minZ * std::pow(ratio, p);
|
float log = minZ * std::pow(ratio, p);
|
||||||
float uniform = minZ + range * p;
|
float uniform = minZ + range * p;
|
||||||
@@ -131,6 +117,8 @@ void ShadowPass::beginFrame(const Component::Camera& camera, const Component::Tr
|
|||||||
viewParams.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y);
|
viewParams.screenDimensions = Vector2(maxExtents.x - minExtents.x, maxExtents.y - minExtents.y);
|
||||||
viewParams.invScreenDimensions = 1.0f / viewParams.screenDimensions;
|
viewParams.invScreenDimensions = 1.0f / viewParams.screenDimensions;
|
||||||
cascades[i].viewParams.add(createViewParamsSet());
|
cascades[i].viewParams.add(createViewParamsSet());
|
||||||
|
|
||||||
|
lastSplitDist = cascadeSplits[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,9 +134,9 @@ void ShadowPass::render() {
|
|||||||
Array<Gfx::ORenderCommand> commands;
|
Array<Gfx::ORenderCommand> commands;
|
||||||
renderPass = graphics->createRenderPass(
|
renderPass = graphics->createRenderPass(
|
||||||
Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout{
|
||||||
.depthAttachment = Gfx::RenderTargetAttachment(
|
.depthAttachment = Gfx::RenderTargetAttachment(cascades[c].views[shadowIndex], Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
cascades[c].views[shadowIndex], Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE),
|
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE),
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -219,7 +207,8 @@ void ShadowPass::render() {
|
|||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
command->bindDescriptor({cascades[c].viewParams[shadowIndex], vertexData->getVertexDataSet(), vertexData->getInstanceDataSet()});
|
command->bindDescriptor(
|
||||||
|
{cascades[c].viewParams[shadowIndex], vertexData->getVertexDataSet(), vertexData->getInstanceDataSet()});
|
||||||
VertexData::DrawCallOffsets offsets = {
|
VertexData::DrawCallOffsets offsets = {
|
||||||
.instanceOffset = 0,
|
.instanceOffset = 0,
|
||||||
};
|
};
|
||||||
@@ -258,6 +247,12 @@ void ShadowPass::render() {
|
|||||||
void ShadowPass::endFrame() {}
|
void ShadowPass::endFrame() {}
|
||||||
|
|
||||||
void ShadowPass::publishOutputs() {
|
void ShadowPass::publishOutputs() {
|
||||||
|
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{.sourceData =
|
||||||
|
{
|
||||||
|
.size = sizeof(float) * NUM_CASCADES,
|
||||||
|
.data = nullptr,
|
||||||
|
},
|
||||||
|
.name = "CascadeSplits"});
|
||||||
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
shadowViewport = graphics->createViewport(nullptr, ViewportCreateInfo{.dimensions =
|
||||||
{
|
{
|
||||||
.size = {SHADOW_MAP_SIZE, SHADOW_MAP_SIZE},
|
.size = {SHADOW_MAP_SIZE, SHADOW_MAP_SIZE},
|
||||||
@@ -268,6 +263,39 @@ void ShadowPass::publishOutputs() {
|
|||||||
.right = 100,
|
.right = 100,
|
||||||
.top = 100,
|
.top = 100,
|
||||||
.bottom = -100});
|
.bottom = -100});
|
||||||
|
uint32 cascadeDim = SHADOW_MAP_SIZE;
|
||||||
|
for (uint32 s = 0; s < NUM_CASCADES; ++s) {
|
||||||
|
cascades[s].shadowMaps = graphics->createTexture2DArray(TextureCreateInfo{
|
||||||
|
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||||
|
.width = cascadeDim,
|
||||||
|
.height = cascadeDim,
|
||||||
|
.elements = 1, // TODO:
|
||||||
|
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
.name = "ShadowMapCascade",
|
||||||
|
});
|
||||||
|
cascades[s].lightSpaceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData = {
|
||||||
|
.size = sizeof(Matrix4),
|
||||||
|
.data = nullptr,
|
||||||
|
},
|
||||||
|
.name = "LightSpaceBuffer"
|
||||||
|
});
|
||||||
|
cascades[s].views.clear();
|
||||||
|
for (uint32 j = 0; j < cascades[s].shadowMaps->getNumLayers(); ++j) {
|
||||||
|
cascades[s].views.add(cascades[s].shadowMaps->createTextureView(0, 1, j, 1));
|
||||||
|
}
|
||||||
|
cascadeDim /= 2;
|
||||||
|
resources->registerTextureOutput(fmt::format("SHADOWMAP_TEXTURE{0}", s), Gfx::PTexture2DArray(cascades[s].shadowMaps));
|
||||||
|
resources->registerBufferOutput(fmt::format("SHADOWMAP_LIGHTSPACE{0}", s), cascades[s].lightSpaceBuffer);
|
||||||
|
}
|
||||||
|
cascadeSplitsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||||
|
.sourceData = {
|
||||||
|
.size = sizeof(float) * NUM_CASCADES,
|
||||||
|
.data = nullptr,
|
||||||
|
},
|
||||||
|
.name = "CASCADE_SPLITS"
|
||||||
|
});
|
||||||
|
resources->registerUniformOutput("SHADOWMAP_CASCADESPLITS", cascadeSplitsBuffer);
|
||||||
viewport = shadowViewport;
|
viewport = shadowViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
namespace Seele {
|
namespace Seele {
|
||||||
|
|
||||||
static constexpr uint64 SHADOW_MAP_SIZE = 8192;
|
static constexpr uint64 SHADOW_MAP_SIZE = 8192;
|
||||||
|
static constexpr uint64 NUM_CASCADES = 4;
|
||||||
|
|
||||||
class ShadowPass : public RenderPass {
|
class ShadowPass : public RenderPass {
|
||||||
public:
|
public:
|
||||||
@@ -20,13 +21,15 @@ class ShadowPass : public RenderPass {
|
|||||||
virtual void createRenderPass() override;
|
virtual void createRenderPass() override;
|
||||||
private:
|
private:
|
||||||
AABB cameraFrustumBox;
|
AABB cameraFrustumBox;
|
||||||
static constexpr uint64 NUM_CASCADES = 4;
|
|
||||||
struct Cascade {
|
struct Cascade {
|
||||||
Gfx::OTexture2D shadowMaps;
|
Gfx::OTexture2DArray shadowMaps;
|
||||||
Array<Gfx::OTextureView> views;
|
Array<Gfx::OTextureView> views;
|
||||||
|
Array<Matrix4> lightSpaceMatrices;
|
||||||
|
Gfx::OShaderBuffer lightSpaceBuffer;
|
||||||
Array<Gfx::PDescriptorSet> viewParams;
|
Array<Gfx::PDescriptorSet> viewParams;
|
||||||
};
|
};
|
||||||
StaticArray<Cascade, NUM_CASCADES> cascades;
|
StaticArray<Cascade, NUM_CASCADES> cascades;
|
||||||
|
Gfx::OUniformBuffer cascadeSplitsBuffer;
|
||||||
Gfx::OPipelineLayout shadowLayout;
|
Gfx::OPipelineLayout shadowLayout;
|
||||||
Gfx::PShaderBuffer cullingBuffer;
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
Gfx::OViewport shadowViewport;
|
Gfx::OViewport shadowViewport;
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ Texture2D::Texture2D(QueueFamilyMapping mapping) : Texture(mapping) {}
|
|||||||
|
|
||||||
Texture2D::~Texture2D() {}
|
Texture2D::~Texture2D() {}
|
||||||
|
|
||||||
|
Texture2DArray::Texture2DArray(QueueFamilyMapping mapping) : Texture(mapping) {}
|
||||||
|
|
||||||
|
Texture2DArray::~Texture2DArray() {}
|
||||||
|
|
||||||
Texture3D::Texture3D(QueueFamilyMapping mapping) : Texture(mapping) {}
|
Texture3D::Texture3D(QueueFamilyMapping mapping) : Texture(mapping) {}
|
||||||
|
|
||||||
Texture3D::~Texture3D() {}
|
Texture3D::~Texture3D() {}
|
||||||
|
|||||||
@@ -75,6 +75,32 @@ class Texture2D : public Texture {
|
|||||||
};
|
};
|
||||||
DEFINE_REF(Texture2D)
|
DEFINE_REF(Texture2D)
|
||||||
|
|
||||||
|
class Texture2DArray : public Texture {
|
||||||
|
public:
|
||||||
|
Texture2DArray(QueueFamilyMapping mapping);
|
||||||
|
virtual ~Texture2DArray();
|
||||||
|
|
||||||
|
virtual SeFormat getFormat() const = 0;
|
||||||
|
virtual uint32 getWidth() const = 0;
|
||||||
|
virtual uint32 getHeight() const = 0;
|
||||||
|
virtual uint32 getDepth() const = 0;
|
||||||
|
virtual uint32 getNumLayers() const = 0;
|
||||||
|
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||||
|
virtual uint32 getMipLevels() const = 0;
|
||||||
|
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||||
|
SePipelineStageFlags dstStage) = 0;
|
||||||
|
virtual void generateMipmaps() = 0;
|
||||||
|
virtual PTextureView getDefaultView() const = 0;
|
||||||
|
|
||||||
|
virtual OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) = 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(Texture2DArray)
|
||||||
|
|
||||||
class Texture3D : public Texture {
|
class Texture3D : public Texture {
|
||||||
public:
|
public:
|
||||||
Texture3D(QueueFamilyMapping mapping);
|
Texture3D(QueueFamilyMapping mapping);
|
||||||
|
|||||||
@@ -9,10 +9,11 @@
|
|||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "RayTracing.h"
|
#include "RayTracing.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
#include "Enums.h"
|
||||||
|
#include <iostream>
|
||||||
#include "vulkan/vulkan_core.h"
|
#include "vulkan/vulkan_core.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <ranges>
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
@@ -32,10 +33,10 @@ void DescriptorLayout::create() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Array<VkDescriptorBindingFlags> bindingFlags;
|
Array<VkDescriptorBindingFlags> bindingFlags;
|
||||||
if (std::ranges::contains(descriptorBindings, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &Gfx::DescriptorBinding::descriptorType)) {
|
if (std::ranges::contains(descriptorBindings, Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, &Gfx::DescriptorBinding::descriptorType)) {
|
||||||
bindings.add({
|
bindings.add({
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // although we can pretend that we support inline uniforms, slang does not generate them
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = VK_SHADER_STAGE_ALL, // todo
|
.stageFlags = VK_SHADER_STAGE_ALL, // todo
|
||||||
.pImmutableSamplers = nullptr,
|
.pImmutableSamplers = nullptr,
|
||||||
@@ -43,11 +44,12 @@ void DescriptorLayout::create() {
|
|||||||
bindingFlags.add(0);
|
bindingFlags.add(0);
|
||||||
}
|
}
|
||||||
for (const auto& gfxBinding : descriptorBindings) {
|
for (const auto& gfxBinding : descriptorBindings) {
|
||||||
if (gfxBinding.descriptorType == Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
|
if (gfxBinding.descriptorType == Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) {
|
||||||
mappings[gfxBinding.name] = {
|
mappings[gfxBinding.name] = {
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.constantOffset = constantsSize,
|
.constantOffset = constantsSize,
|
||||||
.constantSize = gfxBinding.uniformLength,
|
.constantSize = gfxBinding.uniformLength,
|
||||||
|
.type = cast(gfxBinding.descriptorType),
|
||||||
};
|
};
|
||||||
constantsSize += gfxBinding.uniformLength;
|
constantsSize += gfxBinding.uniformLength;
|
||||||
constantsStages |= gfxBinding.shaderStages;
|
constantsStages |= gfxBinding.shaderStages;
|
||||||
@@ -92,15 +94,15 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
|||||||
cachedHandles[i] = nullptr;
|
cachedHandles[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Gfx::SeDescriptorType, uint32> perTypeSizes;
|
Map<VkDescriptorType, uint32> perTypeSizes;
|
||||||
for (uint32 i = 0; i < layout->getBindings().size(); ++i) {
|
for (uint32 i = 0; i < layout->bindings.size(); ++i) {
|
||||||
auto& binding = layout->getBindings()[i];
|
auto& binding = layout->bindings[i];
|
||||||
perTypeSizes[binding.descriptorType] += 512;
|
perTypeSizes[binding.descriptorType] += 512;
|
||||||
}
|
}
|
||||||
Array<VkDescriptorPoolSize> poolSizes;
|
Array<VkDescriptorPoolSize> poolSizes;
|
||||||
for (const auto& [type, num] : perTypeSizes) {
|
for (const auto& [type, num] : perTypeSizes) {
|
||||||
poolSizes.add(VkDescriptorPoolSize{
|
poolSizes.add(VkDescriptorPoolSize{
|
||||||
.type = cast(type),
|
.type = type,
|
||||||
.descriptorCount = num,
|
.descriptorCount = num,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -199,9 +201,9 @@ void DescriptorPool::reset() {
|
|||||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics, owner->getLayout()->getName()), setHandle(VK_NULL_HANDLE),
|
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics, owner->getLayout()->getName()), setHandle(VK_NULL_HANDLE),
|
||||||
graphics(graphics), owner(owner) {
|
graphics(graphics), owner(owner) {
|
||||||
boundResources.resize(owner->getLayout()->getBindings().size());
|
boundResources.resize(owner->getLayout()->bindings.size());
|
||||||
for (uint32 i = 0; i < boundResources.size(); ++i) {
|
for (uint32 i = 0; i < boundResources.size(); ++i) {
|
||||||
boundResources[i].resize(owner->getLayout()->getBindings()[i].descriptorCount);
|
boundResources[i].resize(owner->getLayout()->bindings[i].descriptorCount);
|
||||||
for (size_t x = 0; x < boundResources[i].size(); ++x) {
|
for (size_t x = 0; x < boundResources[i].size(); ++x) {
|
||||||
boundResources[i][x] = nullptr;
|
boundResources[i][x] = nullptr;
|
||||||
}
|
}
|
||||||
@@ -243,8 +245,8 @@ void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, G
|
|||||||
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PVertexBuffer indexBuffer) {
|
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PVertexBuffer vertexBuffer) {
|
||||||
PVertexBuffer vulkanBuffer = indexBuffer.cast<VertexBuffer>();
|
PVertexBuffer vulkanBuffer = vertexBuffer.cast<VertexBuffer>();
|
||||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||||
uint32 binding = map.binding;
|
uint32 binding = map.binding;
|
||||||
// if the buffer is empty
|
// if the buffer is empty
|
||||||
@@ -297,6 +299,33 @@ void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, G
|
|||||||
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DescriptorSet::updateBuffer(const std::string& mappingName, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
|
||||||
|
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||||
|
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||||
|
uint32 binding = map.binding;
|
||||||
|
// if the buffer is empty
|
||||||
|
if (vulkanBuffer->getAlloc() == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bufferInfos.add(VkDescriptorBufferInfo{
|
||||||
|
.buffer = vulkanBuffer->getHandle(),
|
||||||
|
.offset = 0,
|
||||||
|
.range = vulkanBuffer->getSize(),
|
||||||
|
});
|
||||||
|
writeDescriptors.add(VkWriteDescriptorSet{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.dstSet = setHandle,
|
||||||
|
.dstBinding = binding,
|
||||||
|
.dstArrayElement = index,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = map.type,
|
||||||
|
.pBufferInfo = &bufferInfos.back(),
|
||||||
|
});
|
||||||
|
|
||||||
|
boundResources[binding][index] = vulkanBuffer->getAlloc();
|
||||||
|
}
|
||||||
|
|
||||||
void DescriptorSet::updateSampler(const std::string& mappingName, uint32 index, Gfx::PSampler samplerState) {
|
void DescriptorSet::updateSampler(const std::string& mappingName, uint32 index, Gfx::PSampler samplerState) {
|
||||||
PSampler vulkanSampler = samplerState.cast<Sampler>();
|
PSampler vulkanSampler = samplerState.cast<Sampler>();
|
||||||
const auto& map = owner->getLayout()->mappings[mappingName];
|
const auto& map = owner->getLayout()->mappings[mappingName];
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Containers/List.h"
|
#include "Containers/List.h"
|
||||||
#include "Enums.h"
|
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Vulkan/Buffer.h"
|
#include "Graphics/Vulkan/Buffer.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
@@ -61,8 +60,9 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
|||||||
virtual void writeChanges() override;
|
virtual void writeChanges() override;
|
||||||
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) override;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) override;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer indexBuffer) override;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer vertexBuffer) override;
|
||||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) override;
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer indexBuffer) override;
|
||||||
|
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) override;
|
||||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
||||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) override;
|
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) override;
|
||||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
||||||
|
|||||||
@@ -222,6 +222,8 @@ void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
|||||||
|
|
||||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
||||||
|
|
||||||
|
Gfx::OTexture2DArray Graphics::createTexture2DArray(const TextureCreateInfo& createInfo) { return new Texture2DArray(this, createInfo); }
|
||||||
|
|
||||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
||||||
|
|
||||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ class Graphics : public Gfx::Graphics {
|
|||||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||||
|
|
||||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
||||||
|
virtual Gfx::OTexture2DArray createTexture2DArray(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
||||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
||||||
|
|||||||
@@ -444,18 +444,21 @@ void TextureBase::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags
|
|||||||
handle->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
handle->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
void TextureBase::transferOwnership(Gfx::QueueType newOwner) { handle->transferOwnership(newOwner); }
|
void TextureBase::transferOwnership(Gfx::QueueType newOwner) { handle->transferOwnership(newOwner); }
|
||||||
|
|
||||||
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
|
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
|
||||||
handle->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
handle->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||||
handle->download(mipLevel, arrayLayer, face, buffer);
|
handle->download(mipLevel, arrayLayer, face, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBase::generateMipmaps() { handle->generateMipmaps(); }
|
void TextureBase::generateMipmaps() { handle->generateMipmaps(); }
|
||||||
|
|
||||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
: Gfx::Texture2D(graphics->getFamilyMapping()),
|
: Gfx::Texture2D(graphics->getFamilyMapping()),
|
||||||
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, createInfo, existingImage) {}
|
TextureBase(graphics, VK_IMAGE_VIEW_TYPE_2D, createInfo, existingImage) {}
|
||||||
|
|
||||||
Texture2D::~Texture2D() {}
|
Texture2D::~Texture2D() {}
|
||||||
|
|
||||||
@@ -483,6 +486,36 @@ void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageF
|
|||||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture2DArray::Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
|
: Gfx::Texture2DArray(graphics->getFamilyMapping()),
|
||||||
|
TextureBase(graphics, VK_IMAGE_VIEW_TYPE_2D_ARRAY, createInfo, existingImage) {}
|
||||||
|
|
||||||
|
Texture2DArray::~Texture2DArray() {}
|
||||||
|
|
||||||
|
void Texture2DArray::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||||
|
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||||
|
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||||
|
|
||||||
|
Gfx::PTextureView Texture2DArray::getDefaultView() const { return PTextureView(handle->imageView); }
|
||||||
|
|
||||||
|
Gfx::OTextureView Texture2DArray::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||||
|
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture2DArray::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||||
|
|
||||||
|
void Texture2DArray::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||||
|
VkPipelineStageFlags dstStage) {
|
||||||
|
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||||
|
}
|
||||||
|
|
||||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D, createInfo, existingImage) {}
|
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D, createInfo, existingImage) {}
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,32 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
|||||||
};
|
};
|
||||||
DEFINE_REF(Texture2D)
|
DEFINE_REF(Texture2D)
|
||||||
|
|
||||||
|
class Texture2DArray : public Gfx::Texture2DArray, public TextureBase {
|
||||||
|
public:
|
||||||
|
Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||||
|
virtual ~Texture2DArray();
|
||||||
|
virtual uint32 getWidth() const override { return handle->width; }
|
||||||
|
virtual uint32 getHeight() const override { return handle->height; }
|
||||||
|
virtual uint32 getDepth() const override { return handle->depth; }
|
||||||
|
virtual uint32 getNumLayers() const override { return handle->layerCount; }
|
||||||
|
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||||
|
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||||
|
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||||
|
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||||
|
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||||
|
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||||
|
virtual void generateMipmaps() override;
|
||||||
|
virtual Gfx::PTextureView getDefaultView() const override;
|
||||||
|
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Inherited via QueueOwnedResource
|
||||||
|
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||||
|
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||||
|
VkPipelineStageFlags dstStage) override;
|
||||||
|
};
|
||||||
|
DEFINE_REF(Texture2DArray)
|
||||||
|
|
||||||
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||||
public:
|
public:
|
||||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||||
|
|||||||
@@ -14,14 +14,6 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
|
|||||||
.name = "directionalLights",
|
.name = "directionalLights",
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
});
|
});
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
||||||
.name = "shadowMap",
|
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
||||||
});
|
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
||||||
.name = "shadowSampler",
|
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
|
||||||
});
|
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "numDirectionalLights",
|
.name = "numDirectionalLights",
|
||||||
.uniformLength = sizeof(uint32),
|
.uniformLength = sizeof(uint32),
|
||||||
|
|||||||
Reference in New Issue
Block a user