1// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2// 3// 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 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// 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. 14 15// Renderbuffer.cpp: the Renderbuffer class and its derived classes 16// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer 17// objects and related functionality. 18 19#include "Renderbuffer.h" 20 21#include "main.h" 22#include "Texture.h" 23#include "utilities.h" 24 25namespace gl 26{ 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 33// or decrementing. 34void 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{ 76 mTexture2D = texture; 77} 78 79RenderbufferTexture2D::~RenderbufferTexture2D() 80{ 81 mTexture2D = nullptr; 82} 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{ 88 mTexture2D->addProxyRef(proxy); 89} 90 91void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy) 92{ 93 mTexture2D->releaseProxy(proxy); 94} 95 96// Increments refcount on surface. 97// caller must release() the returned surface 98Image *RenderbufferTexture2D::getRenderTarget() 99{ 100 return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0); 101} 102 103GLsizei 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{ 132 mTextureCubeMap = texture; 133} 134 135RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap() 136{ 137 mTextureCubeMap = nullptr; 138} 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{ 144 mTextureCubeMap->addProxyRef(proxy); 145} 146 147void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy) 148{ 149 mTextureCubeMap->releaseProxy(proxy); 150} 151 152// Increments refcount on surface. 153// caller must release() the returned surface 154Image *RenderbufferTextureCubeMap::getRenderTarget() 155{ 156 return mTextureCubeMap->getRenderTarget(mTarget, 0); 157} 158 159GLsizei 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 186Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name) 187{ 188 ASSERT(instance); 189 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{ 201 mInstance->addProxyRef(this); 202 203 Object::addRef(); 204} 205 206void Renderbuffer::release() 207{ 208 mInstance->releaseProxy(this); 209 210 Object::release(); 211} 212 213// Increments refcount on surface. 214// caller must Release() the returned surface 215Image *Renderbuffer::getRenderTarget() 216{ 217 return mInstance->getRenderTarget(); 218} 219 220GLsizei 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{ 277 ASSERT(newStorage); 278 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 296// Increments refcount on surface. 297// caller must Release() the returned surface 298Image *RenderbufferStorage::getRenderTarget() 299{ 300 return nullptr; 301} 302 303GLsizei 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 328Colorbuffer::Colorbuffer(Image *renderTarget) : mRenderTarget(renderTarget) 329{ 330 if(renderTarget) 331 { 332 renderTarget->addRef(); 333 334 mWidth = renderTarget->getWidth(); 335 mHeight = renderTarget->getHeight(); 336 internalFormat = renderTarget->getInternalFormat(); 337 format = sw2es::ConvertBackBufferFormat(internalFormat); 338 mSamples = renderTarget->getMultiSampleDepth() & ~1; 339 } 340} 341 342Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr) 343{ 344 Device *device = getDevice(); 345 346 sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format); 347 int supportedSamples = Context::getSupportedMultisampleCount(samples); 348 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; 364 mSamples = supportedSamples; 365} 366 367Colorbuffer::~Colorbuffer() 368{ 369 if(mRenderTarget) 370 { 371 mRenderTarget->release(); 372 } 373} 374 375// Increments refcount on surface. 376// caller must release() the returned surface 377Image *Colorbuffer::getRenderTarget() 378{ 379 if(mRenderTarget) 380 { 381 mRenderTarget->addRef(); 382 } 383 384 return mRenderTarget; 385} 386 387DepthStencilbuffer::DepthStencilbuffer(Image *depthStencil) : mDepthStencil(depthStencil) 388{ 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); 397 mSamples = depthStencil->getMultiSampleDepth() & ~1; 398 } 399} 400 401DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr) 402{ 403 Device *device = getDevice(); 404 405 int supportedSamples = Context::getSupportedMultisampleCount(samples); 406 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; 420 format = GL_DEPTH24_STENCIL8_EXT; 421 internalFormat = sw::FORMAT_D24S8; 422 mSamples = supportedSamples; 423} 424 425DepthStencilbuffer::~DepthStencilbuffer() 426{ 427 if(mDepthStencil) 428 { 429 mDepthStencil->release(); 430 } 431} 432 433// Increments refcount on surface. 434// caller must release() the returned surface 435Image *DepthStencilbuffer::getRenderTarget() 436{ 437 if(mDepthStencil) 438 { 439 mDepthStencil->addRef(); 440 } 441 442 return mDepthStencil; 443} 444 445Depthbuffer::Depthbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil) 446{ 447 if(depthStencil) 448 { 449 format = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function 450 // will expect one of the valid renderbuffer formats for use in 451 // 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 460 // will expect one of the valid renderbuffer formats for use in 461 // glRenderbufferStorage 462 } 463} 464 465Depthbuffer::~Depthbuffer() 466{ 467} 468 469Stencilbuffer::Stencilbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil) 470{ 471 if(depthStencil) 472 { 473 format = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function 474 // will expect one of the valid renderbuffer formats for use in 475 // 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 484 // will expect one of the valid renderbuffer formats for use in 485 // glRenderbufferStorage 486 } 487} 488 489Stencilbuffer::~Stencilbuffer() 490{ 491} 492 493} 494