PageRenderTime 47ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/GT-I5700/gles20/src/glFramebufferObject.cpp

https://github.com/DE-NISkA/cm_android_vendor_spica
C++ | 1240 lines | 905 code | 243 blank | 92 comment | 214 complexity | 1ac9f2133c232ed7f37db61490d4fa9c MD5 | raw file
  1. /*
  2. *******************************************************************************
  3. *
  4. * SAMSUNG INDIA SOFTWARE OPERATIONS
  5. * Copyright(C) 2006
  6. * ALL RIGHTS RESERVED
  7. *
  8. * This program is proprietary to Samsung India Software Operations Pvt. Ltd.,
  9. * and is protected under International Copyright Act as an unpublished work.Its
  10. * use and disclosure is limited by the terms and conditions of a license agree-
  11. * -ment. It may not be copied or otherwise reproduced or disclosed to persons
  12. * outside the licensee's organization except in accordance with the terms and
  13. * conditions of such an agreement. All copies and reproductions shall be the
  14. * property of Samsung India Software Operations Pvt. Ltd. and must bear this
  15. * notice in its entirety.
  16. *
  17. *******************************************************************************
  18. */
  19. /*
  20. ***************************************************************************//*!
  21. *
  22. * \file glFramebufferObject.cpp
  23. * \author Sandeep Kakarlapudi (s.kakarla@samsung.com)
  24. * \brief Implementation of all FBO and renderbuffer fnuctionality
  25. *
  26. *//*---------------------------------------------------------------------------
  27. * NOTES:
  28. *
  29. *//*---------------------------------------------------------------------------
  30. * HISTORY:
  31. *
  32. * 06.02.2007 Sandeep Kakarlapudi Initial version
  33. *
  34. *******************************************************************************
  35. */
  36. #include "glState.h"
  37. #include "pixel.h"
  38. #include "platform.h"
  39. //--------------- NameManager ---------------
  40. void NameManager::addName(GLuint id)
  41. {
  42. //int size = nameList.size();
  43. NameContainer::iterator it = nameList.begin();
  44. while(it != nameList.end())
  45. {
  46. if(id == (*it))
  47. {
  48. //LOGMSG("\nWARNING: duplicate name found: %d\n",id);
  49. return;
  50. }
  51. else if( id < (*it))
  52. {
  53. nameList.insert(it, id);
  54. return;
  55. }
  56. ++it;
  57. }
  58. nameList.push_back(id);
  59. }
  60. void NameManager::genNames(GLsizei n, GLuint* ids)
  61. {
  62. if(!ids)
  63. {
  64. return;
  65. }
  66. for(int i=0; i<n; i++)
  67. {
  68. ids[i] = _genName();
  69. }
  70. }
  71. void NameManager::removeName(GLuint id)
  72. {
  73. NameContainer::iterator it = nameList.begin();
  74. while(it != nameList.end())
  75. {
  76. if(id == (*it))
  77. {
  78. nameList.erase(it);
  79. return;
  80. }
  81. ++it;
  82. }
  83. }
  84. void NameManager::clear()
  85. {
  86. nameList.clear();
  87. }
  88. GLuint NameManager::_genName() //TODO: validate/optimize me!!
  89. {
  90. GLuint id = 1;
  91. NameContainer::iterator it = nameList.begin();
  92. while(it != nameList.end())
  93. {
  94. if(id < (*it))
  95. {
  96. nameList.insert(it,id);
  97. return id;
  98. }
  99. else
  100. {
  101. id = (*it) + 1;
  102. }
  103. ++it;
  104. }
  105. nameList.push_back(id);
  106. return id;
  107. }
  108. //--------------- FramebufferState ---------------
  109. FramebufferState::FramebufferState()
  110. {
  111. setDefaults();
  112. }
  113. void FramebufferState::setDefaults()
  114. {
  115. framebuffBinding = 0;
  116. framebuffNames.clear();
  117. FBOMap::iterator it = framebuffList.begin();
  118. while(it != framebuffList.end())
  119. {
  120. delete it->second;
  121. ++it;
  122. }
  123. framebuffList.clear();
  124. }
  125. void FramebufferState::detachAttachment(GLenum objectType, GLuint objectName)
  126. {
  127. if(framebuffBinding == 0)
  128. return;
  129. //Get Framebuffer Object
  130. FBOMap::iterator it = framebuffList.find(framebuffBinding);
  131. //Check its not null
  132. gAssert((it!= framebuffList.end()) && "\n framebuffBinding is invalid! Could not find the bound fbo!\n");
  133. FramebufferObject* fbo = it->second;
  134. gAssert((fbo!=0) && "\n framebuffList has a null pointer as an FBO!\n");
  135. if((fbo->colorAttachment.objectType == objectType)
  136. && (fbo->colorAttachment.objectName == objectName))
  137. {
  138. fbo->colorAttachment.setDefaults();
  139. }
  140. if((fbo->depthAttachment.objectType == objectType)
  141. && (fbo->depthAttachment.objectName == objectName))
  142. {
  143. fbo->depthAttachment.setDefaults();
  144. }
  145. if((fbo->stencilAttachment.objectType == objectType)
  146. && (fbo->stencilAttachment.objectName == objectName))
  147. {
  148. fbo->stencilAttachment.setDefaults();
  149. }
  150. }
  151. void FramebufferState::detachRenderbuffer(GLuint id)
  152. {
  153. detachAttachment(GL_RENDERBUFFER, id);
  154. }
  155. void FramebufferState::detachTexture(GLuint id)
  156. {
  157. detachAttachment(GL_TEXTURE, id);
  158. }
  159. GLenum sizedInternalFormat(GLenum format, GLenum type)
  160. {
  161. if((format==GL_RGB)&&(type==GL_UNSIGNED_SHORT_5_6_5))
  162. {
  163. return GL_RGB565;
  164. }
  165. else
  166. {
  167. //LOGMSG("format, type combo unsupported! sizedInternalFormat\n");
  168. return GL_NONE;
  169. }
  170. }
  171. #if 0
  172. bool isColorRenderable(GLenum format)
  173. {
  174. switch(format)
  175. {
  176. case GL_RGBA4:
  177. case GL_RGB5_A1:
  178. case GL_RGB565:
  179. return true;
  180. }
  181. return false;
  182. }
  183. #else
  184. bool isColorRenderable(PxFmt nativeformat)
  185. {
  186. switch(nativeformat)
  187. {
  188. case E_ARGB4:
  189. case E_ARGB1555:
  190. case E_RGB565:
  191. case E_RGB5:
  192. case E_ARGB8:
  193. case E_ARGB0888:
  194. return true;
  195. default:
  196. return false;
  197. }
  198. return false; //To silence compiler.
  199. }
  200. #endif
  201. bool isDepthRenderable(PxFmt nativeformat)
  202. {
  203. switch(nativeformat)
  204. {
  205. case E_Depth24:
  206. return true;
  207. default:
  208. return false;
  209. }
  210. return false; //To silence compiler.
  211. }
  212. bool isStencilRenderable(PxFmt nativeformat)
  213. {
  214. switch(nativeformat)
  215. {
  216. case E_Stencil8:
  217. return true;
  218. default:
  219. return true;
  220. }
  221. return false; //To silence compiler.
  222. }
  223. //--------------- FramebufferObject ---------------
  224. GLenum FramebufferObject::status()
  225. {
  226. //bool attachmentComplete = true;
  227. bool colorAttComplete = true;
  228. bool depthAttComplete = true;
  229. bool stencilAttComplete = true;
  230. RTInfo attInfo[3];
  231. RTInfo& colorAttInfo = attInfo[0];
  232. RTInfo& depthAttInfo = attInfo[1];
  233. RTInfo& stencilAttInfo = attInfo[2];
  234. if(colorAttachment.objectType != GL_NONE)
  235. {
  236. colorAttInfo = colorAttachment.getInfo();
  237. if((!isColorRenderable(colorAttInfo.nativeFormat))||(colorAttInfo.width==0)||(colorAttInfo.height==0))
  238. {
  239. colorAttComplete = false;
  240. }
  241. }
  242. if(depthAttachment.objectType != GL_NONE)
  243. {
  244. depthAttInfo = depthAttachment.getInfo();
  245. if((!isDepthRenderable(depthAttInfo.nativeFormat))||(depthAttInfo.width==0)||(depthAttInfo.height==0))
  246. {
  247. depthAttComplete = false;
  248. }
  249. }
  250. if(stencilAttachment.objectName != GL_NONE)
  251. {
  252. stencilAttInfo = stencilAttachment.getInfo();
  253. if((!isStencilRenderable(stencilAttInfo.nativeFormat))||(stencilAttInfo.width==0)||(stencilAttInfo.height==0))
  254. {
  255. stencilAttComplete = false;
  256. }
  257. }
  258. if(! (colorAttComplete && depthAttComplete && stencilAttComplete))
  259. {
  260. return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
  261. }
  262. if( (colorAttachment.objectType == GL_NONE) && (depthAttachment.objectType == GL_NONE) && (stencilAttachment.objectType == GL_NONE))
  263. {
  264. return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
  265. }
  266. bool dimEq = true;
  267. GLuint width = 0;
  268. GLuint height = 0;
  269. for(unsigned int i=0; i< sizeof(attInfo)/sizeof(attInfo[0]); i++)
  270. {
  271. if(attInfo[i].format)
  272. {
  273. if((width==0)||(height==0))
  274. {
  275. width = attInfo[i].width;
  276. height = attInfo[i].height;
  277. }
  278. else
  279. {
  280. if((width!= attInfo[i].width)||(height!=attInfo[i].height))
  281. {
  282. dimEq = false;
  283. break;
  284. }
  285. }
  286. }
  287. }
  288. if(!dimEq)
  289. {
  290. return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
  291. }
  292. //internal format combinations validity
  293. if((depthAttInfo.format != GL_NONE)&&(stencilAttInfo.format != GL_NONE))
  294. {
  295. return GL_FRAMEBUFFER_UNSUPPORTED;
  296. }
  297. return GL_FRAMEBUFFER_COMPLETE;
  298. }
  299. //------------FBOAttachmentPointState----------------
  300. RTInfo FBOAttachmentPointState::getInfo()
  301. {
  302. GET_GL_STATE(ctx);
  303. RTInfo info;
  304. if(objectType == GL_TEXTURE)
  305. {
  306. TextureObject* texObj = GetTexObject(objectName);
  307. if(!texObj)
  308. {
  309. }
  310. else if(texObj->texType == GL_TEXTURE_2D)
  311. {
  312. //format should no longer be used native format is sufficient.
  313. info.format = 0;//sizedInternalFormat(texObj->images.tex2D[textureLevel].internalFormat,texObj->images.tex2D[textureLevel].PixType);
  314. info.nativeFormat = PxFmt(texObj->images.tex2D[textureLevel].nativeFormat);
  315. info.width = texObj->images.tex2D[textureLevel].width;
  316. info.height = texObj->images.tex2D[textureLevel].height;
  317. //TODO: how to support render to mipmap level?
  318. info.addr.vaddr = texObj->hChunk->GetVirtAddr();
  319. info.addr.paddr = texObj->hChunk->GetPhyAddr();
  320. }
  321. else if(texObj->texType == GL_TEXTURE_CUBE_MAP)
  322. {
  323. //format should no longer be used native format is sufficient.
  324. info.format = 0;//sizedInternalFormat(texObj->images.cubeMap[textureCubeMapFace][textureLevel].internalFormat, texObj->images.cubeMap[textureCubeMapFace][textureLevel].PixType);
  325. info.nativeFormat = PxFmt(texObj->images.cubeMap[textureCubeMapFace][textureLevel].nativeFormat);
  326. info.width = texObj->images.cubeMap[textureCubeMapFace][textureLevel].width;
  327. info.height = texObj->images.cubeMap[textureCubeMapFace][textureLevel].height;
  328. //TODO: how to support render to mipmap level?
  329. //TODO: how to support to different cubemap levels?
  330. info.addr.vaddr = texObj->hChunk->GetVirtAddr();
  331. info.addr.paddr = texObj->hChunk->GetPhyAddr();
  332. }
  333. return info;
  334. }
  335. if(objectType == GL_RENDERBUFFER)
  336. {
  337. RenderbufferObject* rbo =0;
  338. if(!ctx->renderbuffState.getRBO(objectName, &rbo))
  339. {
  340. //TODO: warn?
  341. }
  342. else if(!rbo)
  343. {
  344. //TODO: warn?
  345. }
  346. else
  347. {
  348. //format should no longer be used native format is sufficient.
  349. info.format = 0;//rbo->internalFormat;
  350. info.nativeFormat = rbo->nativeFormat;
  351. info.width = rbo->width;
  352. info.height = rbo->height;
  353. info.addr.vaddr = rbo->hChunk->GetVirtAddr();
  354. info.addr.paddr = rbo->hChunk->GetPhyAddr();
  355. }
  356. }
  357. return info;
  358. }
  359. bool isValidFBAttachment(GLenum attachment)
  360. {
  361. switch(attachment)
  362. {
  363. case GL_COLOR_ATTACHMENT0:
  364. case GL_DEPTH_ATTACHMENT:
  365. case GL_STENCIL_ATTACHMENT:
  366. return true; //intendend fall-through
  367. }
  368. return false;
  369. }
  370. struct PixelFormatInfo
  371. {
  372. GLenum format;
  373. GLuint bpp; //Bytes per pixel (allocation size)
  374. };
  375. PixelFormatInfo validRBformats[]={
  376. {GL_RGBA4, 2},
  377. {GL_RGB5_A1, 2},
  378. {GL_RGB565, 2},
  379. {GL_RGB8, 4},
  380. {GL_RGBA8, 4},
  381. {GL_DEPTH_COMPONENT16, 4}, //Fimg only supports depth24stencil8
  382. {GL_STENCIL_INDEX, 4}, //Fimg only supports depth24stencil8
  383. };
  384. bool isValidRBformat(GLenum format)
  385. {
  386. const int numValidFormats = sizeof(validRBformats)/sizeof(validRBformats[0]);
  387. for(int i=0; i < numValidFormats; i++)
  388. {
  389. if(validRBformats[i].format == format)
  390. {
  391. return true;
  392. }
  393. }
  394. return false;
  395. }
  396. GLuint getFormatBpp(GLenum format)
  397. {
  398. const int numValidFormats = sizeof(validRBformats)/sizeof(validRBformats[0]);
  399. for(int i=0; i < numValidFormats; i++)
  400. {
  401. if(validRBformats[i].format == format)
  402. {
  403. return validRBformats[i].bpp;
  404. }
  405. }
  406. return 0;
  407. }
  408. bool isFBrenderable(OGLState* ctx)
  409. {
  410. //GET_GL_STATE(ctx);
  411. if(ctx->framebuffState.framebuffBinding == 0)
  412. {
  413. return true;
  414. }
  415. FramebufferObject* fbo =0;
  416. if(!ctx->framebuffState.getFBO(ctx->framebuffState.framebuffBinding, &fbo))
  417. {
  418. gAssert(false && "Invalid fbo bound as current!\n");
  419. return false;
  420. }
  421. return (fbo->status() == GL_FRAMEBUFFER_COMPLETE);
  422. }
  423. FramebufferData getFBData()
  424. {
  425. GET_GL_STATE(ctx);
  426. FramebufferData fbData;
  427. fbData.colorAddr.vaddr = fbData.colorAddr.paddr = 0;
  428. fbData.nativeColorFormat = E_INVALID_PIXEL_FORMAT;
  429. fbData.width = fbData.height = 0;
  430. fbData.depthStencilAddr.vaddr = fbData.depthStencilAddr.paddr = 0;
  431. fbData.nativeDepthStencilFormat = E_INVALID_PIXEL_FORMAT;
  432. fbData.flipped = 0;
  433. if(ctx->framebuffState.framebuffBinding == 0)
  434. {
  435. return ctx->defFBData;
  436. }
  437. FramebufferObject* fbo =0;
  438. if(!ctx->framebuffState.getFBO(ctx->framebuffState.framebuffBinding, &fbo))
  439. {
  440. gAssert(false && "Invalid fbo bound as current!\n");
  441. return fbData;
  442. }
  443. if(isFBrenderable(ctx))
  444. {
  445. }
  446. else
  447. {
  448. set_err(GL_INVALID_FRAMEBUFFER_OPERATION);
  449. //LOGMSG("Warning, fb not renderable");
  450. }
  451. //TODO: assert that fb is renderable.
  452. //Next fill out the fbData struct
  453. RTInfo colorAttInfo = fbo->colorAttachment.getInfo();
  454. RTInfo depthAttInfo = fbo->depthAttachment.getInfo();
  455. //RTInfo stencilAttInfo = fbo->depthAttachment.getInfo();
  456. fbData.colorAddr = colorAttInfo.addr;
  457. fbData.nativeColorFormat = PxFmt(colorAttInfo.nativeFormat);
  458. fbData.width = colorAttInfo.width;
  459. fbData.height = colorAttInfo.height;
  460. if(depthAttInfo.addr.vaddr)
  461. {
  462. fbData.depthStencilAddr = depthAttInfo.addr;
  463. fbData.nativeDepthStencilFormat = PxFmt(depthAttInfo.nativeFormat);
  464. }
  465. //TODO: stencil
  466. fbData.flipped = 1;
  467. return fbData;
  468. }
  469. FramebufferData getReadFBData()
  470. {
  471. GET_GL_STATE(ctx);
  472. FramebufferData fbData;
  473. if(ctx->framebuffState.framebuffBinding == 0)
  474. {
  475. return ctx->readFBData;
  476. }
  477. FramebufferObject* fbo = 0;
  478. if(!ctx->framebuffState.getFBO(ctx->framebuffState.framebuffBinding, &fbo))
  479. {
  480. gAssert(false && "Invalid fbo bound as current!\n");
  481. fbData.colorAddr.vaddr = fbData.colorAddr.paddr = 0;
  482. fbData.nativeColorFormat = E_INVALID_PIXEL_FORMAT;
  483. fbData.width = fbData.height = 0;
  484. fbData.depthStencilAddr.vaddr = fbData.depthStencilAddr.paddr = 0;
  485. fbData.nativeDepthStencilFormat = E_INVALID_PIXEL_FORMAT;
  486. fbData.flipped = 0;
  487. return fbData;
  488. }
  489. if(isFBrenderable(ctx))
  490. {
  491. }
  492. else
  493. {
  494. set_err(GL_INVALID_FRAMEBUFFER_OPERATION);
  495. //LOGMSG("Warning, fb not renderable");
  496. }
  497. //TODO: assert that fb is renderable.
  498. //Next fill out the fbData struct
  499. RTInfo colorAttInfo = fbo->colorAttachment.getInfo();
  500. RTInfo depthAttInfo = fbo->depthAttachment.getInfo();
  501. //RTInfo stencilAttInfo = fbo->depthAttachment.getInfo();
  502. fbData.colorAddr = colorAttInfo.addr;
  503. fbData.nativeColorFormat = PxFmt(colorAttInfo.nativeFormat);
  504. fbData.width = colorAttInfo.width;
  505. fbData.height = colorAttInfo.height;
  506. if(depthAttInfo.addr.vaddr)
  507. {
  508. fbData.depthStencilAddr = depthAttInfo.addr;
  509. fbData.nativeDepthStencilFormat = PxFmt(depthAttInfo.nativeFormat);
  510. }
  511. else
  512. {
  513. fbData.depthStencilAddr.vaddr = fbData.depthStencilAddr.paddr = 0;
  514. fbData.nativeDepthStencilFormat = E_INVALID_PIXEL_FORMAT;
  515. }
  516. //TODO: stencil
  517. fbData.flipped = 1;
  518. return fbData;
  519. }
  520. GL_API GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
  521. {
  522. GET_GL_STATE(ctx);
  523. RBOMap::iterator it = ctx->renderbuffState.renderbuffList.find(renderbuffer);
  524. if(it == ctx->renderbuffState.renderbuffList.end())
  525. {
  526. return GL_FALSE;
  527. }
  528. return GL_TRUE;
  529. }
  530. GL_API void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
  531. {
  532. GET_GL_STATE(ctx);
  533. if(target != GL_RENDERBUFFER)
  534. {
  535. set_err(GL_INVALID_ENUM);
  536. return;
  537. }
  538. if(renderbuffer == 0)
  539. {
  540. ctx->renderbuffState.renderbuffBinding = 0;
  541. return;
  542. }
  543. RBOMap::iterator it = ctx->renderbuffState.renderbuffList.find(renderbuffer);
  544. //Does not exist?
  545. if(it == ctx->renderbuffState.renderbuffList.end())
  546. {
  547. //Try creating a new one
  548. if(ctx->renderbuffState.createRenderbuffer(renderbuffer))
  549. {
  550. ctx->renderbuffState.renderbuffBinding = renderbuffer;
  551. }
  552. else
  553. {
  554. set_err(GL_OUT_OF_MEMORY);
  555. }
  556. }
  557. else //exists
  558. {
  559. ctx->renderbuffState.renderbuffBinding = renderbuffer;
  560. }
  561. }
  562. GL_API void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
  563. {
  564. GET_GL_STATE(ctx);
  565. if((n==0) || (renderbuffers==0))
  566. {
  567. return;
  568. }
  569. for(int i=0; i<n; i++)
  570. {
  571. RBOMap::iterator it = ctx->renderbuffState.renderbuffList.find(renderbuffers[i]);
  572. //Is the renderbuffer id valid?
  573. if(it != ctx->renderbuffState.renderbuffList.end())
  574. {
  575. //Unbind if bound to GL_RENDERBUFFER
  576. if(renderbuffers[i] == ctx->renderbuffState.renderbuffBinding)
  577. {
  578. ctx->renderbuffState.renderbuffBinding = 0;
  579. }
  580. //Detach from current framebuffer
  581. ctx->framebuffState.detachRenderbuffer(renderbuffers[i]);
  582. pCA->Free(it->second->hChunk);
  583. ctx->renderbuffState.renderbuffList.erase(it);
  584. ctx->renderbuffState.renderbuffNames.removeName(renderbuffers[i]);
  585. }
  586. }
  587. }
  588. GL_API void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
  589. {
  590. GET_GL_STATE(ctx);
  591. if((n==0) || (renderbuffers == 0))
  592. {
  593. return;
  594. }
  595. ctx->renderbuffState.renderbuffNames.genNames(n, renderbuffers);
  596. }
  597. GL_API void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
  598. {
  599. GET_GL_STATE(ctx);
  600. if(target != GL_RENDERBUFFER)
  601. {
  602. set_err(GL_INVALID_ENUM);
  603. return;
  604. }
  605. if(!isValidRBformat(internalformat))
  606. {
  607. set_err(GL_INVALID_ENUM);
  608. return;
  609. }
  610. if((width > MAX_RENDERBUFFER_SIZE) || (height > MAX_RENDERBUFFER_SIZE))
  611. {
  612. set_err(GL_INVALID_VALUE);
  613. return;
  614. }
  615. if(ctx->renderbuffState.renderbuffBinding == 0)
  616. {
  617. set_err(GL_INVALID_OPERATION); //TODO: spec ambiguity
  618. return;
  619. }
  620. RenderbufferObject* rbo = 0;
  621. if(!ctx->renderbuffState.getRBO(ctx->renderbuffState.renderbuffBinding,&rbo))
  622. {
  623. //LOGMSG("Current renderbuffer is not valid: %d!\n",ctx->renderbuffState.renderbuffBinding );
  624. gAssert(false);
  625. return;
  626. }
  627. if(rbo->hChunk)
  628. {
  629. pCA->Free(rbo->hChunk);
  630. rbo->hChunk = 0;
  631. }
  632. rbo->internalFormat = internalformat;
  633. rbo->nativeFormat = translateGLSizedInternal(internalformat);
  634. GLuint size = width * height * pixelSize(rbo->nativeFormat);
  635. rbo->hChunk = pCA->New(size);
  636. if((rbo->hChunk == 0) || ((GLubyte*) (rbo->hChunk->GetVirtAddr())) == 0)
  637. {
  638. set_err(GL_OUT_OF_MEMORY);
  639. rbo->setDefaults(); //TODO: spec ambiguity
  640. return;
  641. }
  642. rbo->width = width;
  643. rbo->height = height;
  644. }
  645. GL_API void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
  646. {
  647. GET_GL_STATE(ctx);
  648. if(target != GL_RENDERBUFFER)
  649. {
  650. set_err(GL_INVALID_ENUM);
  651. return;
  652. }
  653. if(ctx->renderbuffState.renderbuffBinding == 0)
  654. {
  655. set_err(GL_INVALID_OPERATION);
  656. return;
  657. }
  658. if(!params)
  659. {
  660. return;
  661. }
  662. RenderbufferObject* rbo = 0;
  663. if(!ctx->renderbuffState.getRBO(ctx->renderbuffState.renderbuffBinding,&rbo))
  664. {
  665. //LOGMSG("Current renderbuffer is not valid: %d!\n",ctx->renderbuffState.renderbuffBinding );
  666. gAssert(false);
  667. return;
  668. }
  669. switch(pname)
  670. {
  671. case GL_RENDERBUFFER_WIDTH: *params = rbo->width; break;
  672. case GL_RENDERBUFFER_HEIGHT: *params = rbo->height; break;
  673. case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = rbo->internalFormat; break;
  674. case GL_RENDERBUFFER_RED_SIZE: *params = 0; break; //TODO: return actual
  675. case GL_RENDERBUFFER_GREEN_SIZE: *params = 0; break; //TODO: return actual
  676. case GL_RENDERBUFFER_BLUE_SIZE: *params = 0; break; //TODO: return actual
  677. case GL_RENDERBUFFER_ALPHA_SIZE: *params = 0; break; //TODO: return actual
  678. case GL_RENDERBUFFER_DEPTH_SIZE: *params = 0; break; //TODO: return actual
  679. case GL_RENDERBUFFER_STENCIL_SIZE: *params = 0; break; //TODO: return actual
  680. default:
  681. set_err(GL_INVALID_ENUM);
  682. }
  683. }
  684. //TODO: is this included in GLES 2.0?
  685. GL_API void GL_APIENTRY glGetRenderbufferStorageFormatsiv(GLenum target, int n, GLint *listofformats, GLint *numsupportedformats)
  686. {
  687. }
  688. GL_API GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
  689. {
  690. GET_GL_STATE(ctx);
  691. FBOMap::iterator it = ctx->framebuffState.framebuffList.find(framebuffer);
  692. if(it == ctx->framebuffState.framebuffList.end())
  693. {
  694. return GL_FALSE;
  695. }
  696. return GL_TRUE;
  697. }
  698. GL_API void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
  699. {
  700. GET_GL_STATE(ctx);
  701. if(target != GL_FRAMEBUFFER)
  702. {
  703. set_err(GL_INVALID_ENUM);
  704. return;
  705. }
  706. if(framebuffer == 0)
  707. {
  708. ctx->framebuffState.framebuffBinding = 0;
  709. return;
  710. }
  711. FBOMap::iterator it = ctx->framebuffState.framebuffList.find(framebuffer);
  712. //Does not exist?
  713. if(it == ctx->framebuffState.framebuffList.end())
  714. {
  715. //Try creating a new one
  716. if(ctx->framebuffState.createFramebuffer(framebuffer))
  717. {
  718. ctx->framebuffState.framebuffBinding = framebuffer;
  719. }
  720. else
  721. {
  722. set_err(GL_OUT_OF_MEMORY);
  723. }
  724. }
  725. else //exists
  726. {
  727. ctx->framebuffState.framebuffBinding = framebuffer;
  728. }
  729. }
  730. GL_API void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
  731. {
  732. GET_GL_STATE(ctx);
  733. if((n==0) || (framebuffers==0))
  734. {
  735. return;
  736. }
  737. for(int i=0; i<n; i++)
  738. {
  739. FBOMap::iterator it = ctx->framebuffState.framebuffList.find(framebuffers[i]);
  740. //Is the framebuffer id valid?
  741. if(it != ctx->framebuffState.framebuffList.end())
  742. {
  743. //Unbind if bound to GL_FRAMEBUFFER
  744. if(framebuffers[i] == ctx->framebuffState.framebuffBinding)
  745. {
  746. ctx->framebuffState.framebuffBinding = 0;
  747. }
  748. ctx->framebuffState.framebuffList.erase(it);
  749. ctx->framebuffState.framebuffNames.removeName(framebuffers[i]);
  750. }
  751. }
  752. }
  753. GL_API void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers)
  754. {
  755. GET_GL_STATE(ctx);
  756. if((n==0) || (framebuffers == 0))
  757. {
  758. return;
  759. }
  760. ctx->framebuffState.framebuffNames.genNames(n, framebuffers);
  761. }
  762. GL_API GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
  763. {
  764. GET_GL_STATE(ctx);
  765. if(GL_FRAMEBUFFER != target)
  766. {
  767. set_err(GL_INVALID_ENUM);
  768. return (GLenum)0;
  769. }
  770. if(ctx->framebuffState.framebuffBinding == 0)
  771. {
  772. //TOOD: spec ambiguity should an error be raised?
  773. return (GLenum)0;
  774. }
  775. FramebufferObject* fbo =0;
  776. if(!ctx->framebuffState.getFBO(ctx->framebuffState.framebuffBinding, &fbo))
  777. {
  778. gAssert(false && "Invalid fbo bound as current!\n");
  779. return (GLenum)0;
  780. }
  781. return fbo->status();
  782. }
  783. GL_API void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
  784. {
  785. //Note: texture completeness is not required here since we are only concerned with the level of the texture
  786. GET_GL_STATE(ctx);
  787. if((target != GL_FRAMEBUFFER)||(!isValidFBAttachment(attachment)))
  788. {
  789. set_err(GL_INVALID_ENUM);
  790. return;
  791. }
  792. if( (ctx->framebuffState.framebuffBinding == 0))
  793. {
  794. set_err(GL_INVALID_OPERATION);
  795. }
  796. FramebufferObject* fbo =0;
  797. if(!ctx->framebuffState.getFBO(ctx->framebuffState.framebuffBinding, &fbo))
  798. {
  799. gAssert(false && "Invalid fbo bound as current!\n");
  800. return;
  801. }
  802. FBOAttachmentPointState* att = fbo->getAttachment(attachment);
  803. if(!att)
  804. {
  805. gAssert(false && "Attachment pointer is null!\n");
  806. return;
  807. }
  808. if(texture==0)
  809. {
  810. att->setDefaults();
  811. return;
  812. }
  813. TextureObject* texObj = GetTexObject(texture);
  814. //If tex object is a valid object
  815. if(texObj == 0)
  816. {
  817. set_err(GL_INVALID_VALUE);
  818. return;
  819. }
  820. if(texObj->texType == GL_TEXTURE_2D)
  821. {
  822. if(textarget != GL_TEXTURE_2D)
  823. {
  824. set_err(GL_INVALID_OPERATION);
  825. return;
  826. }
  827. }
  828. else if(texObj->texType == GL_TEXTURE_CUBE_MAP)
  829. {
  830. switch(textarget)
  831. {
  832. case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  833. case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  834. case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  835. case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  836. case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  837. case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  838. break;
  839. default:
  840. set_err(GL_INVALID_OPERATION);
  841. return;
  842. }
  843. }
  844. else
  845. {
  846. set_err(GL_INVALID_OPERATION);
  847. return;
  848. }
  849. if(level != 0)
  850. {
  851. set_err(GL_INVALID_VALUE);
  852. return;
  853. }
  854. att->setDefaults();
  855. att->objectType = GL_TEXTURE;
  856. att->objectName = texture;
  857. att->textureLevel = level;
  858. if(texObj->texType == GL_TEXTURE_CUBE_MAP)
  859. {
  860. att->textureCubeMapFace = textarget;
  861. }
  862. }
  863. //TODO: This is not supported
  864. GL_API void GL_APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
  865. {
  866. //LOGMSG("glFramebufferTexture3D not implemented");
  867. }
  868. GL_API void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
  869. {
  870. GET_GL_STATE(ctx);
  871. if((target != GL_FRAMEBUFFER)||(!isValidFBAttachment(attachment)))
  872. {
  873. set_err(GL_INVALID_ENUM);
  874. return;
  875. }
  876. if( (ctx->framebuffState.framebuffBinding == 0))
  877. {
  878. set_err(GL_INVALID_OPERATION);
  879. }
  880. FramebufferObject* fbo =0;
  881. if(!ctx->framebuffState.getFBO(ctx->framebuffState.framebuffBinding, &fbo))
  882. {
  883. gAssert(false && "Invalid fbo bound as current!\n");
  884. return;
  885. }
  886. FBOAttachmentPointState* att = fbo->getAttachment(attachment);
  887. if(!att)
  888. {
  889. gAssert(false && "Attachment pointer is null!\n");
  890. return;
  891. }
  892. if(renderbuffer == 0)
  893. {
  894. att->setDefaults();
  895. return;
  896. }
  897. RenderbufferObject* rbo =0;
  898. //Spec: If <renderbuffer> is zero, then the value of <renderbuffertarget> is
  899. //ignored.
  900. if(renderbuffertarget != GL_RENDERBUFFER)
  901. {
  902. set_err(GL_INVALID_ENUM);
  903. return;
  904. }
  905. if(!ctx->renderbuffState.getRBO(renderbuffer, &rbo))
  906. {
  907. set_err(GL_INVALID_OPERATION);
  908. return;
  909. }
  910. att->setDefaults();
  911. att->objectType = GL_RENDERBUFFER;
  912. att->objectName = renderbuffer;
  913. }
  914. //may be to be renamed as GetFramebufferParameteriv as this is present in ESSpec
  915. // but not updated in new gl.h
  916. GL_API void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)
  917. {
  918. GET_GL_STATE(ctx);
  919. GLuint index=0;
  920. if(target != GL_FRAMEBUFFER)
  921. {
  922. set_err(GL_INVALID_ENUM);
  923. return;
  924. }
  925. if(ctx->framebuffState.framebuffBinding == 0)
  926. {
  927. set_err(GL_INVALID_OPERATION);
  928. return;
  929. }
  930. if(!isValidFBAttachment(attachment))
  931. {
  932. set_err(GL_INVALID_ENUM);
  933. return;
  934. }
  935. if(!params)
  936. {
  937. return;
  938. }
  939. FBOMap::iterator it = ctx->framebuffState.framebuffList.find(ctx->framebuffState.framebuffBinding);
  940. if(it == ctx->framebuffState.framebuffList.end())
  941. {
  942. //LOGMSG("Current framebuffer is not valid: %d!\n",ctx->framebuffState.framebuffBinding );
  943. gAssert(false);
  944. return;
  945. }
  946. FBOAttachmentPointState* att = it->second->getAttachment(attachment);
  947. if(!att)
  948. {
  949. gAssert(false);
  950. return;
  951. }
  952. if(pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
  953. {
  954. *params = att->objectType;
  955. return;
  956. }
  957. if(att->objectType == GL_RENDERBUFFER)
  958. {
  959. if(pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)
  960. {
  961. *params = att->objectName;
  962. return;
  963. }
  964. set_err(GL_INVALID_ENUM);
  965. return;
  966. }
  967. else if(att->objectType == GL_TEXTURE)
  968. {
  969. switch(pname)
  970. {
  971. case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
  972. *params = att->objectName;
  973. return;
  974. case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
  975. *params = att->textureLevel;
  976. return;
  977. case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
  978. //TODO:
  979. //if is cube texture,
  980. //*params = att->textureCubeMapFace;
  981. //else
  982. //*params = 0;
  983. index = GetTexNameArrayIndex(att->objectName,false);
  984. if(GL_TEXTURE_CUBE_MAP == ctx->sharedState->sharedTexState.texObjects[index]->texType)
  985. {
  986. *params = att->textureCubeMapFace;
  987. }
  988. else
  989. {
  990. *params = 0;
  991. }
  992. return;
  993. }
  994. }
  995. set_err(GL_INVALID_ENUM);
  996. return;
  997. }