| // |
| // 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 |