Skip to content

Commit fae9cd6

Browse files
committed
添加贴图种类的选择
添加法线贴图 修复layout的bug passresource现在支持bind nullptr了(constlayout或者说uniform还不支持)
1 parent 6486e46 commit fae9cd6

10 files changed

Lines changed: 182 additions & 46 deletions

src/Context/Context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ namespace FCT
5050
class ConstBuffer;
5151
class IndexBuffer;
5252
}
53+
class Sampler;
5354

5455
class VertexBuffer;
5556
//class InputLayout;
@@ -126,6 +127,8 @@ namespace FCT
126127
template <typename T>
127128
T* createResource();
128129
virtual RHI::RasterizationPipeline* createTraditionPipeline() = 0;
130+
virtual RHI::ConstBuffer* getEmptyConstBuffer(const ConstLayout& layout) = 0;
131+
virtual Sampler* getEmptySampler() = 0;
129132
StaticMesh<uint32_t>* createMesh(const ModelMesh* modelMesh, const VertexLayout& layout);
130133
StaticMesh<uint32_t>* loadMesh(const std::string& filename,const std::string& meshName, const VertexLayout& layout);
131134
Image* loadTexture(const std::string& filename);

src/Context/RenderGraph.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,10 @@ void RenderGraph::removeDepthStencilEdge(DepthStencilEdge* edgeToRemove) {
919919
Image* image = imageNode->getImage();
920920
if (image) {
921921
imageStates[image] = ImageState{};
922+
if (dynamic_cast<RenderGraphWindowTargetNode*>(imageNode.get()) || dynamic_cast<RenderGraphWindowDepthStencilNode*>(imageNode.get()))
923+
{
924+
imageStates[image].currentLayout = ImageLayout::undefined;
925+
}
922926
}
923927
}
924928

@@ -970,10 +974,9 @@ void RenderGraph::removeDepthStencilEdge(DepthStencilEdge* edgeToRemove) {
970974

971975
bool needsBarrier = false;
972976

973-
if (currentState.currentLayout != requiredLayout &&
974-
currentState.currentLayout != ImageLayout::undefined) {
977+
if (currentState.currentLayout != requiredLayout) {
975978
needsBarrier = true;
976-
}
979+
}
977980

978981
if (!currentState.lastWriterGroup.empty() &&
979982
currentState.lastWriterGroup != groupLeader &&

src/Context/Uniform.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,15 @@ namespace FCT
329329
return true;
330330
}
331331

332+
size_t getHash() const noexcept {
333+
size_t seed = 0;
334+
boost::hash_combine(seed, std::string(m_name));
335+
for (size_t i = 0; i < m_elementCount; ++i) {
336+
boost::hash_combine(seed, m_elements[i].getType());
337+
}
338+
return seed;
339+
}
340+
332341
constexpr size_t getElementCount() const noexcept { return m_elementCount; }
333342

334343
constexpr const ConstElement& getElement(size_t index) const noexcept {

src/Context/VK_Context.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,40 @@ namespace FCT
1919
return new RHI::VK_TraditionalPipeline(this);
2020
}
2121

22+
RHI::ConstBuffer* VK_Context::getEmptyConstBuffer(const ConstLayout& layout)
23+
{
24+
size_t layoutHash = layout.getHash();
25+
auto it = m_emptyConstBufferCache.find(layoutHash);
26+
if (it != m_emptyConstBufferCache.end())
27+
{
28+
return it->second.get();
29+
}
30+
31+
auto emptyBuffer = createResource<RHI::ConstBuffer>();
32+
emptyBuffer->layout(layout);
33+
emptyBuffer->create(); // This will allocate a buffer of the correct size
34+
35+
RHI::ConstBuffer* bufferPtr = emptyBuffer;
36+
m_emptyConstBufferCache[layoutHash] = std::unique_ptr<RHI::ConstBuffer>(bufferPtr);
37+
return bufferPtr;
38+
}
39+
40+
Sampler* VK_Context::getEmptySampler()
41+
{
42+
if (m_emptySampler)
43+
{
44+
return m_emptySampler.get();
45+
}
46+
47+
auto sampler = createResource<Sampler>();
48+
sampler->setFilter(FCT::FilterMode::Linear, FCT::FilterMode::Linear, FCT::FilterMode::Linear);
49+
sampler->setAddressMode(FCT::AddressMode::ClampToEdge, FCT::AddressMode::ClampToEdge, FCT::AddressMode::ClampToEdge);
50+
sampler->create();
51+
52+
m_emptySampler = std::unique_ptr<Sampler>(sampler);
53+
return m_emptySampler.get();
54+
}
55+
2256
VK_Context::~VK_Context()
2357
{
2458
if (m_device) {

src/Context/VK_Context.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ namespace FCT {
4646
return m_graphicsQueue;
4747
}
4848

49+
RHI::ConstBuffer* getEmptyConstBuffer(const ConstLayout& layout) override;
50+
Sampler* getEmptySampler() override;
51+
4952
vk::CommandBuffer beginSingleTimeCommands();
5053
void endSingleTimeCommands(vk::CommandBuffer commandBuffer);
5154
void transferDataToBuffer(vk::Buffer dstBuffer, size_t size, const void* data);
@@ -70,6 +73,8 @@ namespace FCT {
7073
uint32_t m_transferQueueFamilyIndex;
7174
vk::Queue m_transferQueue;
7275
vk::CommandPool m_transferCommandPool;
76+
std::unordered_map<size_t, std::unique_ptr<RHI::ConstBuffer>> m_emptyConstBufferCache;
77+
std::unique_ptr<Sampler> m_emptySampler;
7378
};
7479
}
7580

src/Context/VK_PassResource.cpp

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,23 @@ namespace FCT
2626

2727
void VK_PassResource::addConstBuffer(RHI::ConstBuffer* buffer)
2828
{
29-
if (buffer) {
30-
m_constBuffers.push_back(buffer);
31-
markAllDescriptorSetsDirty();
32-
markAllDescriptorSetsNeedRecreate();
33-
}
29+
m_constBuffers.push_back(buffer);
30+
markAllDescriptorSetsDirty();
31+
markAllDescriptorSetsNeedRecreate();
3432
}
3533

3634
void VK_PassResource::addSampler(Sampler* sampler, SamplerElement element)
3735
{
38-
if (sampler) {
39-
m_samplers.emplace_back(sampler, element);
40-
markAllDescriptorSetsDirty();
41-
markAllDescriptorSetsNeedRecreate();
42-
}
36+
m_samplers.emplace_back(sampler, element);
37+
markAllDescriptorSetsDirty();
38+
markAllDescriptorSetsNeedRecreate();
4339
}
4440

4541
void VK_PassResource::addTexture(Image* texture, TextureElement element)
4642
{
47-
if (texture) {
48-
m_textures[element] = texture;
49-
markAllDescriptorSetsDirty();
50-
markAllDescriptorSetsNeedRecreate();
51-
}
43+
m_textures[element] = texture;
44+
markAllDescriptorSetsDirty();
45+
markAllDescriptorSetsNeedRecreate();
5246
}
5347

5448
void VK_PassResource::setTexture(Image* texture, TextureElement element)
@@ -103,6 +97,7 @@ bool VK_PassResource::createDescriptorSetsAndLayouts(uint32_t frameIdx,
10397
std::map<uint32_t, std::vector<vk::DescriptorSetLayoutBinding>> setBindings;
10498

10599
for (auto* constBuffer : m_constBuffers) {
100+
if (!constBuffer) continue;
106101
auto* vkConstBuffer = static_cast<RHI::VK_ConstBuffer*>(constBuffer);
107102
auto uniformLayout = vkConstBuffer->layout();
108103
auto [setIndex, binding] = m_ctx->getGenerator()->getLayoutBinding(uniformLayout);
@@ -246,6 +241,9 @@ bool VK_PassResource::createDescriptorSetsAndLayouts(uint32_t frameIdx,
246241

247242
for (size_t i = 0; i < m_constBuffers.size(); ++i) {
248243
auto* srcConstBuffer = m_constBuffers[i];
244+
if (!srcConstBuffer) {
245+
continue;
246+
}
249247
auto* constBuffer = static_cast<RHI::VK_ConstBuffer*>(srcConstBuffer);
250248
auto uniformLayout = constBuffer->layout();
251249
auto [setIndex, binding] = m_ctx->getGenerator()->getLayoutBinding(uniformLayout);
@@ -268,17 +266,23 @@ bool VK_PassResource::createDescriptorSetsAndLayouts(uint32_t frameIdx,
268266
}
269267

270268
for (auto& [element, texture ] : m_textures) {
271-
auto* vkTexture = static_cast<RHI::VK_TextureView*>(texture->currentTextureView());
272269
auto [setIndex, binding] = m_ctx->getGenerator()->getTextureBinding(element);
273270

274-
if (setIndex >= m_descriptorSets[frameIdx].size() || !vkTexture) {
271+
if (setIndex >= m_descriptorSets[frameIdx].size()) {
275272
continue;
276273
}
277274

278275
vk::DescriptorImageInfo imageInfo;
279276
imageInfo.setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
280-
imageInfo.setImageView(vkTexture->view());
281277
imageInfo.setSampler(nullptr);
278+
279+
if (texture) {
280+
auto* vkTexture = static_cast<RHI::VK_TextureView*>(texture->currentTextureView());
281+
imageInfo.setImageView(vkTexture ? vkTexture->view() : VK_NULL_HANDLE);
282+
} else {
283+
imageInfo.setImageView(VK_NULL_HANDLE);
284+
}
285+
282286
textureInfos.push_back(imageInfo);
283287

284288
vk::WriteDescriptorSet descriptorWrite;
@@ -287,24 +291,30 @@ bool VK_PassResource::createDescriptorSetsAndLayouts(uint32_t frameIdx,
287291
descriptorWrite.setDstArrayElement(0);
288292
descriptorWrite.setDescriptorType(vk::DescriptorType::eSampledImage);
289293
descriptorWrite.setDescriptorCount(1);
290-
descriptorWrite.setPImageInfo(&textureInfos[textureInfos.size() - 1]);
294+
descriptorWrite.setPImageInfo(&textureInfos.back());
291295

292296
descriptorWrites.push_back(descriptorWrite);
293297
}
294298

295299
for (size_t i = 0; i < m_samplers.size(); ++i) {
296300
auto& [sampler, element] = m_samplers[i];
297-
auto* vkSampler = static_cast<RHI::VK_Sampler*>(sampler);
298301
auto [setIndex, binding] = m_ctx->getGenerator()->getSamplerBinding(element);
299302

300-
if (setIndex >= m_descriptorSets[frameIdx].size() || !vkSampler) {
303+
if (setIndex >= m_descriptorSets[frameIdx].size()) {
301304
continue;
302305
}
303306

304307
vk::DescriptorImageInfo samplerInfo;
305-
samplerInfo.setSampler(vkSampler->getSampler());
306308
samplerInfo.setImageView(nullptr);
307309
samplerInfo.setImageLayout(vk::ImageLayout::eUndefined);
310+
311+
if (sampler) {
312+
auto* vkSampler = static_cast<RHI::VK_Sampler*>(sampler);
313+
samplerInfo.setSampler(vkSampler->getSampler());
314+
} else {
315+
samplerInfo.setSampler(VK_NULL_HANDLE);
316+
}
317+
308318
samplerInfos.push_back(samplerInfo);
309319

310320
vk::WriteDescriptorSet descriptorWrite;
@@ -313,7 +323,7 @@ bool VK_PassResource::createDescriptorSetsAndLayouts(uint32_t frameIdx,
313323
descriptorWrite.setDstArrayElement(0);
314324
descriptorWrite.setDescriptorType(vk::DescriptorType::eSampler);
315325
descriptorWrite.setDescriptorCount(1);
316-
descriptorWrite.setPImageInfo(&samplerInfos[samplerInfos.size() - 1]);
326+
descriptorWrite.setPImageInfo(&samplerInfos.back());
317327

318328
descriptorWrites.push_back(descriptorWrite);
319329
}

src/Context/layout.cpp

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ namespace FCT
3131

3232
void Layout::addTextureSlot(FCT::TextureElement element)
3333
{
34+
if (m_resourceLayout.findTextureIndex(element.getName()) != -1) {
35+
return;
36+
}
3437
m_resourceLayout.addTexture(element);
3538
if (element.getShaderStages() & FCT::ShaderStage::Vertex)
3639
{
@@ -46,11 +49,13 @@ namespace FCT
4649
}
4750
void Layout::addUniformSlot(const UniformSlot& uniformSlot)
4851
{
52+
if (m_uniformLayouts.count(uniformSlot.getName())) {
53+
return;
54+
}
4955
m_uniformLayouts[uniformSlot.getName()] = uniformSlot;
5056
clearShaderCache();
5157
clearPipelineCache();
5258
clearPassResourceCache();
53-
5459
}
5560

5661
void Layout::addTextureSlot(const FCT::TextureSlot& slot)
@@ -64,10 +69,9 @@ namespace FCT
6469

6570
void Layout::addSamplerSlot(const SamplerSlot& samplerSlot)
6671
{
67-
// 检查是否已存在相同名字的SamplerSlot,避免重复添加
6872
auto existingSampler = m_resourceLayout.findSampler(samplerSlot.getName());
6973
if (existingSampler.getName() != nullptr && existingSampler.getName()[0] != '\0') {
70-
return; // 已存在,不重复添加
74+
return;
7175
}
7276

7377
m_resourceLayout.addSampler(samplerSlot);
@@ -411,15 +415,38 @@ namespace FCT
411415
return m_passResourceCache.get(m_passResourceState, [this](const PassResourceState& state)
412416
{
413417
auto ret = m_ctx->createResource<FCT::PassResource>();
414-
for (const auto& tex : state.boundTextures) {
415-
ret->addTexture( tex.second,m_resourceLayout.findTexture(tex.first.c_str()));
418+
419+
for (const auto& layoutPair : m_uniformLayouts) {
420+
const std::string& name = layoutPair.first;
421+
const UniformSlot& slot = layoutPair.second;
422+
auto boundIt = state.boundUniforms.find(name);
423+
if (boundIt != state.boundUniforms.end()) {
424+
ret->addConstBuffer(boundIt->second);
425+
} else {
426+
ret->addConstBuffer(m_ctx->getEmptyConstBuffer(slot));
427+
}
416428
}
417-
for (const auto& samp : state.boundSamplers) {
418-
ret->addSampler(samp.second,m_resourceLayout.findSampler(samp.first.c_str()));
429+
430+
for (size_t i = 0; i < m_resourceLayout.getTextureCount(); ++i) {
431+
const TextureElement& element = m_resourceLayout.getTexture(i);
432+
auto boundIt = state.boundTextures.find(element.getName());
433+
if (boundIt != state.boundTextures.end()) {
434+
ret->addTexture(boundIt->second, element);
435+
} else {
436+
ret->addTexture(nullptr, element);
437+
}
419438
}
420-
for (const auto& uni : state.boundUniforms) {
421-
ret->addConstBuffer(uni.second);
439+
440+
for (size_t i = 0; i < m_resourceLayout.getSamplerCount(); ++i) {
441+
const SamplerElement& element = m_resourceLayout.getSampler(i);
442+
auto boundIt = state.boundSamplers.find(element.getName());
443+
if (boundIt != state.boundSamplers.end()) {
444+
ret->addSampler(boundIt->second, element);
445+
} else {
446+
ret->addSampler(m_ctx->getEmptySampler(), element);
447+
}
422448
}
449+
423450
ret->create();
424451
return ret;
425452
});

src/RHI/VK_RasterizationPipeline.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ namespace FCT::RHI
1919

2020
VK_RasterizationPipeline::~VK_RasterizationPipeline()
2121
{
22+
if (m_pipeline)
23+
{
24+
m_ctx->getDevice().destroyPipeline(m_pipeline);
25+
}
2226
FCT_SAFE_RELEASE(m_blendState);
2327
FCT_SAFE_RELEASE(m_rasterizationState);
2428
FCT_SAFE_RELEASE(m_viewportState);

0 commit comments

Comments
 (0)