PageRenderTime 80ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/lib_angle/src/libGLESv2/entry_points_gles_3_0.cpp

https://bitbucket.org/xixs/lua
C++ | 3377 lines | 2818 code | 525 blank | 34 comment | 503 complexity | d2001ff41eb41ce33f10fab375a2b261 MD5 | raw file
Possible License(s): Zlib, BSD-3-Clause, CC0-1.0, GPL-3.0, GPL-2.0, CPL-1.0, MPL-2.0-no-copyleft-exception, LGPL-2.0, LGPL-2.1, LGPL-3.0, 0BSD, Cube

Large files files are truncated, but you can click here to view the full file

  1. //
  2. // Copyright(c) 2014 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. // entry_points_gles_3_0.cpp : Implements the GLES 3.0 entry points.
  7. #include "libGLESv2/entry_points_gles_3_0.h"
  8. #include "libGLESv2/entry_points_gles_2_0_ext.h"
  9. #include "libGLESv2/global_state.h"
  10. #include "libANGLE/formatutils.h"
  11. #include "libANGLE/Buffer.h"
  12. #include "libANGLE/Context.h"
  13. #include "libANGLE/Error.h"
  14. #include "libANGLE/Fence.h"
  15. #include "libANGLE/Framebuffer.h"
  16. #include "libANGLE/Query.h"
  17. #include "libANGLE/VertexArray.h"
  18. #include "libANGLE/validationES.h"
  19. #include "libANGLE/validationES3.h"
  20. #include "libANGLE/queryconversions.h"
  21. #include "common/debug.h"
  22. namespace gl
  23. {
  24. void GL_APIENTRY ReadBuffer(GLenum mode)
  25. {
  26. EVENT("(GLenum mode = 0x%X)", mode);
  27. Context *context = GetValidGlobalContext();
  28. if (context)
  29. {
  30. if (context->getClientVersion() < 3)
  31. {
  32. context->recordError(Error(GL_INVALID_OPERATION));
  33. return;
  34. }
  35. // glReadBuffer
  36. UNIMPLEMENTED();
  37. }
  38. }
  39. void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
  40. {
  41. EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, "
  42. "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
  43. Context *context = GetValidGlobalContext();
  44. if (context)
  45. {
  46. if (context->getClientVersion() < 3)
  47. {
  48. context->recordError(Error(GL_INVALID_OPERATION));
  49. return;
  50. }
  51. // glDrawRangeElements
  52. UNIMPLEMENTED();
  53. }
  54. }
  55. void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
  56. {
  57. EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
  58. "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, "
  59. "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
  60. target, level, internalformat, width, height, depth, border, format, type, pixels);
  61. Context *context = GetValidGlobalContext();
  62. if (context)
  63. {
  64. if (context->getClientVersion() < 3)
  65. {
  66. context->recordError(Error(GL_INVALID_OPERATION));
  67. return;
  68. }
  69. // validateES3TexImageFormat sets the error code if there is an error
  70. if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
  71. 0, 0, 0, width, height, depth, border, format, type, pixels))
  72. {
  73. return;
  74. }
  75. Extents size(width, height, depth);
  76. Texture *texture = context->getTargetTexture(target);
  77. Error error = texture->setImage(target, level, internalformat, size, format, type, context->getState().getUnpackState(),
  78. reinterpret_cast<const uint8_t *>(pixels));
  79. if (error.isError())
  80. {
  81. context->recordError(error);
  82. return;
  83. }
  84. }
  85. }
  86. void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
  87. {
  88. EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
  89. "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
  90. "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
  91. target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
  92. Context *context = GetValidGlobalContext();
  93. if (context)
  94. {
  95. if (context->getClientVersion() < 3)
  96. {
  97. context->recordError(Error(GL_INVALID_OPERATION));
  98. return;
  99. }
  100. // validateES3TexImageFormat sets the error code if there is an error
  101. if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
  102. xoffset, yoffset, zoffset, width, height, depth, 0,
  103. format, type, pixels))
  104. {
  105. return;
  106. }
  107. // Zero sized uploads are valid but no-ops
  108. if (width == 0 || height == 0 || depth == 0)
  109. {
  110. return;
  111. }
  112. Box area(xoffset, yoffset, zoffset, width, height, depth);
  113. Texture *texture = context->getTargetTexture(target);
  114. Error error = texture->setSubImage(target, level, area, format, type, context->getState().getUnpackState(),
  115. reinterpret_cast<const uint8_t *>(pixels));
  116. if (error.isError())
  117. {
  118. context->recordError(error);
  119. return;
  120. }
  121. }
  122. }
  123. void GL_APIENTRY CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
  124. {
  125. EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
  126. "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
  127. target, level, xoffset, yoffset, zoffset, x, y, width, height);
  128. Context *context = GetValidGlobalContext();
  129. if (context)
  130. {
  131. if (context->getClientVersion() < 3)
  132. {
  133. context->recordError(Error(GL_INVALID_OPERATION));
  134. return;
  135. }
  136. if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
  137. x, y, width, height, 0))
  138. {
  139. return;
  140. }
  141. Offset destOffset(xoffset, yoffset, zoffset);
  142. Rectangle sourceArea(x, y, width, height);
  143. const Framebuffer *framebuffer = context->getState().getReadFramebuffer();
  144. Texture *texture = context->getTargetTexture(target);
  145. Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
  146. if (error.isError())
  147. {
  148. context->recordError(error);
  149. return;
  150. }
  151. }
  152. }
  153. void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
  154. {
  155. EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
  156. "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
  157. "const GLvoid* data = 0x%0.8p)",
  158. target, level, internalformat, width, height, depth, border, imageSize, data);
  159. Context *context = GetValidGlobalContext();
  160. if (context)
  161. {
  162. if (context->getClientVersion() < 3)
  163. {
  164. context->recordError(Error(GL_INVALID_OPERATION));
  165. return;
  166. }
  167. const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
  168. if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
  169. {
  170. context->recordError(Error(GL_INVALID_VALUE));
  171. return;
  172. }
  173. // validateES3TexImageFormat sets the error code if there is an error
  174. if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
  175. 0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data))
  176. {
  177. return;
  178. }
  179. Extents size(width, height, depth);
  180. Texture *texture = context->getTargetTexture(target);
  181. Error error = texture->setCompressedImage(target, level, internalformat, size, context->getState().getUnpackState(),
  182. reinterpret_cast<const uint8_t *>(data));
  183. if (error.isError())
  184. {
  185. context->recordError(error);
  186. return;
  187. }
  188. }
  189. }
  190. void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
  191. {
  192. EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
  193. "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
  194. "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
  195. target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
  196. Context *context = GetValidGlobalContext();
  197. if (context)
  198. {
  199. if (context->getClientVersion() < 3)
  200. {
  201. context->recordError(Error(GL_INVALID_OPERATION));
  202. return;
  203. }
  204. const InternalFormat &formatInfo = GetInternalFormatInfo(format);
  205. if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
  206. {
  207. context->recordError(Error(GL_INVALID_VALUE));
  208. return;
  209. }
  210. if (!data)
  211. {
  212. context->recordError(Error(GL_INVALID_VALUE));
  213. return;
  214. }
  215. // validateES3TexImageFormat sets the error code if there is an error
  216. if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
  217. 0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data))
  218. {
  219. return;
  220. }
  221. // Zero sized uploads are valid but no-ops
  222. if (width == 0 || height == 0)
  223. {
  224. return;
  225. }
  226. Box area(xoffset, yoffset, zoffset, width, height, depth);
  227. Texture *texture = context->getTargetTexture(target);
  228. Error error = texture->setCompressedSubImage(target, level, area, format, context->getState().getUnpackState(),
  229. reinterpret_cast<const uint8_t *>(data));
  230. if (error.isError())
  231. {
  232. context->recordError(error);
  233. return;
  234. }
  235. }
  236. }
  237. void GL_APIENTRY GenQueries(GLsizei n, GLuint* ids)
  238. {
  239. EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
  240. Context *context = GetValidGlobalContext();
  241. if (context)
  242. {
  243. if (context->getClientVersion() < 3)
  244. {
  245. context->recordError(Error(GL_INVALID_OPERATION));
  246. return;
  247. }
  248. if (n < 0)
  249. {
  250. context->recordError(Error(GL_INVALID_VALUE));
  251. return;
  252. }
  253. for (GLsizei i = 0; i < n; i++)
  254. {
  255. ids[i] = context->createQuery();
  256. }
  257. }
  258. }
  259. void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint* ids)
  260. {
  261. EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
  262. Context *context = GetValidGlobalContext();
  263. if (context)
  264. {
  265. if (context->getClientVersion() < 3)
  266. {
  267. context->recordError(Error(GL_INVALID_OPERATION));
  268. return;
  269. }
  270. if (n < 0)
  271. {
  272. context->recordError(Error(GL_INVALID_VALUE));
  273. return;
  274. }
  275. for (GLsizei i = 0; i < n; i++)
  276. {
  277. context->deleteQuery(ids[i]);
  278. }
  279. }
  280. }
  281. GLboolean GL_APIENTRY IsQuery(GLuint id)
  282. {
  283. EVENT("(GLuint id = %u)", id);
  284. Context *context = GetValidGlobalContext();
  285. if (context)
  286. {
  287. if (context->getClientVersion() < 3)
  288. {
  289. context->recordError(Error(GL_INVALID_OPERATION));
  290. return GL_FALSE;
  291. }
  292. return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
  293. }
  294. return GL_FALSE;
  295. }
  296. void GL_APIENTRY BeginQuery(GLenum target, GLuint id)
  297. {
  298. EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
  299. Context *context = GetValidGlobalContext();
  300. if (context)
  301. {
  302. if (context->getClientVersion() < 3)
  303. {
  304. context->recordError(Error(GL_INVALID_OPERATION));
  305. return;
  306. }
  307. if (!ValidateBeginQuery(context, target, id))
  308. {
  309. return;
  310. }
  311. Error error = context->beginQuery(target, id);
  312. if (error.isError())
  313. {
  314. context->recordError(error);
  315. return;
  316. }
  317. }
  318. }
  319. void GL_APIENTRY EndQuery(GLenum target)
  320. {
  321. EVENT("(GLenum target = 0x%X)", target);
  322. Context *context = GetValidGlobalContext();
  323. if (context)
  324. {
  325. if (context->getClientVersion() < 3)
  326. {
  327. context->recordError(Error(GL_INVALID_OPERATION));
  328. return;
  329. }
  330. if (!ValidateEndQuery(context, target))
  331. {
  332. return;
  333. }
  334. Error error = context->endQuery(target);
  335. if (error.isError())
  336. {
  337. context->recordError(error);
  338. return;
  339. }
  340. }
  341. }
  342. void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint* params)
  343. {
  344. EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
  345. Context *context = GetValidGlobalContext();
  346. if (context)
  347. {
  348. if (context->getClientVersion() < 3)
  349. {
  350. context->recordError(Error(GL_INVALID_OPERATION));
  351. return;
  352. }
  353. if (!ValidQueryType(context, target))
  354. {
  355. context->recordError(Error(GL_INVALID_ENUM));
  356. return;
  357. }
  358. switch (pname)
  359. {
  360. case GL_CURRENT_QUERY:
  361. params[0] = static_cast<GLint>(context->getState().getActiveQueryId(target));
  362. break;
  363. default:
  364. context->recordError(Error(GL_INVALID_ENUM));
  365. return;
  366. }
  367. }
  368. }
  369. void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
  370. {
  371. EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
  372. Context *context = GetValidGlobalContext();
  373. if (context)
  374. {
  375. if (context->getClientVersion() < 3)
  376. {
  377. context->recordError(Error(GL_INVALID_OPERATION));
  378. return;
  379. }
  380. Query *queryObject = context->getQuery(id, false, GL_NONE);
  381. if (!queryObject)
  382. {
  383. context->recordError(Error(GL_INVALID_OPERATION));
  384. return;
  385. }
  386. if (context->getState().getActiveQueryId(queryObject->getType()) == id)
  387. {
  388. context->recordError(Error(GL_INVALID_OPERATION));
  389. return;
  390. }
  391. switch(pname)
  392. {
  393. case GL_QUERY_RESULT_EXT:
  394. {
  395. Error error = queryObject->getResult(params);
  396. if (error.isError())
  397. {
  398. context->recordError(error);
  399. return;
  400. }
  401. }
  402. break;
  403. case GL_QUERY_RESULT_AVAILABLE_EXT:
  404. {
  405. Error error = queryObject->isResultAvailable(params);
  406. if (error.isError())
  407. {
  408. context->recordError(error);
  409. return;
  410. }
  411. }
  412. break;
  413. default:
  414. context->recordError(Error(GL_INVALID_ENUM));
  415. return;
  416. }
  417. }
  418. }
  419. GLboolean GL_APIENTRY UnmapBuffer(GLenum target)
  420. {
  421. EVENT("(GLenum target = 0x%X)", target);
  422. Context *context = GetValidGlobalContext();
  423. if (context)
  424. {
  425. if (context->getClientVersion() < 3)
  426. {
  427. context->recordError(Error(GL_INVALID_OPERATION));
  428. return GL_FALSE;
  429. }
  430. return UnmapBufferOES(target);
  431. }
  432. return GL_FALSE;
  433. }
  434. void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
  435. {
  436. EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
  437. Context *context = GetValidGlobalContext();
  438. if (context)
  439. {
  440. if (context->getClientVersion() < 3)
  441. {
  442. context->recordError(Error(GL_INVALID_OPERATION));
  443. return;
  444. }
  445. GetBufferPointervOES(target, pname, params);
  446. }
  447. }
  448. void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum* bufs)
  449. {
  450. Context *context = GetValidGlobalContext();
  451. if (context)
  452. {
  453. if (context->getClientVersion() < 3)
  454. {
  455. context->recordError(Error(GL_INVALID_OPERATION));
  456. return;
  457. }
  458. DrawBuffersEXT(n, bufs);
  459. }
  460. }
  461. void GL_APIENTRY UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  462. {
  463. EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
  464. location, count, transpose, value);
  465. Context *context = GetValidGlobalContext();
  466. if (context)
  467. {
  468. if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
  469. {
  470. return;
  471. }
  472. Program *program = context->getState().getProgram();
  473. program->setUniformMatrix2x3fv(location, count, transpose, value);
  474. }
  475. }
  476. void GL_APIENTRY UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  477. {
  478. EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
  479. location, count, transpose, value);
  480. Context *context = GetValidGlobalContext();
  481. if (context)
  482. {
  483. if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
  484. {
  485. return;
  486. }
  487. Program *program = context->getState().getProgram();
  488. program->setUniformMatrix3x2fv(location, count, transpose, value);
  489. }
  490. }
  491. void GL_APIENTRY UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  492. {
  493. EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
  494. location, count, transpose, value);
  495. Context *context = GetValidGlobalContext();
  496. if (context)
  497. {
  498. if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
  499. {
  500. return;
  501. }
  502. Program *program = context->getState().getProgram();
  503. program->setUniformMatrix2x4fv(location, count, transpose, value);
  504. }
  505. }
  506. void GL_APIENTRY UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  507. {
  508. EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
  509. location, count, transpose, value);
  510. Context *context = GetValidGlobalContext();
  511. if (context)
  512. {
  513. if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
  514. {
  515. return;
  516. }
  517. Program *program = context->getState().getProgram();
  518. program->setUniformMatrix4x2fv(location, count, transpose, value);
  519. }
  520. }
  521. void GL_APIENTRY UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  522. {
  523. EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
  524. location, count, transpose, value);
  525. Context *context = GetValidGlobalContext();
  526. if (context)
  527. {
  528. if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
  529. {
  530. return;
  531. }
  532. Program *program = context->getState().getProgram();
  533. program->setUniformMatrix3x4fv(location, count, transpose, value);
  534. }
  535. }
  536. void GL_APIENTRY UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
  537. {
  538. EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
  539. location, count, transpose, value);
  540. Context *context = GetValidGlobalContext();
  541. if (context)
  542. {
  543. if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
  544. {
  545. return;
  546. }
  547. Program *program = context->getState().getProgram();
  548. program->setUniformMatrix4x3fv(location, count, transpose, value);
  549. }
  550. }
  551. void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
  552. {
  553. EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, "
  554. "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
  555. srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
  556. Context *context = GetValidGlobalContext();
  557. if (context)
  558. {
  559. if (context->getClientVersion() < 3)
  560. {
  561. context->recordError(Error(GL_INVALID_OPERATION));
  562. return;
  563. }
  564. if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
  565. dstX0, dstY0, dstX1, dstY1, mask, filter,
  566. false))
  567. {
  568. return;
  569. }
  570. Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
  571. ASSERT(readFramebuffer);
  572. Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
  573. ASSERT(drawFramebuffer);
  574. Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
  575. Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
  576. Error error = drawFramebuffer->blit(context->getState(), srcArea, dstArea, mask, filter, readFramebuffer);
  577. if (error.isError())
  578. {
  579. context->recordError(error);
  580. return;
  581. }
  582. }
  583. }
  584. void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
  585. {
  586. EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
  587. target, samples, internalformat, width, height);
  588. Context *context = GetValidGlobalContext();
  589. if (context)
  590. {
  591. if (context->getClientVersion() < 3)
  592. {
  593. context->recordError(Error(GL_INVALID_OPERATION));
  594. return;
  595. }
  596. if (!ValidateES3RenderbufferStorageParameters(context, target, samples, internalformat, width, height))
  597. {
  598. return;
  599. }
  600. Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
  601. renderbuffer->setStorage(width, height, internalformat, samples);
  602. }
  603. }
  604. void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
  605. {
  606. EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)",
  607. target, attachment, texture, level, layer);
  608. Context *context = GetValidGlobalContext();
  609. if (context)
  610. {
  611. if (!ValidateFramebufferTextureLayer(context, target, attachment, texture,
  612. level, layer))
  613. {
  614. return;
  615. }
  616. Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
  617. ASSERT(framebuffer);
  618. if (texture != 0)
  619. {
  620. Texture *textureObject = context->getTexture(texture);
  621. ImageIndex index = ImageIndex::MakeInvalid();
  622. if (textureObject->getTarget() == GL_TEXTURE_3D)
  623. {
  624. index = ImageIndex::Make3D(level, layer);
  625. }
  626. else
  627. {
  628. ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
  629. index = ImageIndex::Make2DArray(level, layer);
  630. }
  631. framebuffer->setTextureAttachment(attachment, textureObject, index);
  632. }
  633. else
  634. {
  635. framebuffer->setNULLAttachment(attachment);
  636. }
  637. }
  638. }
  639. GLvoid *GL_APIENTRY MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
  640. {
  641. EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
  642. target, offset, length, access);
  643. Context *context = GetValidGlobalContext();
  644. if (context)
  645. {
  646. if (context->getClientVersion() < 3)
  647. {
  648. context->recordError(Error(GL_INVALID_OPERATION));
  649. return NULL;
  650. }
  651. return MapBufferRangeEXT(target, offset, length, access);
  652. }
  653. return NULL;
  654. }
  655. void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
  656. {
  657. EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
  658. Context *context = GetValidGlobalContext();
  659. if (context)
  660. {
  661. if (context->getClientVersion() < 3)
  662. {
  663. context->recordError(Error(GL_INVALID_OPERATION));
  664. return;
  665. }
  666. FlushMappedBufferRangeEXT(target, offset, length);
  667. }
  668. }
  669. void GL_APIENTRY BindVertexArray(GLuint array)
  670. {
  671. EVENT("(GLuint array = %u)", array);
  672. Context *context = GetValidGlobalContext();
  673. if (context)
  674. {
  675. if (context->getClientVersion() < 3)
  676. {
  677. context->recordError(Error(GL_INVALID_OPERATION));
  678. return;
  679. }
  680. VertexArray *vao = context->getVertexArray(array);
  681. if (!vao)
  682. {
  683. // The default VAO should always exist
  684. ASSERT(array != 0);
  685. context->recordError(Error(GL_INVALID_OPERATION));
  686. return;
  687. }
  688. context->bindVertexArray(array);
  689. }
  690. }
  691. void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays)
  692. {
  693. EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
  694. Context *context = GetValidGlobalContext();
  695. if (context)
  696. {
  697. if (context->getClientVersion() < 3)
  698. {
  699. context->recordError(Error(GL_INVALID_OPERATION));
  700. return;
  701. }
  702. if (n < 0)
  703. {
  704. context->recordError(Error(GL_INVALID_VALUE));
  705. return;
  706. }
  707. for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
  708. {
  709. if (arrays[arrayIndex] != 0)
  710. {
  711. context->deleteVertexArray(arrays[arrayIndex]);
  712. }
  713. }
  714. }
  715. }
  716. void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays)
  717. {
  718. EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
  719. Context *context = GetValidGlobalContext();
  720. if (context)
  721. {
  722. if (context->getClientVersion() < 3)
  723. {
  724. context->recordError(Error(GL_INVALID_OPERATION));
  725. return;
  726. }
  727. if (n < 0)
  728. {
  729. context->recordError(Error(GL_INVALID_VALUE));
  730. return;
  731. }
  732. for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
  733. {
  734. arrays[arrayIndex] = context->createVertexArray();
  735. }
  736. }
  737. }
  738. GLboolean GL_APIENTRY IsVertexArray(GLuint array)
  739. {
  740. EVENT("(GLuint array = %u)", array);
  741. Context *context = GetValidGlobalContext();
  742. if (context)
  743. {
  744. if (context->getClientVersion() < 3)
  745. {
  746. context->recordError(Error(GL_INVALID_OPERATION));
  747. return GL_FALSE;
  748. }
  749. if (array == 0)
  750. {
  751. return GL_FALSE;
  752. }
  753. VertexArray *vao = context->getVertexArray(array);
  754. return (vao != NULL ? GL_TRUE : GL_FALSE);
  755. }
  756. return GL_FALSE;
  757. }
  758. void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint* data)
  759. {
  760. EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)",
  761. target, index, data);
  762. Context *context = GetValidGlobalContext();
  763. if (context)
  764. {
  765. if (context->getClientVersion() < 3)
  766. {
  767. context->recordError(Error(GL_INVALID_OPERATION));
  768. return;
  769. }
  770. const Caps &caps = context->getCaps();
  771. switch (target)
  772. {
  773. case GL_TRANSFORM_FEEDBACK_BUFFER_START:
  774. case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
  775. case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
  776. if (index >= caps.maxTransformFeedbackSeparateAttributes)
  777. {
  778. context->recordError(Error(GL_INVALID_VALUE));
  779. return;
  780. }
  781. break;
  782. case GL_UNIFORM_BUFFER_START:
  783. case GL_UNIFORM_BUFFER_SIZE:
  784. case GL_UNIFORM_BUFFER_BINDING:
  785. if (index >= caps.maxCombinedUniformBlocks)
  786. {
  787. context->recordError(Error(GL_INVALID_VALUE));
  788. return;
  789. }
  790. break;
  791. default:
  792. context->recordError(Error(GL_INVALID_ENUM));
  793. return;
  794. }
  795. if (!(context->getIndexedIntegerv(target, index, data)))
  796. {
  797. GLenum nativeType;
  798. unsigned int numParams = 0;
  799. if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
  800. {
  801. context->recordError(Error(GL_INVALID_ENUM));
  802. return;
  803. }
  804. if (numParams == 0)
  805. {
  806. return; // it is known that pname is valid, but there are no parameters to return
  807. }
  808. if (nativeType == GL_INT_64_ANGLEX)
  809. {
  810. GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min());
  811. GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max());
  812. GLint64 *int64Params = new GLint64[numParams];
  813. context->getIndexedInteger64v(target, index, int64Params);
  814. for (unsigned int i = 0; i < numParams; ++i)
  815. {
  816. GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue);
  817. data[i] = static_cast<GLint>(clampedValue);
  818. }
  819. delete [] int64Params;
  820. }
  821. else
  822. {
  823. UNREACHABLE();
  824. }
  825. }
  826. }
  827. }
  828. void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode)
  829. {
  830. EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
  831. Context *context = GetValidGlobalContext();
  832. if (context)
  833. {
  834. if (context->getClientVersion() < 3)
  835. {
  836. context->recordError(Error(GL_INVALID_OPERATION));
  837. return;
  838. }
  839. switch (primitiveMode)
  840. {
  841. case GL_TRIANGLES:
  842. case GL_LINES:
  843. case GL_POINTS:
  844. break;
  845. default:
  846. context->recordError(Error(GL_INVALID_ENUM));
  847. return;
  848. }
  849. TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
  850. ASSERT(transformFeedback != NULL);
  851. if (transformFeedback->isStarted())
  852. {
  853. context->recordError(Error(GL_INVALID_OPERATION));
  854. return;
  855. }
  856. if (transformFeedback->isPaused())
  857. {
  858. transformFeedback->resume();
  859. }
  860. else
  861. {
  862. transformFeedback->start(primitiveMode);
  863. }
  864. }
  865. }
  866. void GL_APIENTRY EndTransformFeedback(void)
  867. {
  868. EVENT("(void)");
  869. Context *context = GetValidGlobalContext();
  870. if (context)
  871. {
  872. if (context->getClientVersion() < 3)
  873. {
  874. context->recordError(Error(GL_INVALID_OPERATION));
  875. return;
  876. }
  877. TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
  878. ASSERT(transformFeedback != NULL);
  879. if (!transformFeedback->isStarted())
  880. {
  881. context->recordError(Error(GL_INVALID_OPERATION));
  882. return;
  883. }
  884. transformFeedback->stop();
  885. }
  886. }
  887. void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
  888. {
  889. EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)",
  890. target, index, buffer, offset, size);
  891. Context *context = GetValidGlobalContext();
  892. if (context)
  893. {
  894. if (context->getClientVersion() < 3)
  895. {
  896. context->recordError(Error(GL_INVALID_OPERATION));
  897. return;
  898. }
  899. const Caps &caps = context->getCaps();
  900. switch (target)
  901. {
  902. case GL_TRANSFORM_FEEDBACK_BUFFER:
  903. if (index >= caps.maxTransformFeedbackSeparateAttributes)
  904. {
  905. context->recordError(Error(GL_INVALID_VALUE));
  906. return;
  907. }
  908. break;
  909. case GL_UNIFORM_BUFFER:
  910. if (index >= caps.maxUniformBufferBindings)
  911. {
  912. context->recordError(Error(GL_INVALID_VALUE));
  913. return;
  914. }
  915. break;
  916. default:
  917. context->recordError(Error(GL_INVALID_ENUM));
  918. return;
  919. }
  920. if (buffer != 0 && size <= 0)
  921. {
  922. context->recordError(Error(GL_INVALID_VALUE));
  923. return;
  924. }
  925. switch (target)
  926. {
  927. case GL_TRANSFORM_FEEDBACK_BUFFER:
  928. {
  929. // size and offset must be a multiple of 4
  930. if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
  931. {
  932. context->recordError(Error(GL_INVALID_VALUE));
  933. return;
  934. }
  935. // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2)
  936. TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
  937. if (curTransformFeedback && curTransformFeedback->isStarted())
  938. {
  939. context->recordError(Error(GL_INVALID_OPERATION));
  940. return;
  941. }
  942. context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
  943. context->bindGenericTransformFeedbackBuffer(buffer);
  944. break;
  945. }
  946. case GL_UNIFORM_BUFFER:
  947. // it is an error to bind an offset not a multiple of the alignment
  948. if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
  949. {
  950. context->recordError(Error(GL_INVALID_VALUE));
  951. return;
  952. }
  953. context->bindIndexedUniformBuffer(buffer, index, offset, size);
  954. context->bindGenericUniformBuffer(buffer);
  955. break;
  956. default:
  957. UNREACHABLE();
  958. }
  959. }
  960. }
  961. void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer)
  962. {
  963. EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)",
  964. target, index, buffer);
  965. Context *context = GetValidGlobalContext();
  966. if (context)
  967. {
  968. if (context->getClientVersion() < 3)
  969. {
  970. context->recordError(Error(GL_INVALID_OPERATION));
  971. return;
  972. }
  973. const Caps &caps = context->getCaps();
  974. switch (target)
  975. {
  976. case GL_TRANSFORM_FEEDBACK_BUFFER:
  977. if (index >= caps.maxTransformFeedbackSeparateAttributes)
  978. {
  979. context->recordError(Error(GL_INVALID_VALUE));
  980. return;
  981. }
  982. break;
  983. case GL_UNIFORM_BUFFER:
  984. if (index >= caps.maxUniformBufferBindings)
  985. {
  986. context->recordError(Error(GL_INVALID_VALUE));
  987. return;
  988. }
  989. break;
  990. default:
  991. context->recordError(Error(GL_INVALID_ENUM));
  992. return;
  993. }
  994. switch (target)
  995. {
  996. case GL_TRANSFORM_FEEDBACK_BUFFER:
  997. {
  998. // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2)
  999. TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
  1000. if (curTransformFeedback && curTransformFeedback->isStarted())
  1001. {
  1002. context->recordError(Error(GL_INVALID_OPERATION));
  1003. return;
  1004. }
  1005. context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
  1006. context->bindGenericTransformFeedbackBuffer(buffer);
  1007. break;
  1008. }
  1009. case GL_UNIFORM_BUFFER:
  1010. context->bindIndexedUniformBuffer(buffer, index, 0, 0);
  1011. context->bindGenericUniformBuffer(buffer);
  1012. break;
  1013. default:
  1014. UNREACHABLE();
  1015. }
  1016. }
  1017. }
  1018. void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
  1019. {
  1020. EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)",
  1021. program, count, varyings, bufferMode);
  1022. Context *context = GetValidGlobalContext();
  1023. if (context)
  1024. {
  1025. if (context->getClientVersion() < 3)
  1026. {
  1027. context->recordError(Error(GL_INVALID_OPERATION));
  1028. return;
  1029. }
  1030. if (count < 0)
  1031. {
  1032. context->recordError(Error(GL_INVALID_VALUE));
  1033. return;
  1034. }
  1035. const Caps &caps = context->getCaps();
  1036. switch (bufferMode)
  1037. {
  1038. case GL_INTERLEAVED_ATTRIBS:
  1039. break;
  1040. case GL_SEPARATE_ATTRIBS:
  1041. if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
  1042. {
  1043. context->recordError(Error(GL_INVALID_VALUE));
  1044. return;
  1045. }
  1046. break;
  1047. default:
  1048. context->recordError(Error(GL_INVALID_ENUM));
  1049. return;
  1050. }
  1051. if (!ValidProgram(context, program))
  1052. {
  1053. return;
  1054. }
  1055. Program *programObject = context->getProgram(program);
  1056. ASSERT(programObject);
  1057. programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
  1058. }
  1059. }
  1060. void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
  1061. {
  1062. EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, "
  1063. "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
  1064. program, index, bufSize, length, size, type, name);
  1065. Context *context = GetValidGlobalContext();
  1066. if (context)
  1067. {
  1068. if (context->getClientVersion() < 3)
  1069. {
  1070. context->recordError(Error(GL_INVALID_OPERATION));
  1071. return;
  1072. }
  1073. if (bufSize < 0)
  1074. {
  1075. context->recordError(Error(GL_INVALID_VALUE));
  1076. return;
  1077. }
  1078. if (!ValidProgram(context, program))
  1079. {
  1080. return;
  1081. }
  1082. Program *programObject = context->getProgram(program);
  1083. ASSERT(programObject);
  1084. if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
  1085. {
  1086. context->recordError(Error(GL_INVALID_VALUE));
  1087. return;
  1088. }
  1089. programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
  1090. }
  1091. }
  1092. void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
  1093. {
  1094. EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)",
  1095. index, size, type, stride, pointer);
  1096. Context *context = GetValidGlobalContext();
  1097. if (context)
  1098. {
  1099. if (context->getClientVersion() < 3)
  1100. {
  1101. context->recordError(Error(GL_INVALID_OPERATION));
  1102. return;
  1103. }
  1104. if (index >= MAX_VERTEX_ATTRIBS)
  1105. {
  1106. context->recordError(Error(GL_INVALID_VALUE));
  1107. return;
  1108. }
  1109. if (size < 1 || size > 4)
  1110. {
  1111. context->recordError(Error(GL_INVALID_VALUE));
  1112. return;
  1113. }
  1114. switch (type)
  1115. {
  1116. case GL_BYTE:
  1117. case GL_UNSIGNED_BYTE:
  1118. case GL_SHORT:
  1119. case GL_UNSIGNED_SHORT:
  1120. case GL_INT:
  1121. case GL_UNSIGNED_INT:
  1122. case GL_INT_2_10_10_10_REV:
  1123. case GL_UNSIGNED_INT_2_10_10_10_REV:
  1124. break;
  1125. default:
  1126. context->recordError(Error(GL_INVALID_ENUM));
  1127. return;
  1128. }
  1129. if (stride < 0)
  1130. {
  1131. context->recordError(Error(GL_INVALID_VALUE));
  1132. return;
  1133. }
  1134. if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
  1135. {
  1136. context->recordError(Error(GL_INVALID_OPERATION));
  1137. return;
  1138. }
  1139. // [OpenGL ES 3.0.2] Section 2.8 page 24:
  1140. // An INVALID_OPERATION error is generated when a non-zero vertex array object
  1141. // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
  1142. // and the pointer argument is not NULL.
  1143. if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && pointer != NULL)
  1144. {
  1145. context->recordError(Error(GL_INVALID_OPERATION));
  1146. return;
  1147. }
  1148. context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, false, true,
  1149. stride, pointer);
  1150. }
  1151. }
  1152. void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
  1153. {
  1154. EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
  1155. index, pname, params);
  1156. Context *context = GetValidGlobalContext();
  1157. if (context)
  1158. {
  1159. if (context->getClientVersion() < 3)
  1160. {
  1161. context->recordError(Error(GL_INVALID_OPERATION));
  1162. return;
  1163. }
  1164. if (index >= MAX_VERTEX_ATTRIBS)
  1165. {
  1166. context->recordError(Error(GL_INVALID_VALUE));
  1167. return;
  1168. }
  1169. const VertexAttribute &attribState = context->getState().getVertexAttribState(index);
  1170. if (!ValidateGetVertexAttribParameters(context, pname))
  1171. {
  1172. return;
  1173. }
  1174. if (pname == GL_CURRENT_VERTEX_ATTRIB)
  1175. {
  1176. const VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
  1177. for (int i = 0; i < 4; ++i)
  1178. {
  1179. params[i] = currentValueData.IntValues[i];
  1180. }
  1181. }
  1182. else
  1183. {
  1184. *params = QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
  1185. }
  1186. }
  1187. }
  1188. void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
  1189. {
  1190. EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)",
  1191. index, pname, params);
  1192. Context *context = GetValidGlobalContext();
  1193. if (context)
  1194. {
  1195. if (context->getClientVersion() < 3)
  1196. {
  1197. context->recordError(Error(GL_INVALID_OPERATION));
  1198. return;
  1199. }
  1200. if (index >= MAX_VERTEX_ATTRIBS)
  1201. {
  1202. context->recordError(Error(GL_INVALID_VALUE));
  1203. return;
  1204. }
  1205. const VertexAttribute &attribState = context->getState().getVertexAttribState(index);
  1206. if (!ValidateGetVertexAttribParameters(context, pname))
  1207. {
  1208. return;
  1209. }
  1210. if (pname == GL_CURRENT_VERTEX_ATTRIB)
  1211. {
  1212. const VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
  1213. for (int i = 0; i < 4; ++i)
  1214. {
  1215. params[i] = currentValueData.UnsignedIntValues[i];
  1216. }
  1217. }
  1218. else
  1219. {
  1220. *params = QuerySingleVertexAttributeParameter<GLuint>(attribState, pname);
  1221. }
  1222. }
  1223. }
  1224. void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
  1225. {
  1226. EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
  1227. index, x, y, z, w);
  1228. Context *context = GetValidGlobalContext();
  1229. if (context)
  1230. {
  1231. if (context->getClientVersion() < 3)
  1232. {
  1233. context->recordError(Error(GL_INVALID_OPERATION));
  1234. return;
  1235. }
  1236. if (index >= MAX_VERTEX_ATTRIBS)
  1237. {
  1238. context->recordError(Error(GL_INVALID_VALUE));
  1239. return;
  1240. }
  1241. GLint vals[4] = { x, y, z, w };
  1242. context->getState().setVertexAttribi(index, vals);
  1243. }
  1244. }
  1245. void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
  1246. {
  1247. EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)",
  1248. index, x, y, z, w);
  1249. Context *context = GetValidGlobalContext();
  1250. if (context)
  1251. {
  1252. if (context->getClientVersion() < 3)
  1253. {
  1254. context->recordError(Error(GL_INVALID_OPERATION));
  1255. return;
  1256. }
  1257. if (index >= MAX_VERTEX_ATTRIBS)
  1258. {
  1259. context->recordError(Error(GL_INVALID_VALUE));
  1260. return;
  1261. }
  1262. GLuint vals[4] = { x, y, z, w };
  1263. context->getState().setVertexAttribu(index, vals);
  1264. }
  1265. }
  1266. void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint* v)
  1267. {
  1268. EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
  1269. Context *context = GetValidGlobalContext();
  1270. if (context)
  1271. {
  1272. if (context->getClientVersion() < 3)
  1273. {
  1274. context->recordError(Error(GL_INVALID_OPERATION));
  1275. return;
  1276. }
  1277. if (index >= MAX_VERTEX_ATTRIBS)
  1278. {
  1279. context->recordError(Error(GL_INVALID_VALUE));
  1280. return;
  1281. }
  1282. context->getState().setVertexAttribi(index, v);
  1283. }
  1284. }
  1285. void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint* v)
  1286. {
  1287. EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
  1288. Context *context = GetValidGlobalContext();
  1289. if (context)
  1290. {
  1291. if (context->getClientVersion() < 3)
  1292. {
  1293. context->recordError(Error(GL_INVALID_OPERATION));
  1294. return;
  1295. }
  1296. if (index >= MAX_VERTEX_ATTRIBS)
  1297. {
  1298. context->recordError(Error(GL_INVALID_VALUE));
  1299. return;
  1300. }
  1301. context->getState().setVertexAttribu(index, v);
  1302. }
  1303. }
  1304. void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint* params)
  1305. {
  1306. EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)",
  1307. program, location, params);
  1308. Context *context = GetValidGlobalContext();
  1309. if (context)
  1310. {
  1311. if (!ValidateGetUniformuiv(context, program, location, params))
  1312. {
  1313. return;
  1314. }
  1315. Program *programObject = context->getProgram(program);
  1316. ASSERT(programObject);
  1317. programObject->getUniformuiv(location, params);
  1318. }
  1319. }
  1320. GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name)
  1321. {
  1322. EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)",
  1323. program, name);
  1324. Context *context = GetValidGlobalContext();
  1325. if (context)
  1326. {
  1327. if (context->getClientVersion() < 3)
  1328. {
  1329. context->recordError(Error(GL_INVALID_OPERATION));
  1330. return -1;
  1331. }
  1332. if (program == 0)
  1333. {
  1334. context->recordError(Error(GL_INVALID_VALUE));
  1335. return -1;
  1336. }
  1337. Program *programObject = context->getProgram(program);
  1338. if (!programObject || !programObject->isLinked())
  1339. {
  1340. context->recordError(Error(GL_INVALID_OPERATION));
  1341. return -1;
  1342. }
  1343. return programObject->getFragDataLocation(name);
  1344. }
  1345. return 0;
  1346. }
  1347. void GL_APIENTRY Uniform1ui(GLint location, GLuint v0)
  1348. {
  1349. Uniform1uiv(location, 1, &v0);
  1350. }
  1351. void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1)
  1352. {
  1353. const GLuint xy[] = { v0, v1 };
  1354. Uniform2uiv(location, 1, xy);
  1355. }
  1356. void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
  1357. {
  1358. const GLuint xyz[] = { v0, v1, v2 };
  1359. Uniform3uiv(location, 1, xyz);
  1360. }
  1361. void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
  1362. {
  1363. const GLuint xyzw[] = { v0, v1, v2, v3 };
  1364. Uniform4uiv(location, 1, xyzw);
  1365. }
  1366. void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint* value)
  1367. {
  1368. EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
  1369. location, count, value);
  1370. Context *context = GetValidGlobalContext();
  1371. if (context)
  1372. {
  1373. if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
  1374. {
  1375. return;
  1376. }
  1377. Program *program = context->getState().getProgram();
  1378. program->setUniform1uiv(location, count, value);
  1379. }
  1380. }
  1381. void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint* value)
  1382. {
  1383. EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
  1384. location, count, value);
  1385. Context *context = GetValidGlobalContext();
  1386. if (context)
  1387. {
  1388. if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
  1389. {
  1390. return;
  1391. }
  1392. Program *program = context->getState().getProgram();
  1393. program->setUniform2uiv(location, count, value);
  1394. }
  1395. }
  1396. void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint* value)
  1397. {
  1398. EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)",
  1399. location, count, value);
  1400. Context *context = GetValidGlobalContext();
  1401. if (context)
  1402. {
  1403. if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
  1404. {

Large files files are truncated, but you can click here to view the full file