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
23 // Only the manager should be able to create such resources.
25
26 public:
27 virtual ~HlslShaderTextureResourceBinding() override = default;
28
36 PipelineShaderConstantsManager* pShaderConstantsManager, DirectXPso* pUsedPipeline) {
37 // Since pipelines won't change here (because we are inside of the `draw` function)
38 // we don't need to lock the mutex here.
39
40 // Find shader constant offset.
41 const auto it = mtxShaderConstantOffsetPerPipeline.second.find(pUsedPipeline);
42 if (it == mtxShaderConstantOffsetPerPipeline.second.end()) [[unlikely]] {
43 Error error(std::format(
44 "shader resource \"{}\" was requested to set its root constant "
45 "index but this shader resource does not reference the specified pipeline",
48 error.showError();
49 throw std::runtime_error(error.getFullErrorMessage());
50 }
51 const auto& iShaderConstantIndex = mtxShaderConstantOffsetPerPipeline.second.begin()->second;
52
53 // Query texture's SRV descriptor offset in the descriptor range.
54 unsigned int iRootConstantValue = 0;
55 {
56 std::scoped_lock textureGuard(mtxUsedTexture.first);
57
58 const auto pDirectXTexture =
59 reinterpret_cast<DirectXResource*>(mtxUsedTexture.second->getResource());
60
61 // Get SRV.
62 const auto pSrvDescriptor = pDirectXTexture->getDescriptor(DirectXDescriptorType::SRV);
63 if (pSrvDescriptor == nullptr) [[unlikely]] {
64 Error error(std::format(
65 "shader resource \"{}\" was requested to set its root constant "
66 "index but used texture \"{}\" does not seem to have an SRV bound",
68 pDirectXTexture->getResourceName()));
69 error.showError();
70 throw std::runtime_error(error.getFullErrorMessage());
71 }
72
73 // Calculate descriptor offset. This may not be as fast as we want but this is the price we
74 // pay for having a simple approach. We could have cached the offset but we would need to keep
75 // the cached offset updated after the range resizes which seems like a complicated thing.
76 auto result = pSrvDescriptor->getOffsetFromRangeStartOnCurrentFrame();
77 if (std::holds_alternative<Error>(result)) [[unlikely]] {
78 auto error = std::get<Error>(std::move(result));
79 error.addCurrentLocationToErrorStack();
80 error.showError();
81 throw std::runtime_error(error.getFullErrorMessage());
82 }
83
84 iRootConstantValue = std::get<unsigned int>(result);
85 }
86
87 // Copy value to root constants.
88 pShaderConstantsManager->copyValueToShaderConstant(iShaderConstantIndex, iRootConstantValue);
89 }
90
102 [[nodiscard]] virtual std::optional<Error>
103 useNewTexture(std::unique_ptr<TextureHandle> pTextureToUse) override;
104
121 [[nodiscard]] virtual std::optional<Error>
122 changeUsedPipelines(const std::unordered_set<Pipeline*>& pipelinesToUse) override;
123
124 protected:
137 const std::string& sResourceName,
138 std::unique_ptr<TextureHandle> pTextureToUse,
139 std::unordered_map<DirectXPso*, size_t>&& shaderConstantOffsetPerPipeline);
140
150 [[nodiscard]] virtual std::optional<Error> onAfterAllPipelinesRefreshedResources() override;
151
152 private:
163 static std::variant<std::unique_ptr<ShaderTextureResourceBinding>, Error> create(
164 const std::string& sShaderResourceName,
165 const std::unordered_set<Pipeline*>& pipelinesToUse,
166 std::unique_ptr<TextureHandle> pTextureToUse);
167
177 static std::variant<std::shared_ptr<ContinuousDirectXDescriptorRange>, Error>
178 getSrvDescriptorRange(DirectXPso* pPipeline, const std::string& sShaderResourceName);
179
181 std::pair<std::mutex, std::unique_ptr<TextureHandle>> mtxUsedTexture;
182
184 std::pair<std::recursive_mutex, std::unordered_map<DirectXPso*, size_t>>
186
191 static constexpr bool bBindSrvToCubemapFaces = false;
192 };
193} // namespace ne
Definition: DirectXPso.h:22
Definition: DirectXResource.h:32
DirectXDescriptor * getDescriptor(DirectXDescriptorType descriptorType)
Definition: DirectXResource.cpp:182
Definition: Error.h:27
std::string getFullErrorMessage() const
Definition: Error.cpp:84
void showError() const
Definition: Error.cpp:102
Definition: HlslShaderTextureResourceBinding.h:22
void copyResourceIndexToRootConstants(PipelineShaderConstantsManager *pShaderConstantsManager, DirectXPso *pUsedPipeline)
Definition: HlslShaderTextureResourceBinding.h:35
std::pair< std::recursive_mutex, std::unordered_map< DirectXPso *, size_t > > mtxShaderConstantOffsetPerPipeline
Definition: HlslShaderTextureResourceBinding.h:185
static std::variant< std::shared_ptr< ContinuousDirectXDescriptorRange >, Error > getSrvDescriptorRange(DirectXPso *pPipeline, const std::string &sShaderResourceName)
Definition: HlslShaderTextureResourceBinding.cpp:17
virtual std::optional< Error > changeUsedPipelines(const std::unordered_set< Pipeline * > &pipelinesToUse) 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 > pTextureToUse)
Definition: HlslShaderTextureResourceBinding.cpp:76
std::pair< std::mutex, std::unique_ptr< TextureHandle > > mtxUsedTexture
Definition: HlslShaderTextureResourceBinding.h:181
virtual std::optional< Error > useNewTexture(std::unique_ptr< TextureHandle > pTextureToUse) override
Definition: HlslShaderTextureResourceBinding.cpp:186
static constexpr bool bBindSrvToCubemapFaces
Definition: HlslShaderTextureResourceBinding.h:191
virtual std::optional< Error > onAfterAllPipelinesRefreshedResources() override
Definition: HlslShaderTextureResourceBinding.cpp:166
Definition: PipelineShaderConstantsManager.hpp:14
void copyValueToShaderConstant(size_t iShaderConstantIndex, unsigned int iValueToCopy)
Definition: PipelineShaderConstantsManager.hpp:75
std::string getShaderResourceName() const
Definition: ShaderResourceBinding.cpp:11
const std::string sShaderResourceName
Definition: ShaderResourceBinding.h:82
Definition: ShaderTextureResourceBindingManager.h:27
Definition: ShaderResourceBinding.h:86