| // | |
| // Copyright 2014 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl | |
| #include "libANGLE/renderer/d3d/RenderbufferD3D.h" | |
| #include "libANGLE/Context.h" | |
| #include "libANGLE/Image.h" | |
| #include "libANGLE/renderer/d3d/ContextD3D.h" | |
| #include "libANGLE/renderer/d3d/EGLImageD3D.h" | |
| #include "libANGLE/renderer/d3d/RenderTargetD3D.h" | |
| #include "libANGLE/renderer/d3d/RendererD3D.h" | |
| namespace rx | |
| { | |
| RenderbufferD3D::RenderbufferD3D(const gl::RenderbufferState &state, RendererD3D *renderer) | |
| : RenderbufferImpl(state), mRenderer(renderer), mRenderTarget(nullptr), mImage(nullptr) | |
| {} | |
| RenderbufferD3D::~RenderbufferD3D() | |
| { | |
| SafeDelete(mRenderTarget); | |
| mImage = nullptr; | |
| } | |
| void RenderbufferD3D::onDestroy(const gl::Context *context) | |
| { | |
| SafeDelete(mRenderTarget); | |
| } | |
| angle::Result RenderbufferD3D::setStorage(const gl::Context *context, | |
| GLenum internalformat, | |
| size_t width, | |
| size_t height) | |
| { | |
| return setStorageMultisample(context, 0, internalformat, width, height); | |
| } | |
| angle::Result RenderbufferD3D::setStorageMultisample(const gl::Context *context, | |
| size_t samples, | |
| GLenum internalformat, | |
| size_t width, | |
| size_t height) | |
| { | |
| // If the renderbuffer parameters are queried, the calling function | |
| // will expect one of the valid renderbuffer formats for use in | |
| // glRenderbufferStorage, but we should create depth and stencil buffers | |
| // as DEPTH24_STENCIL8 | |
| GLenum creationFormat = internalformat; | |
| if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8) | |
| { | |
| creationFormat = GL_DEPTH24_STENCIL8_OES; | |
| } | |
| // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create | |
| // the specified storage. | |
| // Because ES 3.0 already knows the exact number of supported samples, it would already have | |
| // been validated and generated GL_INVALID_VALUE. | |
| const gl::TextureCaps &formatCaps = mRenderer->getNativeTextureCaps().get(creationFormat); | |
| ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextD3D>(context), samples <= formatCaps.getMaxSamples()); | |
| RenderTargetD3D *newRT = nullptr; | |
| ANGLE_TRY(mRenderer->createRenderTarget(context, static_cast<int>(width), | |
| static_cast<int>(height), creationFormat, | |
| static_cast<GLsizei>(samples), &newRT)); | |
| SafeDelete(mRenderTarget); | |
| mImage = nullptr; | |
| mRenderTarget = newRT; | |
| return angle::Result::Continue; | |
| } | |
| angle::Result RenderbufferD3D::setStorageEGLImageTarget(const gl::Context *context, | |
| egl::Image *image) | |
| { | |
| mImage = GetImplAs<EGLImageD3D>(image); | |
| SafeDelete(mRenderTarget); | |
| return angle::Result::Continue; | |
| } | |
| angle::Result RenderbufferD3D::getRenderTarget(const gl::Context *context, | |
| RenderTargetD3D **outRenderTarget) | |
| { | |
| if (mImage) | |
| { | |
| return mImage->getRenderTarget(context, outRenderTarget); | |
| } | |
| else | |
| { | |
| *outRenderTarget = mRenderTarget; | |
| return angle::Result::Continue; | |
| } | |
| } | |
| angle::Result RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context, | |
| GLenum binding, | |
| const gl::ImageIndex &imageIndex, | |
| GLsizei samples, | |
| FramebufferAttachmentRenderTarget **rtOut) | |
| { | |
| return getRenderTarget(context, reinterpret_cast<RenderTargetD3D **>(rtOut)); | |
| } | |
| angle::Result RenderbufferD3D::initializeContents(const gl::Context *context, | |
| const gl::ImageIndex &imageIndex) | |
| { | |
| RenderTargetD3D *renderTarget = nullptr; | |
| ANGLE_TRY(getRenderTarget(context, &renderTarget)); | |
| return mRenderer->initRenderTarget(context, renderTarget); | |
| } | |
| } // namespace rx |