21 , _debugMessage((
"Render Target: [ " + name() +
" ]").c_str())
23 gl46core::glCreateFramebuffers( 1, &_framebufferHandle );
25 DIVIDE_ASSERT( (_framebufferHandle != 0 && _framebufferHandle !=
GL_NULL_HANDLE),
"glFramebuffer error: Tried to bind an invalid framebuffer!" );
30 gl46core::glObjectLabel( gl46core::GL_FRAMEBUFFER,
33 (
name() +
"_RENDER").c_str());
67 gl46core::glGenerateTextureMipmap(
static_cast<glTexture*
>(
Get(att->resolvedTexture()))->textureHandle() );
79 att->binding( binding );
89 const RTAttachment_uptr& attachment =
_attachments[ attachmentIdx ];
91 if ( tex == INVALID_HANDLE<Texture> )
98 if ( texPtr->depth() == 1u )
103 layeredRendering =
true;
110 ._levelOffset = levelOffset,
111 ._layeredRendering = layeredRendering,
118 const auto binding =
static_cast<gl46core::GLenum
>(attachment->binding());
122 gl46core::glNamedFramebufferTexture( _framebufferHandle, binding, 0u, 0u );
130 DIVIDE_ASSERT( bState._layer._layer < texPtr->depth() && bState._levelOffset < texPtr->mipCount());
134 const gl46core::GLuint handle =
static_cast<glTexture*
>(texPtr)->textureHandle();
135 if ( bState._layer._layer == 0u && bState._layer._cubeFace == 0u && layeredRendering )
137 gl46core::glNamedFramebufferTexture( _framebufferHandle, binding, handle, bState._levelOffset);
145 gl46core::glNamedFramebufferTextureLayer( _framebufferHandle, binding, handle, bState._levelOffset, bState._layer._cubeFace + (bState._layer._layer * 6u) );
148 gl46core::glNamedFramebufferTextureLayer(
_framebufferResolveHandle, binding,
static_cast<glTexture*
>(resolvedTexPtr)->textureHandle(), bState._levelOffset, bState._layer._cubeFace + (bState._layer._layer * 6u) );
153 assert(bState._layer._cubeFace == 0u);
154 gl46core::glNamedFramebufferTextureLayer( _framebufferHandle, binding, handle, bState._levelOffset, bState._layer._layer );
157 gl46core::glNamedFramebufferTextureLayer(
_framebufferResolveHandle, binding,
static_cast<glTexture*
>(resolvedTexPtr)->textureHandle(), bState._levelOffset, bState._layer._layer );
177 bool needsAutoResolve =
false;
182 needsAutoResolve =
true;
192 gl46core::glObjectLabel( gl46core::GL_FRAMEBUFFER,
195 (
name() +
"_RESOLVE").c_str() );
228 if ( source ==
nullptr || !
IsValid(params) )
238 gl46core::GLuint inputHandle = input->_framebufferHandle;
251 const auto prepareAttachments = [](
glFramebuffer* fbo,
const U16 attIndex,
const U16 layer,
const U16 mip )
270 bool readBufferDirty =
false;
284 const gl46core::GLenum readBuffer =
static_cast<gl46core::GLenum
>(inAtt->binding());
285 const gl46core::GLenum writeBuffer =
static_cast<gl46core::GLenum
>(outAtt->binding());
296 gl46core::glNamedFramebufferReadBuffer( inputHandle, readBuffer );
297 readBufferDirty =
true;
304 gl46core::glNamedFramebufferDrawBuffers( output->_framebufferHandle,
310 bool blitted =
false, inputDirty =
false, outputDirty =
false;;
313 if (
IsCubeTexture(
Get(inAtt->resolvedTexture())->descriptor()._texType ) )
320 for (
U8 layer = 0u; layer < layerCount; ++layer )
324 for (
U8 mip = 0u; mip <
entry._mipCount; ++mip )
331 if ( prepareAttachments( input,
entry._input._index,
entry._input._layerOffset + layer,
entry._input._mipOffset + mip ) )
338 if ( prepareAttachments( output,
entry._output._index,
entry._output._layerOffset + layer,
entry._output._mipOffset + mip ) )
344 gl46core::glBlitNamedFramebuffer( inputHandle,
345 output->_framebufferHandle,
350 isColourBlit ? gl46core::GL_COLOR_BUFFER_BIT : gl46core::GL_DEPTH_BUFFER_BIT,
351 gl46core::GL_NEAREST );
377 if ( readBufferDirty )
379 gl46core::glNamedFramebufferReadBuffer( inputHandle, gl46core::GL_NONE );
408 gl46core::GLenum temp = gl46core::GL_NONE;
412 temp = gl46core::GL_NONE;
476 clear( clearPolicy );
511 const gl46core::GLenum rwBuffer =
static_cast<gl46core::GLenum
>(
_attachments[i]->binding());
512 gl46core::glNamedFramebufferReadBuffer( _framebufferHandle, rwBuffer );
515 gl46core::glBlitNamedFramebuffer( _framebufferHandle,
521 gl46core::GL_COLOR_BUFFER_BIT,
522 gl46core::GL_NEAREST );
530 gl46core::glBlitNamedFramebuffer( _framebufferHandle,
536 gl46core::GL_DEPTH_BUFFER_BIT,
537 gl46core::GL_NEAREST );
541 gl46core::glNamedFramebufferReadBuffer( _framebufferHandle, gl46core::GL_NONE );
549 if ( attachment ==
nullptr )
557 gl46core::glGenerateTextureMipmap(
static_cast<glTexture*
>(
Get(texture))->textureHandle() );
574 DIVIDE_ASSERT( att !=
nullptr,
"glFramebuffer::error: Invalid clear target specified!" );
576 const U32 binding = att->binding();
577 if (
static_cast<gl46core::GLenum
>(binding) != gl46core::GL_NONE )
579 const gl46core::GLint buffer =
static_cast<gl46core::GLint
>(binding -
static_cast<gl46core::GLint
>(gl46core::GL_COLOR_ATTACHMENT0));
580 const FColour4& colour = descriptor[i]._colour;
582 const auto& descriptor =
Get( att->renderTexture() )->descriptor();
585 gl46core::glClearNamedFramebufferfv( _framebufferHandle, gl46core::GL_COLOR, buffer, colour.
_v );
589 switch ( descriptor._dataType )
594 gl46core::glClearNamedFramebufferfv( _framebufferHandle, gl46core::GL_COLOR, buffer, colour.
_v );
608 gl46core::glClearNamedFramebufferiv( _framebufferHandle, gl46core::GL_COLOR, buffer, clearColour._v );
619 gl46core::glClearNamedFramebufferuiv( _framebufferHandle, gl46core::GL_COLOR, buffer, clearColour._v );
636 gl46core::glClearNamedFramebufferfi( _framebufferHandle, gl46core::GL_DEPTH_STENCIL, 0, clearColour.
r,
to_I32( clearColour.
g) );
640 gl46core::glClearNamedFramebufferfv( _framebufferHandle, gl46core::GL_DEPTH, 0, &clearColour.
r );
668 bool changedMip =
false;
669 bool needsAttachmentDisabled =
false;
677 if ( changedMip && needsAttachmentDisabled )
713 const gl46core::GLenum status = gl46core::glCheckNamedFramebufferStatus( handle, gl46core::GL_FRAMEBUFFER );
714 if ( status == gl46core::GL_FRAMEBUFFER_COMPLETE )
721 case gl46core::GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
725 case gl46core::GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
729 case gl46core::GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
733 case gl46core::GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
737 case gl46core::GL_FRAMEBUFFER_UNSUPPORTED:
741 case gl46core::GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
745 case gl46core::GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
749 case gl::GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
753 case gl::GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
#define PROFILE_SCOPE_AUTO(CATEGORY)
#define PROFILE_TAG(NAME,...)
#define PROFILE_SCOPE(NAME, CATEGORY)
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
bool setViewport(const Rect< I32 > &viewport)
Returns true if the viewport was changed.
static const DeviceInformation & GetDeviceInformation() noexcept
void registerDrawCall() noexcept
static GLStateTracker & GetStateTracker() noexcept
static bool DeleteFramebuffers(gl46core::GLuint count, gl46core::GLuint *framebuffers)
RTAttachmentDescriptor _descriptor
bool usesAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
RTAttachment * getAttachment(RTAttachmentType type, RTColourAttachmentSlot slot=RTColourAttachmentSlot::SLOT_0) const
U16 getWidth() const noexcept
RenderTargetDescriptor _descriptor
virtual bool initAttachment(RTAttachment *att, RTAttachmentType type, RTColourAttachmentSlot slot)
virtual bool create()
Init all attachments. Returns false if already called.
U8 getAttachmentCount(RTAttachmentType type) const noexcept
const Str< 64 > & name() const noexcept
U16 getHeight() const noexcept
RTAttachment_uptr _attachments[RT_MAX_ATTACHMENT_COUNT]
bool _attachmentsAutoResolve[RT_MAX_ATTACHMENT_COUNT]
bool _attachmentsUsed[RT_MAX_ATTACHMENT_COUNT]
bool initAttachment(RTAttachment *att, RTAttachmentType type, RTColourAttachmentSlot slot) override
RTDrawDescriptor _previousPolicy
void blitFrom(RenderTarget *source, const RTBlitParams ¶ms)
void begin(const RTDrawDescriptor &drawPolicy, const RTClearDescriptor &clearPolicy)
eastl::fixed_vector< BindingState, 8+2, true > _attachmentState
~glFramebuffer() override
gl46core::GLuint _framebufferResolveHandle
glFramebuffer(GFXDevice &context, const RenderTargetDescriptor &descriptor)
bool setMipLevelInternal(U8 attachmentIdx, U16 writeLevel)
void end(const RTTransitionMask &mask)
void prepareBuffers(const RTDrawDescriptor &drawPolicy)
gl46core::GLenum _activeReadBuffer
bool create() override
Bake in all settings and attachments to Prepare it for rendering.
void clear(const RTClearDescriptor &descriptor)
static void QueueMipMapsRecomputation(const RTAttachment_uptr &attachment)
void setMipLevel(U16 writeLevel)
bool toggleAttachment(U8 attachmentIdx, AttachmentState state, U16 levelOffset, DrawLayerEntry layerOffset, bool layeredRendering)
std::array< DrawLayerEntry, RT_MAX_ATTACHMENT_COUNT > _previousDrawLayers
struct Divide::glFramebuffer::ColourBufferState _colourBuffers
void resolve(const RTTransitionMask &mask)
bool checkStatusInternal(gl46core::GLuint handle)
constexpr bool IS_DEBUG_BUILD
constexpr bool ENABLE_GPU_VALIDATION
Error callbacks, validations, buffer checks, etc. are controlled by this flag. Heavy performance impa...
constexpr Optick::Category::Type Graphics
Handle console commands that start with a forward slash.
constexpr U8 FLOAT_TO_CHAR_UNORM(F32_NORM value) noexcept
Returns round(value * 255)
constexpr U8 INVALID_INDEX
eastl::fixed_vector< RTBlitEntry, MAX_BLIT_ENTRIES, false > RTBlitParams
constexpr I8 FLOAT_TO_CHAR_SNORM(F32_SNORM value) noexcept
Returns clamped value * 128.
constexpr U32 to_U32(const T value)
static constexpr U32 RT_DEPTH_ATTACHMENT_IDX
bool IsNormalizedTexture(GFXImagePacking packing) noexcept
bool IsCubeTexture(TextureType texType) noexcept
RTAttachmentType
This enum is used when creating render targets to define the channel that the texture will attach to.
bool IsValid(const RTBlitParams ¶ms) noexcept
constexpr gl46core::GLuint GL_NULL_HANDLE
Invalid object value. Used to compare handles and determine if they were properly created.
static constexpr U8 RT_MAX_ATTACHMENT_COUNT
std::array< RTClearEntry, RT_MAX_ATTACHMENT_COUNT > RTClearDescriptor
bool[RT_MAX_ATTACHMENT_COUNT] RTTransitionMask
constexpr I32 to_I32(const T value)
FORCE_INLINE T * Get(const Handle< T > handle)
Project const SceneEntry & entry
bool SupportsZOffsetTexture(TextureType texType) noexcept
constexpr auto to_base(const Type value) -> Type
static NO_INLINE void errorfn(const char *format, T &&... args)
U8 _cubeFace
Ignored for non cube textures.
bool setDepthWrite(bool state)
RTAttachment * _externalAttachment
DrawLayerEntry _writeLayers[RT_MAX_ATTACHMENT_COUNT]
bool _layeredRendering
Set to true to bind all image layers to the render target (e.g. for Geometry Shader layered rendering...
AttachmentState _attState
std::array< gl46core::GLenum, to_base(RTColourAttachmentSlot::COUNT)> _glSlot