Nameless Engine
Loading...
Searching...
No Matches
HlslShaderTextureResourceBinding.h
1#pragma once
2
3// Standard.
4#include <string>
5#include <memory>
6#include <unordered_set>
7#include <variant>
8#include <mutex>
9
10// Custom.
11#include "shader/general/resource/binding/ShaderResourceBinding.h"
12#include "render/directx/descriptors/DirectXDescriptorHeap.h"
13#include "render/general/pipeline/PipelineShaderConstantsManager.hpp"
14#include "render/directx/resource/DirectXResource.h"
15
16namespace ne {
17 class TextureHandle;
18 class Pipeline;
19 class DirectXPso;
20 class Renderer;
21
24 // Only the manager should be able to create such resources.
26
27 public:
28 virtual ~HlslShaderTextureResourceBinding() override = default;
29
37 PipelineShaderConstantsManager* pShaderConstantsManager, DirectXPso* pUsedPipeline) {
38 // Since pipelines won't change here (because we are inside of the `draw` function)
39 // we don't need to lock the mutex here.
40
41 // Find shader constant offset.
42 const auto it = mtxShaderConstantOffsetPerPipeline.second.find(pUsedPipeline);
43 if (it == mtxShaderConstantOffsetPerPipeline.second.end()) [[unlikely]] {
44 Error error(std::format(
45 "shader resource \"{}\" was requested to set its root constant "
46 "index but this shader resource does not reference the specified pipeline",
49 error.showError();
50 throw std::runtime_error(error.getFullErrorMessage());
51 }
52 const auto& shaderConstantsOffsets = it->second;
53
54 // Query texture's SRV descriptor offset in the descriptor range.
55 unsigned int iRootConstantValue = 0;
56 unsigned int iSamplerArrayOffset = 0; // also save offset into the array of texture samplers
57 {
58 std::scoped_lock textureGuard(mtxUsedTexture.first);
59
60 iSamplerArrayOffset = mtxUsedTexture.second.iTextureSamplerOffset;
61
62 const auto pDirectXTexture =
63 reinterpret_cast<DirectXResource*>(mtxUsedTexture.second.pTexture->getResource());
64
65 // Get SRV.
66 const auto pSrvDescriptor = pDirectXTexture->getDescriptor(DirectXDescriptorType::SRV);
67 if (pSrvDescriptor == nullptr) [[unlikely]] {
68 Error error(std::format(
69 "shader resource \"{}\" was requested to set its root constant "
70 "index but used texture \"{}\" does not seem to have an SRV bound",
72 pDirectXTexture->getResourceName()));
73 error.showError();
74 throw std::runtime_error(error.getFullErrorMessage());
75 }
76
77 // Calculate descriptor offset. This may not be as fast as we want but this is the price we
78 // pay for having a simple approach. We could have cached the offset but we would need to keep
79 // the cached offset updated after the range resizes which seems like a complicated thing.
80 auto result = pSrvDescriptor->getOffsetFromRangeStartOnCurrentFrame();
81 if (std::holds_alternative<Error>(result)) [[unlikely]] {
82 auto error = std::get<Error>(std::move(result));
83 error.addCurrentLocationToErrorStack();
84 error.showError();
85 throw std::runtime_error(error.getFullErrorMessage());
86 }
87
88 iRootConstantValue = std::get<unsigned int>(result);
89 }
90
91 // Copy descriptor range offset to root constants.
92 pShaderConstantsManager->copyValueToShaderConstant(
93 shaderConstantsOffsets.iTextureShaderConstantIndex, iRootConstantValue);
94
95 // Also set offset into the sampler array.
96 pShaderConstantsManager->copyValueToShaderConstant(
97 shaderConstantsOffsets.iSamplerArrayOffsetConstantIndex, iSamplerArrayOffset);
98 }
99
111 [[nodiscard]] virtual std::optional<Error>
112 useNewTexture(std::unique_ptr<TextureHandle> pTextureToUse) override;
113
130 [[nodiscard]] virtual std::optional<Error>
131 changeUsedPipelines(const std::unordered_set<Pipeline*>& pipelinesToUse) override;
132
133 protected:
138
141 };
142
144 struct TextureInfo {
146 std::unique_ptr<TextureHandle> pTexture;
147
149 unsigned int iTextureSamplerOffset = 0;
150 };
151
165 const std::string& sResourceName,
166 TextureInfo textureInfo,
167 std::unordered_map<DirectXPso*, ShaderConstantOffsets>&& shaderConstantOffsetPerPipeline,
169
179 [[nodiscard]] virtual std::optional<Error> onAfterAllPipelinesRefreshedResources() override;
180
181 private:
192 static std::variant<std::unique_ptr<ShaderTextureResourceBinding>, Error> create(
193 const std::string& sShaderResourceName,
194 const std::unordered_set<Pipeline*>& pipelinesToUse,
195 std::unique_ptr<TextureHandle> pTexture);
196
206 static std::variant<std::shared_ptr<ContinuousDirectXDescriptorRange>, Error>
207 getSrvDescriptorRange(DirectXPso* pPipeline, const std::string& sShaderResourceName);
208
217 static unsigned int getTextureSamplerOffset(DirectXResource* pTexture, Renderer* pRenderer);
218
220 std::pair<std::mutex, TextureInfo> mtxUsedTexture;
221
223 std::pair<std::recursive_mutex, std::unordered_map<DirectXPso*, ShaderConstantOffsets>>
225
227 Renderer* const pRenderer = nullptr;
228
230 static constexpr std::string_view sIndexIntoTextureSamplersArrayShaderConstantName =
231 "iIndexIntoTextureSamplersArrayForDiffuse";
232
237 static constexpr bool bBindSrvToCubemapFaces = false;
238 };
239} // namespace ne
Definition: DirectXPso.h:22
Definition: DirectXResource.h:33
DirectXDescriptor * getDescriptor(DirectXDescriptorType descriptorType)
Definition: DirectXResource.cpp:184
Definition: Error.h:27
std::string getFullErrorMessage() const
Definition: Error.cpp:84
void showError() const
Definition: Error.cpp:102
Definition: HlslShaderTextureResourceBinding.h:23
std::pair< std::mutex, TextureInfo > mtxUsedTexture
Definition: HlslShaderTextureResourceBinding.h:220
void copyResourceIndexToRootConstants(PipelineShaderConstantsManager *pShaderConstantsManager, DirectXPso *pUsedPipeline)
Definition: HlslShaderTextureResourceBinding.h:36
std::pair< std::recursive_mutex, std::unordered_map< DirectXPso *, ShaderConstantOffsets > > mtxShaderConstantOffsetPerPipeline
Definition: HlslShaderTextureResourceBinding.h:224
static std::variant< std::shared_ptr< ContinuousDirectXDescriptorRange >, Error > getSrvDescriptorRange(DirectXPso *pPipeline, const std::string &sShaderResourceName)
Definition: HlslShaderTextureResourceBinding.cpp:18
virtual std::optional< Error > changeUsedPipelines(const std::unordered_set< Pipeline * > &pipelinesToUse) override
Definition: HlslShaderTextureResourceBinding.cpp:302
static unsigned int getTextureSamplerOffset(DirectXResource *pTexture, Renderer *pRenderer)
Definition: HlslShaderTextureResourceBinding.cpp:91
virtual std::optional< Error > useNewTexture(std::unique_ptr< TextureHandle > pTextureToUse) override
Definition: HlslShaderTextureResourceBinding.cpp:252
static constexpr std::string_view sIndexIntoTextureSamplersArrayShaderConstantName
Definition: HlslShaderTextureResourceBinding.h:230
static constexpr bool bBindSrvToCubemapFaces
Definition: HlslShaderTextureResourceBinding.h:237
virtual std::optional< Error > onAfterAllPipelinesRefreshedResources() override
Definition: HlslShaderTextureResourceBinding.cpp:232
static std::variant< std::unique_ptr< ShaderTextureResourceBinding >, Error > create(const std::string &sShaderResourceName, const std::unordered_set< Pipeline * > &pipelinesToUse, std::unique_ptr< TextureHandle > pTexture)
Definition: HlslShaderTextureResourceBinding.cpp:123
Renderer *const pRenderer
Definition: HlslShaderTextureResourceBinding.h:227
Definition: PipelineShaderConstantsManager.hpp:14
void copyValueToShaderConstant(size_t iShaderConstantIndex, unsigned int iValueToCopy)
Definition: PipelineShaderConstantsManager.hpp:75
Definition: Renderer.h:43
std::string getShaderResourceName() const
Definition: ShaderResourceBinding.cpp:11
const std::string sShaderResourceName
Definition: ShaderResourceBinding.h:82
Definition: ShaderTextureResourceBindingManager.h:27
Definition: ShaderResourceBinding.h:86
Definition: HlslShaderTextureResourceBinding.h:135
size_t iSamplerArrayOffsetConstantIndex
Definition: HlslShaderTextureResourceBinding.h:140
size_t iTextureShaderConstantIndex
Definition: HlslShaderTextureResourceBinding.h:137
Definition: HlslShaderTextureResourceBinding.h:144
std::unique_ptr< TextureHandle > pTexture
Definition: HlslShaderTextureResourceBinding.h:146
unsigned int iTextureSamplerOffset
Definition: HlslShaderTextureResourceBinding.h:149