Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
RenderTarget.cpp
Go to the documentation of this file.
1
2
4
7
10
12
13namespace Divide {
14namespace {
15 const char* getAttachmentName(const RTAttachmentType type) noexcept
16 {
17 switch (type)
18 {
19 case RTAttachmentType::COLOUR: return "Colour";
20 case RTAttachmentType::DEPTH: return "Depth";
21 case RTAttachmentType::DEPTH_STENCIL: return "Depth_Stencil";
22 default: break;
23 };
24
25 return "ERROR";
26 };
27};
28
30 : GraphicsResource(context, Type::RENDER_TARGET, getGUID(), _ID(descriptor._name.c_str())),
31 _descriptor(descriptor)
32{
33 if ( _descriptor._name.empty() )
34 {
36 }
37}
38
40{
41 if (att == nullptr || _descriptor._msaaSamples == 0u )
42 {
43 return false;
44 }
45
46 return att->_descriptor._autoResolve;
47}
48
50{
51 std::ranges::fill(_attachmentsUsed, false);
52 std::ranges::fill(_attachmentsAutoResolve, false);
53
54 // Avoid invalid dimensions
55 assert(getWidth() != 0 && getHeight() != 0 && "glFramebuffer error: Invalid frame buffer dimensions!");
56
57 const auto updateAttachment = [&](const RTAttachmentDescriptor& attDesc)
58 {
59 bool printWarning = false;
60
61 RTAttachment* att = nullptr;
62 switch (attDesc._type)
63 {
66 {
67 assert(attDesc._slot == RTColourAttachmentSlot::SLOT_0 );
68 printWarning = _attachments[RT_DEPTH_ATTACHMENT_IDX] != nullptr;
69 _attachments[RT_DEPTH_ATTACHMENT_IDX] = std::make_unique<RTAttachment>(*this, attDesc);
71 } break;
73 {
74 printWarning = _attachments[to_base(attDesc._slot)] != nullptr;
75 _attachments[to_base(attDesc._slot)] = std::make_unique<RTAttachment>(*this, attDesc);
76 att = _attachments[to_base(attDesc._slot)].get();
77 } break;
78 default: DIVIDE_UNEXPECTED_CALL(); break;
79 };
80
81 if (printWarning)
82 {
83 Console::d_printfn(LOCALE_STR("WARNING_REPLACING_RT_ATTACHMENT"), getGUID(), getAttachmentName(attDesc._type), to_base(attDesc._slot));
84 }
85
86 return att;
87 };
88
90 {
91 RTAttachment* att = updateAttachment(attDesc);
92
93 const string texName = Util::StringFormat("RT_{}_Att_{}_{}_{}",
94 name().c_str(),
95 getAttachmentName(attDesc._type),
96 to_base(attDesc._slot),
97 getGUID());
103
104 const bool needsMSAAResolve = autoResolveAttachment(att);
105
106 Handle<Texture> renderTexture = INVALID_HANDLE<Texture>;
107 Handle<Texture> resolveTexture = INVALID_HANDLE<Texture>;
108 const MipMappingState mipMapState = attDesc._texDescriptor._mipMappingState;
109 {
110 if ( needsMSAAResolve )
111 {
115 }
116
117 ResourceDescriptor<Texture> textureAttachment(texName + "_RENDER", attDesc._texDescriptor );
118 textureAttachment.waitForReady(true);
119
120 renderTexture = CreateResource(textureAttachment);
121
122 Get(renderTexture)->createWithData(nullptr, 0u, vec2<U16>(getWidth(), getHeight()), {});
123 }
124
125 if ( needsMSAAResolve )
126 {
128 attDesc._texDescriptor._mipMappingState = mipMapState;
129 attDesc._texDescriptor._msaaSamples = 0u;
130
131 ResourceDescriptor<Texture> textureAttachment( texName + "_RESOLVE", attDesc._texDescriptor );
132 textureAttachment.waitForReady( true );
133
134 resolveTexture = CreateResource( textureAttachment );
135
136 Get(resolveTexture)->createWithData( nullptr, 0u, vec2<U16>( getWidth(), getHeight() ), {} );
137 }
138 else
139 {
140 resolveTexture = GetResourceRef(renderTexture);
141 }
142
143 att->setTexture(renderTexture, resolveTexture);
144
145 if ( !initAttachment( att, attDesc._type, attDesc._slot ) )
146 {
148 }
149 }
150
152 {
153 Handle<Texture> renderTexture = GetResourceRef(attDesc._externalAttachment->renderTexture());
154 Handle<Texture> resolveTexture = GetResourceRef(attDesc._externalAttachment->resolvedTexture());
155
156 DIVIDE_ASSERT(Get( renderTexture )->descriptor()._msaaSamples == _descriptor._msaaSamples);
157
158 RTAttachment* att = updateAttachment(attDesc);
159 att->setTexture( renderTexture, resolveTexture );
160 if ( !initAttachment( att, attDesc._type, attDesc._slot ) )
161 {
163 }
164 }
165
166 return true;
167}
168
170{
171 return getAttachment(type, slot) != nullptr;
172}
173
175{
177}
178
180{
181 switch (type)
182 {
185 case RTAttachmentType::COLOUR: return _attachments[to_base(slot)].get();
186
187 case RTAttachmentType::COUNT: break;
188 }
189
191 return nullptr;
192}
193
195{
196 switch (type)
197 {
199 case RTAttachmentType::DEPTH_STENCIL: return _attachments[RT_DEPTH_ATTACHMENT_IDX] == nullptr ? 0u : 1;
201 {
202 U8 count = 0u;
203 for (const auto& rt : _attachments)
204 {
205 if (rt != nullptr)
206 {
207 ++count;
208 }
209 }
210
211 return count;
212 }
213 case RTAttachmentType::COUNT: break;
214 }
215
217 return 0u;
218}
219
221{
222 return getResolution().width;
223}
224
226{
227 return getResolution().height;
228}
229
231{
233}
234
235const Str<64>& RenderTarget::name() const noexcept
236{
237 return _descriptor._name;
238}
239
241{
243}
244
245bool RenderTarget::resize(const U16 width, const U16 height)
246{
247 if (_descriptor._resolution != vec2<U16>(width, height))
248 {
249 _descriptor._resolution.set(width, height);
250 return create();
251 }
252
253 return false;
254}
255
257{
259}
260
262{
263 CLAMP( newSampleCount, U8_ZERO, DisplayManager::MaxMSAASamples() );
264
265 if (_descriptor._msaaSamples != newSampleCount)
266 {
267 _descriptor._msaaSamples = newSampleCount;
268 return create();
269 }
270
271 return false;
272}
273
275{
276 if (att->_descriptor._externalAttachment == nullptr)
277 {
278 ResourcePtr<Texture> attTex = Get(att->texture());
279
280 // Do we need to resize the attachment?
281 const bool shouldResize = attTex->width() != getWidth() || attTex->height() != getHeight();
282 if (shouldResize)
283 {
284 attTex->createWithData(nullptr, 0u, vec2<U16>(getWidth(), getHeight()), {});
285 }
286
287 ResourcePtr<Texture> attRenderTex = Get( att->renderTexture() );
288 const bool updateSampleCount = attRenderTex->descriptor()._msaaSamples != _descriptor._msaaSamples;
290 {
291 attRenderTex->setSampleCount(_descriptor._msaaSamples);
292 }
293 }
294
295 att->changed(false);
298
299 return true;
300}
301
302}; //namespace Divide
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_ASSERT(...)
#define DIVIDE_UNEXPECTED_CALL()
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
FORCE_INLINE I64 getGUID() const noexcept
Definition: GUIDWrapper.h:51
void setTexture(Handle< Texture > renderTexture, Handle< Texture > resolveTexture) noexcept
Handle< Texture > texture() const
RTAttachmentDescriptor _descriptor
Definition: RTAttachment.h:128
bool usesAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
RTAttachment * getAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
U8 getSampleCount() const noexcept
bool autoResolveAttachment(RTAttachment *att) const
bool updateSampleCount(U8 newSampleCount)
Change msaa sampel count for all attachments.
bool resize(U16 width, U16 height)
Resize all attachments.
F32 & depthClearValue() noexcept
U16 getWidth() const noexcept
RenderTargetDescriptor _descriptor
Definition: RenderTarget.h:100
virtual bool initAttachment(RTAttachment *att, RTAttachmentType type, RTColourAttachmentSlot slot)
virtual bool create()
Init all attachments. Returns false if already called.
RenderTarget(GFXDevice &context, const RenderTargetDescriptor &descriptor)
bool hasAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
vec2< U16 > getResolution() const noexcept
U8 getAttachmentCount(RTAttachmentType type) const noexcept
const Str< 64 > & name() const noexcept
U16 getHeight() const noexcept
RTAttachment_uptr _attachments[RT_MAX_ATTACHMENT_COUNT]
Definition: RenderTarget.h:102
bool _attachmentsAutoResolve[RT_MAX_ATTACHMENT_COUNT]
Definition: RenderTarget.h:104
bool _attachmentsUsed[RT_MAX_ATTACHMENT_COUNT]
Definition: RenderTarget.h:103
void set(const T *v) noexcept
set the 2 components of the vector manually using a source pointer to a (large enough) array
Definition: MathVectors.h:335
Str StringFormat(const char *fmt, Args &&...args)
const char * getAttachmentName(const RTAttachmentType type) noexcept
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
static constexpr U32 RT_DEPTH_ATTACHMENT_IDX
Definition: RTAttachment.h:71
T * ResourcePtr
Definition: Resource.h:112
uint8_t U8
RTAttachmentType
This enum is used when creating render targets to define the channel that the texture will attach to.
Definition: RTAttachment.h:47
FORCE_INLINE Handle< T > GetResourceRef(const Handle< T > handle)
void AddImageUsageFlag(PropertyDescriptor< Texture > &descriptor, const ImageUsage usage) noexcept
uint16_t U16
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
RTColourAttachmentSlot
::value constexpr void CLAMP(T &n, T min, T max) noexcept
Clamps value n between min and max.
Definition: MathHelper.inl:114
void RemoveImageUsageFlag(PropertyDescriptor< Texture > &descriptor, const ImageUsage usage) noexcept
FORCE_INLINE T * Get(const Handle< T > handle)
constexpr U8 U8_ZERO
constexpr auto to_base(const Type value) -> Type
static NO_INLINE void d_printfn(const char *format, T &&... args)
static U8 MaxMSAASamples() noexcept
RTColourAttachmentSlot _slot
Definition: RTAttachment.h:67
RTAttachment * _externalAttachment
Definition: RTAttachment.h:65
ExternalRTAttachmentDescriptors _externalAttachments
Definition: RenderTarget.h:53
InternalRTAttachmentDescriptors _attachments
Definition: RenderTarget.h:52