blob: 07ae6b53b8194d077329a9756d04c442fc039acd [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.com0dc8a5e2012-01-18 16:29:34 +000055RenderbufferTexture::RenderbufferTexture(Texture *texture, GLenum target) : mTarget(target)
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000056{
daniel@transgaming.com0dc8a5e2012-01-18 16:29:34 +000057 mTexture.set(texture);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000058}
59
60RenderbufferTexture::~RenderbufferTexture()
61{
daniel@transgaming.com0dc8a5e2012-01-18 16:29:34 +000062 mTexture.set(NULL);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000063}
64
65IDirect3DSurface9 *RenderbufferTexture::getRenderTarget()
66{
67 return mTexture->getRenderTarget(mTarget);
68}
69
70IDirect3DSurface9 *RenderbufferTexture::getDepthStencil()
71{
72 return NULL;
73}
74
75GLsizei RenderbufferTexture::getWidth() const
76{
daniel@transgaming.comf1286442011-11-29 19:42:23 +000077 return mTexture->getWidth(0);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000078}
79
80GLsizei RenderbufferTexture::getHeight() const
81{
daniel@transgaming.comf1286442011-11-29 19:42:23 +000082 return mTexture->getHeight(0);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000083}
84
85GLenum RenderbufferTexture::getInternalFormat() const
86{
87 return mTexture->getInternalFormat();
88}
daniel@transgaming.comfbc39522011-11-11 04:10:28 +000089
90D3DFORMAT RenderbufferTexture::getD3DFormat() const
91{
92 return mTexture->getD3DFormat();
93}
94
daniel@transgaming.comd14558a2011-11-09 17:46:18 +000095GLsizei RenderbufferTexture::getSamples() const
96{
97 return 0;
98}
99
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000100unsigned int RenderbufferTexture::getSerial() const
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000101{
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000102 return mTexture->getRenderTargetSerial(mTarget);
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000103}
104
105Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
106{
107 ASSERT(instance != NULL);
108 mInstance = instance;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000109}
110
111Renderbuffer::~Renderbuffer()
112{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000113 delete mInstance;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000114}
115
116IDirect3DSurface9 *Renderbuffer::getRenderTarget()
117{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000118 return mInstance->getRenderTarget();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119}
120
121IDirect3DSurface9 *Renderbuffer::getDepthStencil()
122{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000123 return mInstance->getDepthStencil();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000124}
125
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000126GLsizei Renderbuffer::getWidth() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000127{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000128 return mInstance->getWidth();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000129}
130
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000131GLsizei Renderbuffer::getHeight() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000132{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000133 return mInstance->getHeight();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000134}
135
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000136GLenum Renderbuffer::getInternalFormat() const
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000137{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000138 return mInstance->getInternalFormat();
139}
140
141D3DFORMAT Renderbuffer::getD3DFormat() const
142{
143 return mInstance->getD3DFormat();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000144}
145
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000146GLuint Renderbuffer::getRedSize() const
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000147{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000148 return mInstance->getRedSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000149}
150
151GLuint Renderbuffer::getGreenSize() const
152{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000153 return mInstance->getGreenSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000154}
155
156GLuint Renderbuffer::getBlueSize() const
157{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000158 return mInstance->getBlueSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000159}
160
161GLuint Renderbuffer::getAlphaSize() const
162{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000163 return mInstance->getAlphaSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000164}
165
166GLuint Renderbuffer::getDepthSize() const
167{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000168 return mInstance->getDepthSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000169}
170
171GLuint Renderbuffer::getStencilSize() const
172{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000173 return mInstance->getStencilSize();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000174}
175
176GLsizei Renderbuffer::getSamples() const
177{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000178 return mInstance->getSamples();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000179}
180
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000181unsigned int Renderbuffer::getSerial() const
182{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000183 return mInstance->getSerial();
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000184}
185
186void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
187{
188 ASSERT(newStorage != NULL);
189
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000190 delete mInstance;
191 mInstance = newStorage;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000192}
193
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000194RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000195{
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000196 mWidth = 0;
197 mHeight = 0;
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000198 mInternalFormat = GL_RGBA4;
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000199 mD3DFormat = D3DFMT_A8R8G8B8;
200 mSamples = 0;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000201}
202
203RenderbufferStorage::~RenderbufferStorage()
204{
205}
206
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000207IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
208{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209 return NULL;
210}
211
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000212IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
213{
214 return NULL;
215}
216
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000217GLsizei RenderbufferStorage::getWidth() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218{
219 return mWidth;
220}
221
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000222GLsizei RenderbufferStorage::getHeight() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223{
224 return mHeight;
225}
226
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000227GLenum RenderbufferStorage::getInternalFormat() const
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000228{
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000229 return mInternalFormat;
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000230}
231
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000232D3DFORMAT RenderbufferStorage::getD3DFormat() const
233{
234 return mD3DFormat;
235}
236
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000237GLsizei RenderbufferStorage::getSamples() const
238{
239 return mSamples;
240}
241
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000242unsigned int RenderbufferStorage::getSerial() const
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000243{
daniel@transgaming.comfbc39522011-11-11 04:10:28 +0000244 return mSerial;
245}
246
247unsigned int RenderbufferStorage::issueSerial()
248{
249 return mCurrentSerial++;
250}
251
252unsigned int RenderbufferStorage::issueCubeSerials()
253{
254 unsigned int firstSerial = mCurrentSerial;
255 mCurrentSerial += 6;
256 return firstSerial;
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000257}
258
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000259Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000260{
261 if (renderTarget)
262 {
263 renderTarget->AddRef();
264
265 D3DSURFACE_DESC description;
266 renderTarget->GetDesc(&description);
267
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000268 mWidth = description.Width;
269 mHeight = description.Height;
270 mInternalFormat = dx2es::ConvertBackBufferFormat(description.Format);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000271 mD3DFormat = description.Format;
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000272 mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000273 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000274}
275
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000276Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000277{
278 IDirect3DDevice9 *device = getDevice();
279
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000280 D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000281 int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
282
283 if (supportedSamples == -1)
284 {
285 error(GL_OUT_OF_MEMORY);
286
287 return;
288 }
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000289
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000290 if (width > 0 && height > 0)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000291 {
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000292 HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000293 es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000294
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000295 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
296 {
297 error(GL_OUT_OF_MEMORY);
298
299 return;
300 }
301
302 ASSERT(SUCCEEDED(result));
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000303 }
304
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000305 mWidth = width;
306 mHeight = height;
307 mInternalFormat = format;
308 mD3DFormat = requestedFormat;
309 mSamples = supportedSamples;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000310}
311
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000312Colorbuffer::~Colorbuffer()
313{
314 if (mRenderTarget)
315 {
316 mRenderTarget->Release();
317 }
318}
319
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000320IDirect3DSurface9 *Colorbuffer::getRenderTarget()
321{
daniel@transgaming.com5e4dbb32011-11-11 04:10:18 +0000322 if (mRenderTarget)
323 {
324 mRenderTarget->AddRef();
325 }
326
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000327 return mRenderTarget;
328}
329
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000330DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000331{
332 if (depthStencil)
333 {
334 depthStencil->AddRef();
335
336 D3DSURFACE_DESC description;
337 depthStencil->GetDesc(&description);
338
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000339 mWidth = description.Width;
340 mHeight = description.Height;
341 mInternalFormat = dx2es::ConvertDepthStencilFormat(description.Format);
342 mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000343 mD3DFormat = description.Format;
344 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000345}
346
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000347DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000348{
349 IDirect3DDevice9 *device = getDevice();
350
351 mDepthStencil = NULL;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000352
353 int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples);
354
355 if (supportedSamples == -1)
356 {
357 error(GL_OUT_OF_MEMORY);
358
359 return;
360 }
361
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000362 if (width > 0 && height > 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000363 {
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000364 HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples),
365 0, FALSE, &mDepthStencil, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000366
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000367 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
368 {
369 error(GL_OUT_OF_MEMORY);
370
371 return;
372 }
373
374 ASSERT(SUCCEEDED(result));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000375 }
376
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000377 mWidth = width;
378 mHeight = height;
379 mInternalFormat = GL_DEPTH24_STENCIL8_OES;
380 mD3DFormat = D3DFMT_D24S8;
381 mSamples = supportedSamples;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000382}
383
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000384DepthStencilbuffer::~DepthStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000385{
386 if (mDepthStencil)
387 {
388 mDepthStencil->Release();
389 }
390}
391
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000392IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
393{
394 return mDepthStencil;
395}
396
397Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
398{
399 if (depthStencil)
400 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000401 mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
402 // will expect one of the valid renderbuffer formats for use in
403 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000404 }
405}
406
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000407Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000408{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000409 if (mDepthStencil)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000410 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000411 mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
412 // will expect one of the valid renderbuffer formats for use in
413 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000414 }
415}
416
417Depthbuffer::~Depthbuffer()
418{
419}
420
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000421Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
422{
423 if (depthStencil)
424 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000425 mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
426 // will expect one of the valid renderbuffer formats for use in
427 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000428 }
429}
430
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000431Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000432{
daniel@transgaming.comd14558a2011-11-09 17:46:18 +0000433 if (mDepthStencil)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000434 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000435 mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
436 // will expect one of the valid renderbuffer formats for use in
437 // glRenderbufferStorage
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000438 }
439}
440
441Stencilbuffer::~Stencilbuffer()
442{
443}
444
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000445}