blob: a39c4ad7150d9892472a3029d9319bf638265c82 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 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
7// Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes
8// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
9// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
10
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000011#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000012
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013#include "libGLESv2/main.h"
enne@chromium.org0fa74632010-09-21 16:18:52 +000014#include "libGLESv2/Texture.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000015#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
17namespace gl
18{
daniel@transgaming.comfbc39522011-11-11 04:10:28 +000019unsigned int RenderbufferStorage::mCurrentSerial = 1;
daniel@transgaming.com092bd482010-05-12 03:39:36 +000020
daniel@transgaming.comfbc39522011-11-11 04:10:28 +000021RenderbufferInterface::RenderbufferInterface()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000023}
24
25GLuint RenderbufferInterface::getRedSize() const
26{
27 return dx2es::GetRedSize(getD3DFormat());
28}
29
30GLuint RenderbufferInterface::getGreenSize() const
31{
32 return dx2es::GetGreenSize(getD3DFormat());
33}
34
35GLuint RenderbufferInterface::getBlueSize() const
36{
37 return dx2es::GetBlueSize(getD3DFormat());
38}
39
40GLuint RenderbufferInterface::getAlphaSize() const
41{
42 return dx2es::GetAlphaSize(getD3DFormat());
43}
44
45GLuint RenderbufferInterface::getDepthSize() const
46{
47 return dx2es::GetDepthSize(getD3DFormat());
48}
49
50GLuint RenderbufferInterface::getStencilSize() const
51{
52 return dx2es::GetStencilSize(getD3DFormat());
53}
54
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000055RenderbufferTexture::RenderbufferTexture(Texture *texture, GLenum target) : mTexture(texture), mTarget(target)
56{
57}
58
59RenderbufferTexture::~RenderbufferTexture()
60{
61}
62
63IDirect3DSurface9 *RenderbufferTexture::getRenderTarget()
64{
65 return mTexture->getRenderTarget(mTarget);
66}
67
68IDirect3DSurface9 *RenderbufferTexture::getDepthStencil()
69{
70 return NULL;
71}
72
73GLsizei RenderbufferTexture::getWidth() const
74{
75 return mTexture->getWidth();
76}
77
78GLsizei RenderbufferTexture::getHeight() const
79{
80 return mTexture->getHeight();
81}
82
83GLenum RenderbufferTexture::getInternalFormat() const
84{
85 return mTexture->getInternalFormat();
86}
daniel@transgaming.comfbc39522011-11-11 04:10:28 +000087
88D3DFORMAT RenderbufferTexture::getD3DFormat() const
89{
90 return mTexture->getD3DFormat();
91}
92
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000093GLsizei RenderbufferTexture::getSamples() const
94{
95 return 0;
96}
97
daniel@transgaming.comfbc39522011-11-11 04:10:28 +000098unsigned int RenderbufferTexture::getSerial() const
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000099{
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000100 return mTexture->getRenderTargetSerial(mTarget);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000101}
102
103Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
104{
105 ASSERT(instance != NULL);
106 mInstance = instance;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107}
108
109Renderbuffer::~Renderbuffer()
110{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000111 delete mInstance;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000112}
113
114IDirect3DSurface9 *Renderbuffer::getRenderTarget()
115{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000116 return mInstance->getRenderTarget();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000117}
118
119IDirect3DSurface9 *Renderbuffer::getDepthStencil()
120{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000121 return mInstance->getDepthStencil();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000122}
123
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000124GLsizei Renderbuffer::getWidth() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000125{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000126 return mInstance->getWidth();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000127}
128
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000129GLsizei Renderbuffer::getHeight() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000130{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000131 return mInstance->getHeight();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000132}
133
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000134GLenum Renderbuffer::getInternalFormat() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000135{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000136 return mInstance->getInternalFormat();
137}
138
139D3DFORMAT Renderbuffer::getD3DFormat() const
140{
141 return mInstance->getD3DFormat();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000142}
143
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000144GLuint Renderbuffer::getRedSize() const
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000145{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000146 return mInstance->getRedSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000147}
148
149GLuint Renderbuffer::getGreenSize() const
150{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000151 return mInstance->getGreenSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000152}
153
154GLuint Renderbuffer::getBlueSize() const
155{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000156 return mInstance->getBlueSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000157}
158
159GLuint Renderbuffer::getAlphaSize() const
160{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000161 return mInstance->getAlphaSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000162}
163
164GLuint Renderbuffer::getDepthSize() const
165{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000166 return mInstance->getDepthSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000167}
168
169GLuint Renderbuffer::getStencilSize() const
170{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000171 return mInstance->getStencilSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000172}
173
174GLsizei Renderbuffer::getSamples() const
175{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000176 return mInstance->getSamples();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000177}
178
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000179unsigned int Renderbuffer::getSerial() const
180{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000181 return mInstance->getSerial();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000182}
183
184void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
185{
186 ASSERT(newStorage != NULL);
187
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000188 delete mInstance;
189 mInstance = newStorage;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000190}
191
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000192RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000193{
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000194 mWidth = 0;
195 mHeight = 0;
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000196 mInternalFormat = GL_RGBA4;
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000197 mD3DFormat = D3DFMT_A8R8G8B8;
198 mSamples = 0;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000199}
200
201RenderbufferStorage::~RenderbufferStorage()
202{
203}
204
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000205IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
206{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000207 return NULL;
208}
209
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000210IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
211{
212 return NULL;
213}
214
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000215GLsizei RenderbufferStorage::getWidth() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000216{
217 return mWidth;
218}
219
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000220GLsizei RenderbufferStorage::getHeight() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000221{
222 return mHeight;
223}
224
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000225GLenum RenderbufferStorage::getInternalFormat() const
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000226{
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000227 return mInternalFormat;
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000228}
229
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000230D3DFORMAT RenderbufferStorage::getD3DFormat() const
231{
232 return mD3DFormat;
233}
234
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000235GLsizei RenderbufferStorage::getSamples() const
236{
237 return mSamples;
238}
239
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000240unsigned int RenderbufferStorage::getSerial() const
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000241{
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000242 return mSerial;
243}
244
245unsigned int RenderbufferStorage::issueSerial()
246{
247 return mCurrentSerial++;
248}
249
250unsigned int RenderbufferStorage::issueCubeSerials()
251{
252 unsigned int firstSerial = mCurrentSerial;
253 mCurrentSerial += 6;
254 return firstSerial;
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000255}
256
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000257Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000258{
259 if (renderTarget)
260 {
261 renderTarget->AddRef();
262
263 D3DSURFACE_DESC description;
264 renderTarget->GetDesc(&description);
265
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000266 mWidth = description.Width;
267 mHeight = description.Height;
268 mInternalFormat = dx2es::ConvertBackBufferFormat(description.Format);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000269 mD3DFormat = description.Format;
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000270 mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000271 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000272}
273
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000274Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000275{
276 IDirect3DDevice9 *device = getDevice();
277
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000278 D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000279 int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
280
281 if (supportedSamples == -1)
282 {
283 error(GL_OUT_OF_MEMORY);
284
285 return;
286 }
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000287
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000288 if (width > 0 && height > 0)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000289 {
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000290 HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000291 es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000292
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000293 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
294 {
295 error(GL_OUT_OF_MEMORY);
296
297 return;
298 }
299
300 ASSERT(SUCCEEDED(result));
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000301 }
302
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000303 mWidth = width;
304 mHeight = height;
305 mInternalFormat = format;
306 mD3DFormat = requestedFormat;
307 mSamples = supportedSamples;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000308}
309
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000310Colorbuffer::~Colorbuffer()
311{
312 if (mRenderTarget)
313 {
314 mRenderTarget->Release();
315 }
316}
317
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000318IDirect3DSurface9 *Colorbuffer::getRenderTarget()
319{
daniel@transgaming.com5e4dbb32011-11-11 04:10:18 +0000320 if (mRenderTarget)
321 {
322 mRenderTarget->AddRef();
323 }
324
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000325 return mRenderTarget;
326}
327
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000328DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000329{
330 if (depthStencil)
331 {
332 depthStencil->AddRef();
333
334 D3DSURFACE_DESC description;
335 depthStencil->GetDesc(&description);
336
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000337 mWidth = description.Width;
338 mHeight = description.Height;
339 mInternalFormat = dx2es::ConvertDepthStencilFormat(description.Format);
340 mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000341 mD3DFormat = description.Format;
342 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000343}
344
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000345DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000346{
347 IDirect3DDevice9 *device = getDevice();
348
349 mDepthStencil = NULL;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000350
351 int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples);
352
353 if (supportedSamples == -1)
354 {
355 error(GL_OUT_OF_MEMORY);
356
357 return;
358 }
359
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000360 if (width > 0 && height > 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000361 {
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000362 HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples),
363 0, FALSE, &mDepthStencil, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000364
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000365 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
366 {
367 error(GL_OUT_OF_MEMORY);
368
369 return;
370 }
371
372 ASSERT(SUCCEEDED(result));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000373 }
374
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000375 mWidth = width;
376 mHeight = height;
377 mInternalFormat = GL_DEPTH24_STENCIL8_OES;
378 mD3DFormat = D3DFMT_D24S8;
379 mSamples = supportedSamples;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000380}
381
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000382DepthStencilbuffer::~DepthStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000383{
384 if (mDepthStencil)
385 {
386 mDepthStencil->Release();
387 }
388}
389
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000390IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
391{
392 return mDepthStencil;
393}
394
395Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
396{
397 if (depthStencil)
398 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000399 mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
400 // will expect one of the valid renderbuffer formats for use in
401 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000402 }
403}
404
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000405Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000406{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000407 if (mDepthStencil)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000408 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000409 mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
410 // will expect one of the valid renderbuffer formats for use in
411 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000412 }
413}
414
415Depthbuffer::~Depthbuffer()
416{
417}
418
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000419Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
420{
421 if (depthStencil)
422 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000423 mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
424 // will expect one of the valid renderbuffer formats for use in
425 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000426 }
427}
428
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000429Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000430{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000431 if (mDepthStencil)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000432 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000433 mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
434 // will expect one of the valid renderbuffer formats for use in
435 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000436 }
437}
438
439Stencilbuffer::~Stencilbuffer()
440{
441}
442
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000443}