Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/renderer/backend/gl/DeviceCommandContext.cpp
Show First 20 Lines • Show All 144 Lines • ▼ Show 20 Lines | if (glUnmapBufferARB(target) == GL_TRUE) | ||||
break; | break; | ||||
// Unmap might fail on e.g. resolution switches, so just try again | // Unmap might fail on e.g. resolution switches, so just try again | ||||
// and hope it will eventually succeed | // and hope it will eventually succeed | ||||
LOGMESSAGE("glUnmapBuffer failed, trying again...\n"); | LOGMESSAGE("glUnmapBuffer failed, trying again...\n"); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* In case we don't need a framebuffer content (because of the following clear | |||||
* or overwriting by a shader) we might give a hint to a driver via | |||||
* glInvalidateFramebuffer. | |||||
*/ | |||||
void InvalidateFramebuffer( | |||||
CFramebuffer* framebuffer, const bool color, const bool depthStencil) | |||||
{ | |||||
GLsizei numberOfAttachments = 0; | |||||
GLenum attachments[8]; | |||||
const bool isBackbuffer = framebuffer->GetHandle() == 0; | |||||
if (color && (framebuffer->GetAttachmentMask() & GL_COLOR_BUFFER_BIT)) | |||||
{ | |||||
if (isBackbuffer) | |||||
#if CONFIG2_GLES | |||||
attachments[numberOfAttachments++] = GL_COLOR_EXT; | |||||
#else | |||||
attachments[numberOfAttachments++] = GL_COLOR; | |||||
#endif | |||||
else | |||||
attachments[numberOfAttachments++] = GL_COLOR_ATTACHMENT0; | |||||
} | |||||
if (depthStencil) | |||||
{ | |||||
if (isBackbuffer) | |||||
{ | |||||
if (framebuffer->GetAttachmentMask() & GL_DEPTH_BUFFER_BIT) | |||||
#if CONFIG2_GLES | |||||
attachments[numberOfAttachments++] = GL_DEPTH_EXT; | |||||
#else | |||||
attachments[numberOfAttachments++] = GL_DEPTH; | |||||
#endif | |||||
if (framebuffer->GetAttachmentMask() & GL_STENCIL_BUFFER_BIT) | |||||
#if CONFIG2_GLES | |||||
attachments[numberOfAttachments++] = GL_STENCIL_EXT; | |||||
#else | |||||
attachments[numberOfAttachments++] = GL_STENCIL; | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
if (framebuffer->GetAttachmentMask() & GL_DEPTH_BUFFER_BIT) | |||||
attachments[numberOfAttachments++] = GL_DEPTH_ATTACHMENT; | |||||
if (framebuffer->GetAttachmentMask() & GL_STENCIL_BUFFER_BIT) | |||||
attachments[numberOfAttachments++] = GL_STENCIL_ATTACHMENT; | |||||
} | |||||
} | |||||
if (numberOfAttachments > 0) | |||||
{ | |||||
#if CONFIG2_GLES | |||||
glDiscardFramebufferEXT(GL_FRAMEBUFFER_EXT, numberOfAttachments, attachments); | |||||
#else | |||||
glInvalidateFramebuffer(GL_FRAMEBUFFER_EXT, numberOfAttachments, attachments); | |||||
#endif | |||||
ogl_WarnIfError(); | |||||
} | |||||
} | |||||
} // anonymous namespace | } // anonymous namespace | ||||
// static | // static | ||||
std::unique_ptr<CDeviceCommandContext> CDeviceCommandContext::Create(CDevice* device) | std::unique_ptr<CDeviceCommandContext> CDeviceCommandContext::Create(CDevice* device) | ||||
{ | { | ||||
std::unique_ptr<CDeviceCommandContext> deviceCommandContext(new CDeviceCommandContext(device)); | std::unique_ptr<CDeviceCommandContext> deviceCommandContext(new CDeviceCommandContext(device)); | ||||
deviceCommandContext->m_Framebuffer = static_cast<CFramebuffer*>(device->GetCurrentBackbuffer()); | deviceCommandContext->m_Framebuffer = device->GetCurrentBackbuffer( | ||||
Renderer::Backend::AttachmentLoadOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentStoreOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentLoadOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentStoreOp::DONT_CARE)->As<CFramebuffer>(); | |||||
deviceCommandContext->ResetStates(); | deviceCommandContext->ResetStates(); | ||||
return deviceCommandContext; | return deviceCommandContext; | ||||
} | } | ||||
CDeviceCommandContext::CDeviceCommandContext(CDevice* device) | CDeviceCommandContext::CDeviceCommandContext(CDevice* device) | ||||
: m_Device(device) | : m_Device(device) | ||||
{ | { | ||||
glActiveTexture(GL_TEXTURE0); | glActiveTexture(GL_TEXTURE0); | ||||
▲ Show 20 Lines • Show All 310 Lines • ▼ Show 20 Lines | void CDeviceCommandContext::Flush() | ||||
BindBuffer(CBuffer::Type::INDEX, nullptr); | BindBuffer(CBuffer::Type::INDEX, nullptr); | ||||
BindBuffer(CBuffer::Type::VERTEX, nullptr); | BindBuffer(CBuffer::Type::VERTEX, nullptr); | ||||
} | } | ||||
void CDeviceCommandContext::ResetStates() | void CDeviceCommandContext::ResetStates() | ||||
{ | { | ||||
SetGraphicsPipelineStateImpl(MakeDefaultGraphicsPipelineStateDesc(), true); | SetGraphicsPipelineStateImpl(MakeDefaultGraphicsPipelineStateDesc(), true); | ||||
SetScissors(0, nullptr); | SetScissors(0, nullptr); | ||||
m_Framebuffer = static_cast<CFramebuffer*>(m_Device->GetCurrentBackbuffer()); | m_Framebuffer = m_Device->GetCurrentBackbuffer( | ||||
Renderer::Backend::AttachmentLoadOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentStoreOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentLoadOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentStoreOp::DONT_CARE)->As<CFramebuffer>(); | |||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
} | } | ||||
void CDeviceCommandContext::SetGraphicsPipelineStateImpl( | void CDeviceCommandContext::SetGraphicsPipelineStateImpl( | ||||
const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force) | const GraphicsPipelineStateDesc& pipelineStateDesc, const bool force) | ||||
{ | { | ||||
ENSURE(!m_InsidePass); | ENSURE(!m_InsidePass); | ||||
▲ Show 20 Lines • Show All 261 Lines • ▼ Show 20 Lines | glBlitFramebufferEXT( | ||||
0, 0, sourceFramebuffer->GetWidth(), sourceFramebuffer->GetHeight(), | 0, 0, sourceFramebuffer->GetWidth(), sourceFramebuffer->GetHeight(), | ||||
0, 0, sourceFramebuffer->GetWidth(), sourceFramebuffer->GetHeight(), | 0, 0, sourceFramebuffer->GetWidth(), sourceFramebuffer->GetHeight(), | ||||
(sourceFramebuffer->GetAttachmentMask() & destinationFramebuffer->GetAttachmentMask()), | (sourceFramebuffer->GetAttachmentMask() & destinationFramebuffer->GetAttachmentMask()), | ||||
GL_NEAREST); | GL_NEAREST); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
#endif | #endif | ||||
} | } | ||||
void CDeviceCommandContext::ClearFramebuffer() | |||||
{ | |||||
ClearFramebuffer(true, true, true); | |||||
} | |||||
void CDeviceCommandContext::ClearFramebuffer(const bool color, const bool depth, const bool stencil) | void CDeviceCommandContext::ClearFramebuffer(const bool color, const bool depth, const bool stencil) | ||||
{ | { | ||||
ENSURE(m_InsideFramebufferPass); | |||||
const bool needsColor = color && (m_Framebuffer->GetAttachmentMask() & GL_COLOR_BUFFER_BIT) != 0; | const bool needsColor = color && (m_Framebuffer->GetAttachmentMask() & GL_COLOR_BUFFER_BIT) != 0; | ||||
const bool needsDepth = depth && (m_Framebuffer->GetAttachmentMask() & GL_DEPTH_BUFFER_BIT) != 0; | const bool needsDepth = depth && (m_Framebuffer->GetAttachmentMask() & GL_DEPTH_BUFFER_BIT) != 0; | ||||
const bool needsStencil = stencil && (m_Framebuffer->GetAttachmentMask() & GL_STENCIL_BUFFER_BIT) != 0; | const bool needsStencil = stencil && (m_Framebuffer->GetAttachmentMask() & GL_STENCIL_BUFFER_BIT) != 0; | ||||
GLbitfield mask = 0; | GLbitfield mask = 0; | ||||
if (needsColor) | if (needsColor) | ||||
{ | { | ||||
ApplyColorMask(ColorWriteMask::RED | ColorWriteMask::GREEN | ColorWriteMask::BLUE | ColorWriteMask::ALPHA); | ApplyColorMask(ColorWriteMask::RED | ColorWriteMask::GREEN | ColorWriteMask::BLUE | ColorWriteMask::ALPHA); | ||||
glClearColor( | glClearColor( | ||||
Show All 27 Lines | |||||
{ | { | ||||
ENSURE(!m_InsideFramebufferPass); | ENSURE(!m_InsideFramebufferPass); | ||||
m_InsideFramebufferPass = true; | m_InsideFramebufferPass = true; | ||||
ENSURE(framebuffer); | ENSURE(framebuffer); | ||||
m_Framebuffer = framebuffer->As<CFramebuffer>(); | m_Framebuffer = framebuffer->As<CFramebuffer>(); | ||||
ENSURE(m_Framebuffer->GetHandle() == 0 || (m_Framebuffer->GetWidth() > 0 && m_Framebuffer->GetHeight() > 0)); | ENSURE(m_Framebuffer->GetHandle() == 0 || (m_Framebuffer->GetWidth() > 0 && m_Framebuffer->GetHeight() > 0)); | ||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
if (m_Device->UseFramebufferInvalidating()) | |||||
{ | |||||
InvalidateFramebuffer( | |||||
m_Framebuffer, | |||||
m_Framebuffer->GetColorAttachmentLoadOp() != AttachmentLoadOp::LOAD, | |||||
m_Framebuffer->GetDepthStencilAttachmentLoadOp() != AttachmentLoadOp::LOAD); | |||||
} | |||||
const bool needsClearColor = | |||||
m_Framebuffer->GetColorAttachmentLoadOp() == AttachmentLoadOp::CLEAR; | |||||
const bool needsClearDepthStencil = | |||||
m_Framebuffer->GetDepthStencilAttachmentLoadOp() == AttachmentLoadOp::CLEAR; | |||||
if (needsClearColor || needsClearDepthStencil) | |||||
{ | |||||
ClearFramebuffer( | |||||
needsClearColor, needsClearDepthStencil, needsClearDepthStencil); | |||||
} | |||||
} | } | ||||
void CDeviceCommandContext::EndFramebufferPass() | void CDeviceCommandContext::EndFramebufferPass() | ||||
{ | { | ||||
if (m_Device->UseFramebufferInvalidating()) | |||||
{ | |||||
InvalidateFramebuffer( | |||||
m_Framebuffer, | |||||
m_Framebuffer->GetColorAttachmentStoreOp() != AttachmentStoreOp::STORE, | |||||
m_Framebuffer->GetDepthStencilAttachmentStoreOp() != AttachmentStoreOp::STORE); | |||||
} | |||||
ENSURE(m_InsideFramebufferPass); | ENSURE(m_InsideFramebufferPass); | ||||
m_InsideFramebufferPass = false; | m_InsideFramebufferPass = false; | ||||
m_Framebuffer = static_cast<CFramebuffer*>(m_Device->GetCurrentBackbuffer()); | CFramebuffer* framebuffer = m_Device->GetCurrentBackbuffer( | ||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_Framebuffer->GetHandle()); | Renderer::Backend::AttachmentLoadOp::DONT_CARE, | ||||
Renderer::Backend::AttachmentStoreOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentLoadOp::DONT_CARE, | |||||
Renderer::Backend::AttachmentStoreOp::DONT_CARE)->As<CFramebuffer>(); | |||||
if (framebuffer->GetHandle() != m_Framebuffer->GetHandle()) | |||||
{ | |||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer->GetHandle()); | |||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
} | } | ||||
m_Framebuffer = framebuffer; | |||||
} | |||||
void CDeviceCommandContext::ReadbackFramebufferSync( | void CDeviceCommandContext::ReadbackFramebufferSync( | ||||
const uint32_t x, const uint32_t y, const uint32_t width, const uint32_t height, | const uint32_t x, const uint32_t y, const uint32_t width, const uint32_t height, | ||||
void* data) | void* data) | ||||
{ | { | ||||
ENSURE(m_Framebuffer); | ENSURE(m_Framebuffer); | ||||
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); | glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); | ||||
ogl_WarnIfError(); | ogl_WarnIfError(); | ||||
▲ Show 20 Lines • Show All 382 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator