blob: 0b83683aa6d7e9606c6ddc1685ee5a1c9933eeaf [file] [log] [blame]
Geoff Lang6a1e6b92014-11-06 10:42:45 -05001//
2// Copyright 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Langda88add2014-12-01 10:22:01 -05007// FramebufferD3D.cpp: Implements the DefaultAttachmentD3D and FramebufferD3D classes.
Geoff Lang6a1e6b92014-11-06 10:42:45 -05008
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/renderer/d3d/FramebufferD3D.h"
Geoff Langb5d8f232014-12-04 15:43:01 -050010#include "libANGLE/renderer/d3d/TextureD3D.h"
Geoff Langda88add2014-12-01 10:22:01 -050011#include "libANGLE/renderer/d3d/RendererD3D.h"
Geoff Langb5d8f232014-12-04 15:43:01 -050012#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050013#include "libANGLE/renderer/RenderTarget.h"
Geoff Langb5d8f232014-12-04 15:43:01 -050014#include "libANGLE/FramebufferAttachment.h"
Geoff Lang6a1e6b92014-11-06 10:42:45 -050015
16namespace rx
17{
18
19DefaultAttachmentD3D::DefaultAttachmentD3D(RenderTarget *renderTarget)
20 : mRenderTarget(renderTarget)
21{
22 ASSERT(mRenderTarget);
23}
24
25DefaultAttachmentD3D::~DefaultAttachmentD3D()
26{
27 SafeDelete(mRenderTarget);
28}
29
30DefaultAttachmentD3D *DefaultAttachmentD3D::makeDefaultAttachmentD3D(DefaultAttachmentImpl* impl)
31{
32 ASSERT(HAS_DYNAMIC_TYPE(DefaultAttachmentD3D*, impl));
33 return static_cast<DefaultAttachmentD3D*>(impl);
34}
35
36GLsizei DefaultAttachmentD3D::getWidth() const
37{
38 return mRenderTarget->getWidth();
39}
40
41GLsizei DefaultAttachmentD3D::getHeight() const
42{
43 return mRenderTarget->getHeight();
44}
45
46GLenum DefaultAttachmentD3D::getInternalFormat() const
47{
48 return mRenderTarget->getInternalFormat();
49}
50
51GLenum DefaultAttachmentD3D::getActualFormat() const
52{
53 return mRenderTarget->getActualFormat();
54}
55
56GLsizei DefaultAttachmentD3D::getSamples() const
57{
58 return mRenderTarget->getSamples();
59}
60
61RenderTarget *DefaultAttachmentD3D::getRenderTarget() const
62{
63 return mRenderTarget;
64}
65
Geoff Langda88add2014-12-01 10:22:01 -050066
67FramebufferD3D::FramebufferD3D(RendererD3D *renderer)
Geoff Lang748f74e2014-12-01 11:25:34 -050068 : mRenderer(renderer),
69 mColorBuffers(renderer->getRendererCaps().maxColorAttachments)
Geoff Langda88add2014-12-01 10:22:01 -050070{
71 ASSERT(mRenderer != nullptr);
Geoff Lang748f74e2014-12-01 11:25:34 -050072
73 std::fill(mColorBuffers.begin(), mColorBuffers.end(), nullptr);
Geoff Langda88add2014-12-01 10:22:01 -050074}
75
76FramebufferD3D::~FramebufferD3D()
77{
78}
79
Geoff Lang9dd95802014-12-01 11:12:59 -050080void FramebufferD3D::setColorAttachment(size_t index, const gl::FramebufferAttachment *attachment)
81{
Geoff Lang748f74e2014-12-01 11:25:34 -050082 ASSERT(index < mColorBuffers.size());
83 mColorBuffers[index] = attachment;
Geoff Lang9dd95802014-12-01 11:12:59 -050084}
85
86void FramebufferD3D::setDepthttachment(const gl::FramebufferAttachment *attachment)
87{
88}
89
90void FramebufferD3D::setStencilAttachment(const gl::FramebufferAttachment *attachment)
91{
92}
93
94void FramebufferD3D::setDepthStencilAttachment(const gl::FramebufferAttachment *attachment)
95{
96}
97
98void FramebufferD3D::setDrawBuffers(size_t count, const GLenum *buffers)
99{
100}
101
102void FramebufferD3D::setReadBuffer(GLenum buffer)
103{
104}
105
Geoff Lang9ad4bda2014-12-01 11:03:09 -0500106gl::Error FramebufferD3D::invalidate(size_t, const GLenum *)
107{
108 // No-op in D3D
109 return gl::Error(GL_NO_ERROR);
110}
111
112gl::Error FramebufferD3D::invalidateSub(size_t, const GLenum *, const gl::Rectangle &)
113{
114 // No-op in D3D
115 return gl::Error(GL_NO_ERROR);
116}
117
Geoff Lang748f74e2014-12-01 11:25:34 -0500118GLenum FramebufferD3D::checkStatus() const
119{
120 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
121 for (size_t colorAttachment = 0; colorAttachment < mColorBuffers.size(); colorAttachment++)
122 {
123 const gl::FramebufferAttachment *attachment = mColorBuffers[colorAttachment];
124 if (attachment != nullptr)
125 {
126 for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++)
127 {
128 const gl::FramebufferAttachment *prevAttachment = mColorBuffers[prevColorAttachment];
129 if (prevAttachment != nullptr &&
130 (attachment->id() == prevAttachment->id() &&
131 attachment->type() == prevAttachment->type()))
132 {
133 return GL_FRAMEBUFFER_UNSUPPORTED;
134 }
135 }
136 }
137 }
138
139 return GL_FRAMEBUFFER_COMPLETE;
140}
141
Geoff Langb5d8f232014-12-04 15:43:01 -0500142gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget **outRT)
143{
144 if (attachment->type() == GL_TEXTURE)
145 {
146 gl::Texture *texture = attachment->getTexture();
147 ASSERT(texture);
148 TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
149 const gl::ImageIndex *index = attachment->getTextureImageIndex();
150 ASSERT(index);
151 return textureD3D->getRenderTarget(*index, outRT);
152 }
153 else if (attachment->type() == GL_RENDERBUFFER)
154 {
155 gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
156 ASSERT(renderbuffer);
157 RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
158 *outRT = renderbufferD3D->getRenderTarget();
159 return gl::Error(GL_NO_ERROR);
160 }
161 else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
162 {
163 const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
164 DefaultAttachmentD3D *defaultAttachmentD3D = DefaultAttachmentD3D::makeDefaultAttachmentD3D(defaultAttachment->getImplementation());
165 ASSERT(defaultAttachmentD3D);
166
167 *outRT = defaultAttachmentD3D->getRenderTarget();
168 return gl::Error(GL_NO_ERROR);
169 }
170 else
171 {
172 UNREACHABLE();
173 return gl::Error(GL_INVALID_OPERATION);
174 }
175}
176
177// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
178unsigned int GetAttachmentSerial(const gl::FramebufferAttachment *attachment)
179{
180 if (attachment->type() == GL_TEXTURE)
181 {
182 gl::Texture *texture = attachment->getTexture();
183 ASSERT(texture);
184 TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
185 const gl::ImageIndex *index = attachment->getTextureImageIndex();
186 ASSERT(index);
187 return textureD3D->getRenderTargetSerial(*index);
188 }
189 else if (attachment->type() == GL_RENDERBUFFER)
190 {
191 gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
192 ASSERT(renderbuffer);
193 RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
194 return renderbufferD3D->getRenderTargetSerial();
195 }
196 else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
197 {
198 const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
199 DefaultAttachmentD3D *defaultAttachmentD3D = DefaultAttachmentD3D::makeDefaultAttachmentD3D(defaultAttachment->getImplementation());
200 ASSERT(defaultAttachmentD3D);
201 return defaultAttachmentD3D->getRenderTarget()->getSerial();
202 }
203 else
204 {
205 UNREACHABLE();
206 return 0;
207 }
208}
209
Geoff Lang6a1e6b92014-11-06 10:42:45 -0500210}