1#include "SwapChainGL20.h"
4#include "FormatsGL20.h"
5#include "GraphicsDeviceGL20.h"
7#include "Foundation/Platform/WindowData.h"
14Cogs::SwapChainGL20::SwapChainGL20(GraphicsDeviceGL20* device,
bool isPrimary)
15 : graphicsDevice(device),
16 isPrimary(isPrimary) {
19Cogs::SwapChainGL20::~SwapChainGL20() {
40 glContext = graphicsDevice->getShareContext();
42 else if (windowData && windowData->defaultContext) {
43 glContext = GLContext(windowData->defaultContext);
46 LOG_ERROR(logger,
"No share or window context .");
50 if (!glContext.create(
nullptr, winData, &graphicsDevice->getShareContext(), &settings, GLContext::Platform::GL, debugLogging)) {
51 LOG_ERROR(logger,
"Can't retrieve window's device context.");
55 glContext.makeCurrent();
59 glGenFramebuffers(1, &framebuffer);
62 graphicsDevice->getDefaultSwapChain()->glContext.makeCurrent();
68void Cogs::SwapChainGL20::destroy()
79 glContext.makeCurrent();
80 glBindFramebuffer(GL_FRAMEBUFFER, 0);
81 glDrawBuffer(GL_BACK);
85 recreateOffscreenBuffers();
101 acquire = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
103 glContext.makeCurrent();
105 glWaitSync(acquire, 0, GL_TIMEOUT_IGNORED);
106 glDeleteSync(acquire);
107 glDisable(GL_SCISSOR_TEST);
108 glViewport(0, 0, width, height);
109 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
110 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
111 glDrawBuffer(GL_BACK);
112 glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
113 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
119 glContext.swapBuffers(syncInterval, presentFlags);
123 graphicsDevice->getDefaultSwapChain()->glContext.makeCurrent();
127void Cogs::SwapChainGL20::ReleaseFence()
129 if(release) glDeleteSync(release);
130 release = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
133void Cogs::SwapChainGL20::ReleaseWait()
136 glWaitSync(release, 0, GL_TIMEOUT_IGNORED);
137 glDeleteSync(release);
147 if ((width != newWidth) || (height != newHeight) || forceIt) {
158 return graphicsDevice->getSettings().numSamples;
177 desc.height = height;
180 desc.target = Cogs::ResourceDimensions::Texture2DMS;
183 if (Cogs::HandleIsValid(depthStencil)) {
187 if (Cogs::HandleIsValid(renderTarget)) {
191 if (Cogs::HandleIsValid(textureHandle)) {
196 textureHandle = textures->
loadTexture(desc,
nullptr);
197 if (!Cogs::HandleIsValid(this->textureHandle)) {
198 LOG_ERROR(logger,
"Unable to create offscreen texture.");
203 rt_desc.
texture = textureHandle;
206 if (!Cogs::HandleIsValid(renderTarget)) {
207 LOG_ERROR(logger,
"Error creating render target.");
212 if (!Cogs::HandleIsValid(depthStencil)) {
213 LOG_ERROR(logger,
"Error creating depth stencil.");
218 GLsync acquire = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
219 glContext.makeCurrent();
220 glWaitSync(acquire, 0, GL_TIMEOUT_IGNORED);
221 glDeleteSync(acquire);
223 const TextureGL20& texture = graphicsDevice->getTextures()->textures[textureHandle];
224 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
225 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.type, texture.textureId, 0);
226 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
228 case GL_FRAMEBUFFER_COMPLETE:
230 case GL_FRAMEBUFFER_UNDEFINED: [[fallthrough]];
231 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: [[fallthrough]];
232 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: [[fallthrough]];
233 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: [[fallthrough]];
234 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: [[fallthrough]];
235 case GL_FRAMEBUFFER_UNSUPPORTED: [[fallthrough]];
236 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: [[fallthrough]];
237 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: [[fallthrough]];
239 LOG_ERROR(logger,
"Failed to create swapchain FBO, glCheckFramebufferStatus()=0x%x", status);
240 glDeleteFramebuffers(1, &framebuffer);
247 graphicsDevice->getDefaultSwapChain()->glContext.makeCurrent();
Log implementation class.
bool recreateOffscreenBuffers()
Recreates the textures and render targets used for offscreen rendering.
virtual void endFrame(uint32_t syncInterval=0, uint32_t presentFlags=PresentFlags::None) override
Finalises rendering and swaps the front and back buffers of this swap chain instance.
virtual void setSize(int newWidth, int newHeight, bool forceIt=false) override
Changes the size of this swap chain's viewport.
virtual void setFullscreen(bool enabled) override
Switch this swap chain to fullscreen or windowed depending on the parameter.
virtual void beginFrame() override
Prepares this swap chain for rendering.
virtual int getSamples() const override
Returns the number of samples this swap chain has.
bool initialize(WindowData *windowData, bool debugLogging)
Initialises this swap chain and attaches it to the window provided.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Settings for graphics device initialization.
int numSamples
Number of samples to use for back buffer MSAA.
TextureFormat colorFormat
Back buffer format.
Describes a single render target view and which resources to use from the underlying texture.
uint16_t numLayers
Number of available layers to render to.
TextureHandle texture
Texture handle.
void releaseRenderTarget(RenderTargetHandle renderTargetHandle) override
Release the render target with the given renderTargetHandle.
void releaseDepthStencilTarget(DepthStencilHandle depthStencilHandle) override
Release the depth target with the given depthStencilHandle.
RenderTargetHandle createRenderTarget(const RenderTargetViewDescription *renderTargetViews, const size_t numViews) override
Create a render target using the given view descriptions.
DepthStencilHandle createDepthStencilTarget(const RenderTargetHandle handle) override
Creates a depth/stencil target to back the render target with the given handle.
@ RenderTarget
The texture can be used as a render target and drawn into.
TextureHandle loadTexture(const TextureDescription &desc, const TextureData *data) override
Load a texture from the given description.
void releaseTexture(TextureHandle textureHandle) override
Release the texture with the given textureHandle.