blob: a2b8e978cdc74c9ac99a9632f90aa555c203911b [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
Nicolas Capens264f1522015-01-09 17:21:17 -05002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
Nicolas Capens264f1522015-01-09 17:21:17 -05006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
Nicolas Capens264f1522015-01-09 17:21:17 -05008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Nicolas Capens264f1522015-01-09 17:21:17 -050014
15// Renderbuffer.cpp: the Renderbuffer class and its derived classes
16// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
Nicolas Capensa9b49372015-01-30 00:33:26 -050017// objects and related functionality.
Nicolas Capens264f1522015-01-09 17:21:17 -050018
19#include "Renderbuffer.h"
20
21#include "main.h"
22#include "Texture.h"
23#include "utilities.h"
24
Nicolas Capensf4486fd2015-01-22 11:10:37 -050025namespace gl
Nicolas Capens264f1522015-01-09 17:21:17 -050026{
27RenderbufferInterface::RenderbufferInterface()
28{
29}
30
31// The default case for classes inherited from RenderbufferInterface is not to
32// need to do anything upon the reference count to the parent Renderbuffer incrementing
Nicolas Capens0bac2852016-05-07 06:09:58 -040033// or decrementing.
Nicolas Capens264f1522015-01-09 17:21:17 -050034void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
35{
36}
37
38void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
39{
40}
41
42GLuint RenderbufferInterface::getRedSize() const
43{
44 return sw2es::GetRedSize(getInternalFormat());
45}
46
47GLuint RenderbufferInterface::getGreenSize() const
48{
49 return sw2es::GetGreenSize(getInternalFormat());
50}
51
52GLuint RenderbufferInterface::getBlueSize() const
53{
54 return sw2es::GetBlueSize(getInternalFormat());
55}
56
57GLuint RenderbufferInterface::getAlphaSize() const
58{
59 return sw2es::GetAlphaSize(getInternalFormat());
60}
61
62GLuint RenderbufferInterface::getDepthSize() const
63{
64 return sw2es::GetDepthSize(getInternalFormat());
65}
66
67GLuint RenderbufferInterface::getStencilSize() const
68{
69 return sw2es::GetStencilSize(getInternalFormat());
70}
71
72///// RenderbufferTexture2D Implementation ////////
73
74RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
75{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -050076 mTexture2D = texture;
Nicolas Capens264f1522015-01-09 17:21:17 -050077}
78
79RenderbufferTexture2D::~RenderbufferTexture2D()
80{
Nicolas Capens0bac2852016-05-07 06:09:58 -040081 mTexture2D = nullptr;
Nicolas Capens264f1522015-01-09 17:21:17 -050082}
83
84// Textures need to maintain their own reference count for references via
85// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
86void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
87{
Nicolas Capens0bac2852016-05-07 06:09:58 -040088 mTexture2D->addProxyRef(proxy);
Nicolas Capens264f1522015-01-09 17:21:17 -050089}
90
91void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
92{
Nicolas Capens0bac2852016-05-07 06:09:58 -040093 mTexture2D->releaseProxy(proxy);
Nicolas Capens264f1522015-01-09 17:21:17 -050094}
95
Nicolas Capensa9b49372015-01-30 00:33:26 -050096// Increments refcount on surface.
97// caller must release() the returned surface
98Image *RenderbufferTexture2D::getRenderTarget()
Nicolas Capens264f1522015-01-09 17:21:17 -050099{
100 return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
101}
102
Nicolas Capens264f1522015-01-09 17:21:17 -0500103GLsizei RenderbufferTexture2D::getWidth() const
104{
105 return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
106}
107
108GLsizei RenderbufferTexture2D::getHeight() const
109{
110 return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
111}
112
113GLenum RenderbufferTexture2D::getFormat() const
114{
115 return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
116}
117
118sw::Format RenderbufferTexture2D::getInternalFormat() const
119{
120 return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
121}
122
123GLsizei RenderbufferTexture2D::getSamples() const
124{
125 return 0;
126}
127
128///// RenderbufferTextureCubeMap Implementation ////////
129
130RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
131{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500132 mTextureCubeMap = texture;
Nicolas Capens264f1522015-01-09 17:21:17 -0500133}
134
135RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
136{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400137 mTextureCubeMap = nullptr;
Nicolas Capens264f1522015-01-09 17:21:17 -0500138}
139
140// Textures need to maintain their own reference count for references via
141// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
142void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
143{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400144 mTextureCubeMap->addProxyRef(proxy);
Nicolas Capens264f1522015-01-09 17:21:17 -0500145}
146
147void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
148{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400149 mTextureCubeMap->releaseProxy(proxy);
Nicolas Capens264f1522015-01-09 17:21:17 -0500150}
151
Nicolas Capensa9b49372015-01-30 00:33:26 -0500152// Increments refcount on surface.
153// caller must release() the returned surface
Nicolas Capens264f1522015-01-09 17:21:17 -0500154Image *RenderbufferTextureCubeMap::getRenderTarget()
155{
156 return mTextureCubeMap->getRenderTarget(mTarget, 0);
157}
158
Nicolas Capens264f1522015-01-09 17:21:17 -0500159GLsizei RenderbufferTextureCubeMap::getWidth() const
160{
161 return mTextureCubeMap->getWidth(mTarget, 0);
162}
163
164GLsizei RenderbufferTextureCubeMap::getHeight() const
165{
166 return mTextureCubeMap->getHeight(mTarget, 0);
167}
168
169GLenum RenderbufferTextureCubeMap::getFormat() const
170{
171 return mTextureCubeMap->getFormat(mTarget, 0);
172}
173
174sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
175{
176 return mTextureCubeMap->getInternalFormat(mTarget, 0);
177}
178
179GLsizei RenderbufferTextureCubeMap::getSamples() const
180{
181 return 0;
182}
183
184////// Renderbuffer Implementation //////
185
Nicolas Capense826ef02015-04-02 14:43:13 -0400186Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500187{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400188 ASSERT(instance);
Nicolas Capens264f1522015-01-09 17:21:17 -0500189 mInstance = instance;
190}
191
192Renderbuffer::~Renderbuffer()
193{
194 delete mInstance;
195}
196
197// The RenderbufferInterface contained in this Renderbuffer may need to maintain
198// its own reference count, so we pass it on here.
199void Renderbuffer::addRef()
200{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400201 mInstance->addProxyRef(this);
Nicolas Capens264f1522015-01-09 17:21:17 -0500202
Nicolas Capens0bac2852016-05-07 06:09:58 -0400203 Object::addRef();
Nicolas Capens264f1522015-01-09 17:21:17 -0500204}
205
206void Renderbuffer::release()
207{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400208 mInstance->releaseProxy(this);
Nicolas Capens264f1522015-01-09 17:21:17 -0500209
Nicolas Capens0bac2852016-05-07 06:09:58 -0400210 Object::release();
Nicolas Capens264f1522015-01-09 17:21:17 -0500211}
212
Nicolas Capensa9b49372015-01-30 00:33:26 -0500213// Increments refcount on surface.
214// caller must Release() the returned surface
215Image *Renderbuffer::getRenderTarget()
Nicolas Capens264f1522015-01-09 17:21:17 -0500216{
217 return mInstance->getRenderTarget();
218}
219
Nicolas Capens264f1522015-01-09 17:21:17 -0500220GLsizei Renderbuffer::getWidth() const
221{
222 return mInstance->getWidth();
223}
224
225GLsizei Renderbuffer::getHeight() const
226{
227 return mInstance->getHeight();
228}
229
230GLenum Renderbuffer::getFormat() const
231{
232 return mInstance->getFormat();
233}
234
235sw::Format Renderbuffer::getInternalFormat() const
236{
237 return mInstance->getInternalFormat();
238}
239
240GLuint Renderbuffer::getRedSize() const
241{
242 return mInstance->getRedSize();
243}
244
245GLuint Renderbuffer::getGreenSize() const
246{
247 return mInstance->getGreenSize();
248}
249
250GLuint Renderbuffer::getBlueSize() const
251{
252 return mInstance->getBlueSize();
253}
254
255GLuint Renderbuffer::getAlphaSize() const
256{
257 return mInstance->getAlphaSize();
258}
259
260GLuint Renderbuffer::getDepthSize() const
261{
262 return mInstance->getDepthSize();
263}
264
265GLuint Renderbuffer::getStencilSize() const
266{
267 return mInstance->getStencilSize();
268}
269
270GLsizei Renderbuffer::getSamples() const
271{
272 return mInstance->getSamples();
273}
274
275void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
276{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400277 ASSERT(newStorage);
Nicolas Capens264f1522015-01-09 17:21:17 -0500278
279 delete mInstance;
280 mInstance = newStorage;
281}
282
283RenderbufferStorage::RenderbufferStorage()
284{
285 mWidth = 0;
286 mHeight = 0;
287 format = GL_RGBA4;
288 internalFormat = sw::FORMAT_A8R8G8B8;
289 mSamples = 0;
290}
291
292RenderbufferStorage::~RenderbufferStorage()
293{
294}
295
Nicolas Capensa9b49372015-01-30 00:33:26 -0500296// Increments refcount on surface.
297// caller must Release() the returned surface
298Image *RenderbufferStorage::getRenderTarget()
299{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400300 return nullptr;
Nicolas Capensa9b49372015-01-30 00:33:26 -0500301}
302
Nicolas Capens264f1522015-01-09 17:21:17 -0500303GLsizei RenderbufferStorage::getWidth() const
304{
305 return mWidth;
306}
307
308GLsizei RenderbufferStorage::getHeight() const
309{
310 return mHeight;
311}
312
313GLenum RenderbufferStorage::getFormat() const
314{
315 return format;
316}
317
318sw::Format RenderbufferStorage::getInternalFormat() const
319{
320 return internalFormat;
321}
322
323GLsizei RenderbufferStorage::getSamples() const
324{
325 return mSamples;
326}
327
Nicolas Capensa9b49372015-01-30 00:33:26 -0500328Colorbuffer::Colorbuffer(Image *renderTarget) : mRenderTarget(renderTarget)
Nicolas Capens264f1522015-01-09 17:21:17 -0500329{
330 if(renderTarget)
331 {
332 renderTarget->addRef();
Nicolas Capens0bac2852016-05-07 06:09:58 -0400333
Nicolas Capens264f1522015-01-09 17:21:17 -0500334 mWidth = renderTarget->getWidth();
335 mHeight = renderTarget->getHeight();
336 internalFormat = renderTarget->getInternalFormat();
337 format = sw2es::ConvertBackBufferFormat(internalFormat);
Nicolas Capensa9b49372015-01-30 00:33:26 -0500338 mSamples = renderTarget->getMultiSampleDepth() & ~1;
Nicolas Capens264f1522015-01-09 17:21:17 -0500339 }
340}
341
Nicolas Capens3ff330f2015-09-03 16:41:09 -0400342Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
Nicolas Capens264f1522015-01-09 17:21:17 -0500343{
344 Device *device = getDevice();
345
346 sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
Nicolas Capens3ff330f2015-09-03 16:41:09 -0400347 int supportedSamples = Context::getSupportedMultisampleCount(samples);
Nicolas Capens264f1522015-01-09 17:21:17 -0500348
349 if(width > 0 && height > 0)
350 {
351 mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
352
353 if(!mRenderTarget)
354 {
355 error(GL_OUT_OF_MEMORY);
356 return;
357 }
358 }
359
360 mWidth = width;
361 mHeight = height;
362 this->format = format;
363 internalFormat = requestedFormat;
Alexis Hetu7a570402015-07-02 13:46:59 -0400364 mSamples = supportedSamples;
Nicolas Capens264f1522015-01-09 17:21:17 -0500365}
366
367Colorbuffer::~Colorbuffer()
368{
369 if(mRenderTarget)
370 {
371 mRenderTarget->release();
372 }
373}
374
Nicolas Capensa9b49372015-01-30 00:33:26 -0500375// Increments refcount on surface.
376// caller must release() the returned surface
377Image *Colorbuffer::getRenderTarget()
Nicolas Capens264f1522015-01-09 17:21:17 -0500378{
379 if(mRenderTarget)
380 {
381 mRenderTarget->addRef();
382 }
383
384 return mRenderTarget;
385}
386
Nicolas Capensa9b49372015-01-30 00:33:26 -0500387DepthStencilbuffer::DepthStencilbuffer(Image *depthStencil) : mDepthStencil(depthStencil)
Nicolas Capens264f1522015-01-09 17:21:17 -0500388{
389 if(depthStencil)
390 {
391 depthStencil->addRef();
392
393 mWidth = depthStencil->getWidth();
394 mHeight = depthStencil->getHeight();
395 internalFormat = depthStencil->getInternalFormat();
396 format = sw2es::ConvertDepthStencilFormat(internalFormat);
Nicolas Capensa9b49372015-01-30 00:33:26 -0500397 mSamples = depthStencil->getMultiSampleDepth() & ~1;
Nicolas Capens264f1522015-01-09 17:21:17 -0500398 }
399}
400
Nicolas Capens3ff330f2015-09-03 16:41:09 -0400401DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
Nicolas Capens264f1522015-01-09 17:21:17 -0500402{
403 Device *device = getDevice();
404
Nicolas Capens3ff330f2015-09-03 16:41:09 -0400405 int supportedSamples = Context::getSupportedMultisampleCount(samples);
Nicolas Capens264f1522015-01-09 17:21:17 -0500406
407 if(width > 0 && height > 0)
408 {
409 mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
410
411 if(!mDepthStencil)
412 {
413 error(GL_OUT_OF_MEMORY);
414 return;
415 }
416 }
417
418 mWidth = width;
419 mHeight = height;
Nicolas Capensa9b49372015-01-30 00:33:26 -0500420 format = GL_DEPTH24_STENCIL8_EXT;
Nicolas Capens264f1522015-01-09 17:21:17 -0500421 internalFormat = sw::FORMAT_D24S8;
Alexis Hetu7a570402015-07-02 13:46:59 -0400422 mSamples = supportedSamples;
Nicolas Capens264f1522015-01-09 17:21:17 -0500423}
424
425DepthStencilbuffer::~DepthStencilbuffer()
426{
427 if(mDepthStencil)
428 {
429 mDepthStencil->release();
430 }
431}
432
Nicolas Capensa9b49372015-01-30 00:33:26 -0500433// Increments refcount on surface.
434// caller must release() the returned surface
435Image *DepthStencilbuffer::getRenderTarget()
Nicolas Capens264f1522015-01-09 17:21:17 -0500436{
437 if(mDepthStencil)
438 {
439 mDepthStencil->addRef();
440 }
441
442 return mDepthStencil;
443}
444
Nicolas Capensa9b49372015-01-30 00:33:26 -0500445Depthbuffer::Depthbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
Nicolas Capens264f1522015-01-09 17:21:17 -0500446{
447 if(depthStencil)
448 {
449 format = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
Nicolas Capens0bac2852016-05-07 06:09:58 -0400450 // will expect one of the valid renderbuffer formats for use in
Nicolas Capens264f1522015-01-09 17:21:17 -0500451 // glRenderbufferStorage
452 }
453}
454
455Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
456{
457 if(mDepthStencil)
458 {
459 format = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
Nicolas Capens0bac2852016-05-07 06:09:58 -0400460 // will expect one of the valid renderbuffer formats for use in
Nicolas Capens264f1522015-01-09 17:21:17 -0500461 // glRenderbufferStorage
462 }
463}
464
465Depthbuffer::~Depthbuffer()
466{
467}
468
Nicolas Capensa9b49372015-01-30 00:33:26 -0500469Stencilbuffer::Stencilbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
Nicolas Capens264f1522015-01-09 17:21:17 -0500470{
471 if(depthStencil)
472 {
473 format = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
Nicolas Capens0bac2852016-05-07 06:09:58 -0400474 // will expect one of the valid renderbuffer formats for use in
Nicolas Capens264f1522015-01-09 17:21:17 -0500475 // glRenderbufferStorage
476 }
477}
478
479Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
480{
481 if(mDepthStencil)
482 {
483 format = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
Nicolas Capens0bac2852016-05-07 06:09:58 -0400484 // will expect one of the valid renderbuffer formats for use in
Nicolas Capens264f1522015-01-09 17:21:17 -0500485 // glRenderbufferStorage
486 }
487}
488
489Stencilbuffer::~Stencilbuffer()
490{
491}
492
493}