5#include <QOffscreenSurface>
6#include <QOpenGLContext>
7#include <QtCore/qmap.h>
8#include <QtGui/private/qopenglextensions_p.h>
9#include <QtGui/private/qopenglprogrambinarycache_p.h>
10#include <QtGui/private/qwindow_p.h>
11#include <qpa/qplatformopenglcontext.h>
156#define GL_BGRA 0x80E1
176#define GL_RG16 0x822C
184#define GL_RGBA8 0x8058
188#define GL_RGBA32F 0x8814
192#define GL_RGBA16F 0x881A
196#define GL_R16F 0x822D
200#define GL_R32F 0x822E
204#define GL_HALF_FLOAT 0x140B
207#ifndef GL_DEPTH_COMPONENT16
208#define GL_DEPTH_COMPONENT16 0x81A5
211#ifndef GL_DEPTH_COMPONENT24
212#define GL_DEPTH_COMPONENT24 0x81A6
215#ifndef GL_DEPTH_COMPONENT32F
216#define GL_DEPTH_COMPONENT32F 0x8CAC
219#ifndef GL_UNSIGNED_INT_24_8
220#define GL_UNSIGNED_INT_24_8 0x84FA
223#ifndef GL_STENCIL_INDEX
224#define GL_STENCIL_INDEX 0x1901
227#ifndef GL_STENCIL_INDEX8
228#define GL_STENCIL_INDEX8 0x8D48
231#ifndef GL_DEPTH24_STENCIL8
232#define GL_DEPTH24_STENCIL8 0x88F0
235#ifndef GL_DEPTH_STENCIL_ATTACHMENT
236#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
239#ifndef GL_DEPTH_STENCIL
240#define GL_DEPTH_STENCIL 0x84F9
243#ifndef GL_PRIMITIVE_RESTART_FIXED_INDEX
244#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
247#ifndef GL_FRAMEBUFFER_SRGB
248#define GL_FRAMEBUFFER_SRGB 0x8DB9
251#ifndef GL_READ_FRAMEBUFFER
252#define GL_READ_FRAMEBUFFER 0x8CA8
255#ifndef GL_DRAW_FRAMEBUFFER
256#define GL_DRAW_FRAMEBUFFER 0x8CA9
259#ifndef GL_MAX_DRAW_BUFFERS
260#define GL_MAX_DRAW_BUFFERS 0x8824
263#ifndef GL_TEXTURE_COMPARE_MODE
264#define GL_TEXTURE_COMPARE_MODE 0x884C
267#ifndef GL_COMPARE_REF_TO_TEXTURE
268#define GL_COMPARE_REF_TO_TEXTURE 0x884E
271#ifndef GL_TEXTURE_COMPARE_FUNC
272#define GL_TEXTURE_COMPARE_FUNC 0x884D
275#ifndef GL_MAX_SAMPLES
276#define GL_MAX_SAMPLES 0x8D57
279#ifndef GL_SHADER_STORAGE_BUFFER
280#define GL_SHADER_STORAGE_BUFFER 0x90D2
284#define GL_READ_ONLY 0x88B8
288#define GL_WRITE_ONLY 0x88B9
292#define GL_READ_WRITE 0x88BA
295#ifndef GL_COMPUTE_SHADER
296#define GL_COMPUTE_SHADER 0x91B9
299#ifndef GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT
300#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
303#ifndef GL_ELEMENT_ARRAY_BARRIER_BIT
304#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
307#ifndef GL_UNIFORM_BARRIER_BIT
308#define GL_UNIFORM_BARRIER_BIT 0x00000004
311#ifndef GL_BUFFER_UPDATE_BARRIER_BIT
312#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
315#ifndef GL_SHADER_STORAGE_BARRIER_BIT
316#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
319#ifndef GL_TEXTURE_FETCH_BARRIER_BIT
320#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
323#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
324#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
327#ifndef GL_PIXEL_BUFFER_BARRIER_BIT
328#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
331#ifndef GL_TEXTURE_UPDATE_BARRIER_BIT
332#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
335#ifndef GL_FRAMEBUFFER_BARRIER_BIT
336#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
339#ifndef GL_ALL_BARRIER_BITS
340#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
343#ifndef GL_VERTEX_PROGRAM_POINT_SIZE
344#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
347#ifndef GL_POINT_SPRITE
348#define GL_POINT_SPRITE 0x8861
351#ifndef GL_MAP_READ_BIT
352#define GL_MAP_READ_BIT 0x0001
355#ifndef GL_MAP_WRITE_BIT
356#define GL_MAP_WRITE_BIT 0x0002
359#ifndef GL_TEXTURE_2D_MULTISAMPLE
360#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
363#ifndef GL_TEXTURE_2D_MULTISAMPLE_ARRAY
364#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
367#ifndef GL_TEXTURE_EXTERNAL_OES
368#define GL_TEXTURE_EXTERNAL_OES 0x8D65
371#ifndef GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS
372#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
375#ifndef GL_MAX_COMPUTE_WORK_GROUP_COUNT
376#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
379#ifndef GL_MAX_COMPUTE_WORK_GROUP_SIZE
380#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
383#ifndef GL_TEXTURE_CUBE_MAP_SEAMLESS
384#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
387#ifndef GL_CONTEXT_LOST
388#define GL_CONTEXT_LOST 0x0507
391#ifndef GL_PROGRAM_BINARY_LENGTH
392#define GL_PROGRAM_BINARY_LENGTH 0x8741
395#ifndef GL_NUM_PROGRAM_BINARY_FORMATS
396#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
399#ifndef GL_UNPACK_ROW_LENGTH
400#define GL_UNPACK_ROW_LENGTH 0x0CF2
404#define GL_TEXTURE_3D 0x806F
407#ifndef GL_TEXTURE_WRAP_R
408#define GL_TEXTURE_WRAP_R 0x8072
411#ifndef GL_TEXTURE_RECTANGLE
412#define GL_TEXTURE_RECTANGLE 0x84F5
415#ifndef GL_TEXTURE_2D_ARRAY
416#define GL_TEXTURE_2D_ARRAY 0x8C1A
419#ifndef GL_MAX_ARRAY_TEXTURE_LAYERS
420#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
423#ifndef GL_MAX_VERTEX_UNIFORM_COMPONENTS
424#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
427#ifndef GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
428#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
431#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
432#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
435#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
436#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
440#define GL_RGB10_A2 0x8059
443#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
444#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
447#ifndef GL_MAX_VARYING_COMPONENTS
448#define GL_MAX_VARYING_COMPONENTS 0x8B4B
451#ifndef GL_MAX_VARYING_FLOATS
452#define GL_MAX_VARYING_FLOATS 0x8B4B
455#ifndef GL_MAX_VARYING_VECTORS
456#define GL_MAX_VARYING_VECTORS 0x8DFC
459#ifndef GL_TESS_CONTROL_SHADER
460#define GL_TESS_CONTROL_SHADER 0x8E88
463#ifndef GL_TESS_EVALUATION_SHADER
464#define GL_TESS_EVALUATION_SHADER 0x8E87
467#ifndef GL_PATCH_VERTICES
468#define GL_PATCH_VERTICES 0x8E72
472#define GL_LINE 0x1B01
476#define GL_FILL 0x1B02
480#define GL_PATCHES 0x000E
483#ifndef GL_GEOMETRY_SHADER
484#define GL_GEOMETRY_SHADER 0x8DD9
488#define GL_BACK_LEFT 0x0402
492#define GL_BACK_RIGHT 0x0403
496# define GL_TEXTURE_1D 0x0DE0
499#ifndef GL_TEXTURE_1D_ARRAY
500# define GL_TEXTURE_1D_ARRAY 0x8C18
504#define GL_HALF_FLOAT 0x140B
507#ifndef GL_MAX_VERTEX_OUTPUT_COMPONENTS
508#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
512#define GL_TIMESTAMP 0x8E28
515#ifndef GL_QUERY_RESULT
516#define GL_QUERY_RESULT 0x8866
519#ifndef GL_QUERY_RESULT_AVAILABLE
520#define GL_QUERY_RESULT_AVAILABLE 0x8867
524#define GL_BUFFER 0x82E0
528#define GL_PROGRAM 0x82E2
536QRhiGles2InitParams::QRhiGles2InitParams()
565 if (tempContext.create())
566 fmt = tempContext.format();
568 qWarning(
"QRhiGles2: Failed to create temporary context");
587 ctx = importDevice->context;
589 qWarning(
"No OpenGL context given, cannot import");
604 if (currentSurface->surfaceClass() ==
QSurface::Window && !currentSurface->surfaceHandle())
607 return currentSurface;
615#if defined(Q_OS_MACOS)
640 if (!
ctx->makeCurrent(surface)) {
641 if (
ctx->isValid()) {
642 qWarning(
"QRhiGles2: Failed to make context current. Expect bad things to happen.");
644 qWarning(
"QRhiGles2: Context is lost.");
658 return srgb ? 0x8C4C : 0x83F0;
660 return srgb ? 0x8C4E : 0x83F2;
662 return srgb ? 0x8C4F : 0x83F3;
665 return srgb ? 0x9275 : 0x9274;
667 return srgb ? 0x9277 : 0x9276;
669 return srgb ? 0x9279 : 0x9278;
672 return srgb ? 0x93D0 : 0x93B0;
674 return srgb ? 0x93D1 : 0x93B1;
676 return srgb ? 0x93D2 : 0x93B2;
678 return srgb ? 0x93D3 : 0x93B3;
680 return srgb ? 0x93D4 : 0x93B4;
682 return srgb ? 0x93D5 : 0x93B5;
684 return srgb ? 0x93D6 : 0x93B6;
686 return srgb ? 0x93D7 : 0x93B7;
688 return srgb ? 0x93D8 : 0x93B8;
690 return srgb ? 0x93D9 : 0x93B9;
692 return srgb ? 0x93DA : 0x93BA;
694 return srgb ? 0x93DB : 0x93BB;
696 return srgb ? 0x93DC : 0x93BC;
698 return srgb ? 0x93DD : 0x93BD;
717 ctx->setShareContext(shareContext);
718 ctx->setScreen(shareContext->screen());
722 if (!
ctx->create()) {
723 qWarning(
"QRhiGles2: Failed to create context");
728 qCDebug(QRHI_LOG_INFO) <<
"Created OpenGL context" <<
ctx->format();
765 glFramebufferTexture1D =
770 const char *vendor =
reinterpret_cast<const char *
>(
f->glGetString(GL_VENDOR));
771 const char *
renderer =
reinterpret_cast<const char *
>(
f->glGetString(GL_RENDERER));
772 const char *version =
reinterpret_cast<const char *
>(
f->glGetString(GL_VERSION));
774 qCDebug(QRHI_LOG_INFO,
"OpenGL VENDOR: %s RENDERER: %s VERSION: %s", vendor,
renderer, version);
787 caps.ctxMajor = actualFormat.majorVersion();
788 caps.ctxMinor = actualFormat.minorVersion();
793 QVarLengthArray<GLint, 16> compressedTextureFormats(
n);
809 std::array<QRhiTexture::Flags, 2> textureVariantFlags;
810 textureVariantFlags[0] = {};
813 for (QRhiTexture::Flags
f : textureVariantFlags) {
820 for (QRhiTexture::Flags
f : textureVariantFlags) {
827 for (QRhiTexture::Flags
f : textureVariantFlags) {
844 f->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &
caps.maxTextureSize);
846 if (!
caps.gles ||
caps.ctxMajor >= 3) {
849 caps.hasDrawBuffersFunc =
true;
854 caps.maxDrawBuffers = 1;
855 caps.hasDrawBuffersFunc =
false;
868 caps.fixedIndexPrimitiveRestart =
caps.ctxMajor >= 3;
870 caps.fixedIndexPrimitiveRestart =
caps.ctxMajor > 4 || (
caps.ctxMajor == 4 &&
caps.ctxMinor >= 3);
872 if (
caps.fixedIndexPrimitiveRestart) {
883 caps.bgraInternalFormat =
caps.bgraExternalFormat &&
caps.gles;
886 caps.floatFormats =
caps.ctxMajor >= 3;
887 caps.rgb10Formats =
caps.ctxMajor >= 3;
888 caps.depthTexture =
caps.ctxMajor >= 3;
891 caps.needsDepthStencilCombinedAttach =
true;
893 caps.needsDepthStencilCombinedAttach =
false;
900 caps.srgbWriteControl =
ctx->hasExtension(
"GL_EXT_framebuffer_sRGB") ||
ctx->hasExtension(
"GL_EXT_sRGB_write_control");
905 caps.uniformBuffers =
caps.ctxMajor >= 3;
907 caps.uniformBuffers =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 1);
914 caps.instancing =
caps.ctxMajor >= 3;
916 caps.instancing =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 3);
918 caps.baseVertex =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 2);
921 caps.compute =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 1);
923 caps.compute =
caps.ctxMajor > 4 || (
caps.ctxMajor == 4 &&
caps.ctxMinor >= 3);
931 caps.maxThreadGroupsPerDimension =
qMin(tgPerDim[0],
qMin(tgPerDim[1], tgPerDim[2]));
938 caps.textureCompareMode =
caps.ctxMajor >= 3;
940 caps.textureCompareMode =
true;
947 caps.nonBaseLevelFramebufferTexture =
caps.ctxMajor >= 3;
949 caps.nonBaseLevelFramebufferTexture =
true;
951 caps.texelFetch =
caps.ctxMajor >= 3;
952 caps.intAttributes =
caps.ctxMajor >= 3;
956 caps.multisampledTexture =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 1);
958 caps.multisampledTexture =
caps.ctxMajor >= 3;
963 caps.programBinary =
caps.ctxMajor >= 3;
965 caps.programBinary =
caps.ctxMajor > 4 || (
caps.ctxMajor == 4 &&
caps.ctxMinor >= 1);
967 if (
caps.programBinary) {
971 caps.programBinary =
false;
974 caps.texture3D =
caps.ctxMajor >= 3;
977 caps.texture1D =
false;
979 caps.texture1D = glTexImage1D && (
caps.ctxMajor >= 2);
982 caps.tessellation =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 2);
984 caps.tessellation =
caps.ctxMajor >= 4;
987 caps.geometryShader =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 2);
989 caps.geometryShader =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 2);
991 if (
caps.ctxMajor >= 3) {
992 GLint maxArraySize = 0;
994 caps.maxTextureArraySize = maxArraySize;
996 caps.maxTextureArraySize = 0;
1003 GLint maxVertexUniformVectors = 0;
1005 GLint maxFragmentUniformVectors = 0;
1007 caps.maxUniformVectors =
qMin(maxVertexUniformVectors, maxFragmentUniformVectors);
1009 GLint maxVertexUniformComponents = 0;
1011 GLint maxFragmentUniformComponents = 0;
1013 caps.maxUniformVectors =
qMin(maxVertexUniformComponents, maxFragmentUniformComponents) / 4;
1020 }
else if (
caps.ctxMajor >= 3) {
1035 if (!
caps.coreProfile)
1042 if (!
caps.gles && (
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 2)))
1050 if (
caps.multiView) {
1051 glFramebufferTextureMultiviewOVR =
1057 caps.timestamps = !
caps.gles && (
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 3));
1058 if (
caps.timestamps) {
1063 if (!glQueryCounter || !glGetQueryObjectui64v)
1064 caps.timestamps =
false;
1069 caps.objectLabel =
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 2);
1071 caps.objectLabel =
caps.ctxMajor > 4 || (
caps.ctxMajor == 4 &&
caps.ctxMinor >= 3);
1072 if (
caps.objectLabel) {
1084 caps.glesMultisampleRenderToTexture =
ctx->hasExtension(
"GL_EXT_multisampled_render_to_texture");
1085 if (
caps.glesMultisampleRenderToTexture) {
1089 caps.glesMultiviewMultisampleRenderToTexture =
ctx->hasExtension(
"GL_OVR_multiview_multisampled_render_to_texture");
1090 if (
caps.glesMultiviewMultisampleRenderToTexture) {
1095 caps.glesMultisampleRenderToTexture =
false;
1096 caps.glesMultiviewMultisampleRenderToTexture =
false;
1099 caps.unpackRowLength = !
caps.gles ||
caps.ctxMajor >= 3;
1116 if (
ofr.tsQueries[0]) {
1117 f->glDeleteQueries(2,
ofr.tsQueries);
1118 ofr.tsQueries[0] =
ofr.tsQueries[1] = 0;
1122 f->glDeleteVertexArrays(1, &
vao);
1144 f->glDeleteBuffers(1, &e.
buffer.buffer);
1150 f->glDeleteTextures(1, &e.
texture.texture);
1172 for (
int i = 1;
i <=
caps.maxSamples;
i *= 2)
1234 *glsizedintformat = *glintformat;
1236 *gltype = GL_UNSIGNED_SHORT;
1240 *glsizedintformat = *glintformat;
1242 *gltype = GL_UNSIGNED_SHORT;
1245 *glintformat =
GL_R8;
1246 *glsizedintformat = *glintformat;
1252 *glsizedintformat = *glintformat;
1258 *glsizedintformat = *glintformat;
1264 *glsizedintformat = *glintformat;
1270 *glsizedintformat = *glintformat;
1276 *glsizedintformat = *glintformat;
1282 *glsizedintformat = *glintformat;
1288 *glsizedintformat = *glintformat;
1294 *glsizedintformat = *glintformat;
1295 *glformat = GL_DEPTH_COMPONENT;
1296 *gltype = GL_UNSIGNED_SHORT;
1300 *glsizedintformat = *glintformat;
1301 *glformat = GL_DEPTH_COMPONENT;
1302 *gltype = GL_UNSIGNED_INT;
1306 *glsizedintformat = *glintformat;
1312 *glsizedintformat = *glintformat;
1313 *glformat = GL_DEPTH_COMPONENT;
1334 return caps.depthTexture;
1337 return caps.depth24;
1340 return caps.depth24 &&
caps.packedDepthStencil;
1343 return caps.bgraExternalFormat;
1346 return caps.r8Format;
1349 return caps.r8Format;
1352 return caps.r16Format;
1355 return caps.r16Format;
1359 return caps.floatFormats;
1363 return caps.floatFormats;
1366 return caps.rgb10Formats;
1379 return caps.multisampledTexture;
1381 return caps.msaaRenderBuffer;
1385 return caps.timestamps;
1387 return caps.instancing;
1391 return caps.fixedIndexPrimitiveRestart;
1397 return caps.npotTextureFull;
1399 return caps.coreProfile;
1401 return caps.elementIndexUint;
1403 return caps.compute;
1405 return !
caps.coreProfile;
1409 return caps.baseVertex;
1415 return !
caps.gles ||
caps.properMapBuffer;
1417 return caps.nonBaseLevelFramebufferTexture;
1419 return caps.texelFetch;
1421 return caps.nonBaseLevelFramebufferTexture;
1423 return caps.intAttributes;
1425 return caps.screenSpaceDerivatives;
1429 return caps.programBinary;
1431 return caps.unpackRowLength;
1435 return caps.texture3D;
1437 return caps.texture3D;
1439 return caps.maxTextureArraySize > 0;
1441 return caps.tessellation;
1443 return caps.geometryShader;
1449 return caps.texture1D;
1451 return caps.texture1D;
1453 return caps.halfAttributes;
1455 return caps.texture1D;
1457 return caps.texture3D;
1459 return caps.multiView &&
caps.maxTextureArraySize > 0;
1465 Q_UNREACHABLE_RETURN(
false);
1475 return caps.maxTextureSize;
1477 return caps.maxDrawBuffers;
1485 return caps.maxThreadGroupsPerDimension;
1487 return caps.maxThreadsPerThreadGroup;
1489 return caps.maxThreadGroupsX;
1491 return caps.maxThreadGroupsY;
1493 return caps.maxThreadGroupsZ;
1497 return int(qMin<qint64>(INT_MAX,
caps.maxUniformVectors *
qint64(16)));
1499 return caps.maxVertexInputs;
1501 return caps.maxVertexOutputs;
1503 Q_UNREACHABLE_RETURN(0);
1574 header.driver[driverStrLen] =
'\0';
1576 const size_t dataOffset =
sizeof(
header);
1585 char *
p =
buf.data() + dataOffset;
1594 memcpy(
p,
key.constData(),
key.size());
1600 memcpy(
p,
data.constData(),
data.size());
1621 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: Invalid blob size (header incomplete)");
1629 if (
header.rhiId != rhiId) {
1630 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: The data is for a different QRhi version or backend (%u, %u)",
1635 if (
header.arch != arch) {
1636 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: Architecture does not match (%u, %u)",
1640 if (
header.programBinaryCount == 0)
1645 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: OpenGL vendor/renderer/version does not match");
1650 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: Invalid blob size (data incomplete)");
1656 const char *
p =
data.constData() + dataOffset;
1682 int sampleCount, QRhiRenderBuffer::Flags
flags,
1689 const QSize &pixelSize,
int depth,
int arraySize,
1690 int sampleCount, QRhiTexture::Flags
flags)
1699 return new QGles2Sampler(
this, magFilter, minFilter, mipmapMode, u,
v,
w);
1703 QRhiTextureRenderTarget::Flags
flags)
1730 if (pipelineChanged) {
1737 cmd.
args.bindGraphicsPipeline.ps = ps;
1742 int dynamicOffsetCount,
1752 srb = gfxPsD->m_shaderResourceBindings;
1754 srb = compPsD->m_shaderResourceBindings;
1760 for (
int i = 0, ie = srbD->m_bindings.size();
i != ie; ++
i) {
1768 for (
int elem = 0; elem <
b->u.stex.count; ++elem) {
1826 if (gfxPsD && (gfxPsD->currentSrb != srb || gfxPsD->currentSrbGeneration != srbD->generation)) {
1828 gfxPsD->currentSrb = srb;
1829 gfxPsD->currentSrbGeneration = srbD->generation;
1830 }
else if (compPsD && (compPsD->currentSrb != srb || compPsD->currentSrbGeneration != srbD->generation)) {
1832 compPsD->currentSrb = srb;
1833 compPsD->currentSrbGeneration = srbD->generation;
1848 cmd.
args.bindShaderResources.maybeGraphicsPs = gfxPsD;
1849 cmd.
args.bindShaderResources.maybeComputePs = compPsD;
1850 cmd.
args.bindShaderResources.srb = srb;
1851 cmd.
args.bindShaderResources.dynamicOffsetCount = 0;
1852 if (srbD->hasDynamicOffset) {
1854 cmd.
args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
1855 uint *
p = cmd.
args.bindShaderResources.dynamicOffsetPairs;
1856 for (
int i = 0;
i < dynamicOffsetCount; ++
i) {
1858 *
p++ =
uint(dynOfs.first);
1859 *
p++ = dynOfs.second;
1862 qWarning(
"Too many dynamic offsets (%d, max is %d)",
1877 for (
int i = 0;
i < bindingCount; ++
i) {
1886 cmd.
args.bindVertexBuffer.buffer = bufD->buffer;
1887 cmd.
args.bindVertexBuffer.offset = ofs;
1888 cmd.
args.bindVertexBuffer.binding = startBinding +
i;
1902 cmd.
args.bindIndexBuffer.buffer = ibufD->buffer;
1903 cmd.
args.bindIndexBuffer.offset = indexOffset;
1918 const std::array<float, 4>
r =
viewport.viewport();
1920 if (
r[2] < 0.0f ||
r[3] < 0.0f)
1925 cmd.
args.viewport.x =
r[0];
1926 cmd.
args.viewport.y =
r[1];
1927 cmd.
args.viewport.w =
r[2];
1928 cmd.
args.viewport.h =
r[3];
1938 const std::array<int, 4>
r = scissor.
scissor();
1940 if (
r[2] < 0 ||
r[3] < 0)
1945 cmd.
args.scissor.x =
r[0];
1946 cmd.
args.scissor.y =
r[1];
1947 cmd.
args.scissor.w =
r[2];
1948 cmd.
args.scissor.h =
r[3];
1958 cmd.
args.blendConstants.r = float(
c.redF());
1959 cmd.
args.blendConstants.g = float(
c.greenF());
1960 cmd.
args.blendConstants.b = float(
c.blueF());
1961 cmd.
args.blendConstants.a = float(
c.alphaF());
1971 cmd.
args.stencilRef.ref = refValue;
1984 cmd.
args.draw.vertexCount = vertexCount;
1985 cmd.
args.draw.firstVertex = firstVertex;
1987 cmd.
args.draw.baseInstance = firstInstance;
1999 cmd.
args.drawIndexed.indexCount = indexCount;
2000 cmd.
args.drawIndexed.firstIndex = firstIndex;
2002 cmd.
args.drawIndexed.baseInstance = firstInstance;
2003 cmd.
args.drawIndexed.baseVertex = vertexOffset;
2043 cmd.
args.beginFrame.timestampQuery = tsQuery;
2045 cmd.
args.endFrame.timestampQuery = tsQuery;
2075 f->glBindVertexArray(0);
2117 ctx->handle()->beginFrame();
2122 swapChainD->cb.resetState();
2124 if (swapChainD->timestamps.active[swapChainD->currentTimestampPairIndex]) {
2125 double elapsedSec = 0;
2126 if (swapChainD->timestamps.tryQueryTimestamps(swapChainD->currentTimestampPairIndex,
this, &elapsedSec))
2127 swapChainD->cb.lastGpuTime = elapsedSec;
2130 GLuint tsStart = swapChainD->timestamps.query[swapChainD->currentTimestampPairIndex * 2];
2131 GLuint tsEnd = swapChainD->timestamps.query[swapChainD->currentTimestampPairIndex * 2 + 1];
2132 const bool recordTimestamps = tsStart && tsEnd && !swapChainD->timestamps.active[swapChainD->currentTimestampPairIndex];
2144 GLuint tsStart = swapChainD->timestamps.query[swapChainD->currentTimestampPairIndex * 2];
2145 GLuint tsEnd = swapChainD->timestamps.query[swapChainD->currentTimestampPairIndex * 2 + 1];
2146 const bool recordTimestamps = tsStart && tsEnd && !swapChainD->timestamps.active[swapChainD->currentTimestampPairIndex];
2147 if (recordTimestamps) {
2148 swapChainD->timestamps.active[swapChainD->currentTimestampPairIndex] =
true;
2160 ctx->swapBuffers(swapChainD->surface);
2166 swapChainD->frameCount += 1;
2169 ctx->handle()->endFrame();
2182 ofr.cbWrapper.resetState();
2185 if (!
ofr.tsQueries[0])
2186 f->glGenQueries(2,
ofr.tsQueries);
2190 *
cb = &
ofr.cbWrapper;
2214 if (
ofr.tsQueries[0]) {
2218 if (timestamps[1] >= timestamps[0]) {
2219 const quint64 nanoseconds = timestamps[1] - timestamps[0];
2220 ofr.cbWrapper.lastGpuTime = nanoseconds / 1000000000.0;
2236 ofr.cbWrapper.resetCommands();
2295 if (
access == prevAccess)
2308 bufD->usageState.access =
access;
2318 if (
access == prevAccess)
2327 texD->usageState.access =
access;
2352 cmd.
args.subImage.target = texD->target;
2353 cmd.
args.subImage.texture = texD->texture;
2354 cmd.
args.subImage.faceTarget = effectiveTarget;
2356 cmd.
args.subImage.dx = dp.x();
2357 cmd.
args.subImage.dy = is1D && isArray ?
layer : dp.y();
2358 cmd.
args.subImage.dz = is3D || isArray ?
layer : 0;
2359 cmd.
args.subImage.w =
size.width();
2360 cmd.
args.subImage.h =
size.height();
2361 cmd.
args.subImage.glformat = texD->glformat;
2362 cmd.
args.subImage.gltype = texD->gltype;
2364 if (dataStride == 0)
2365 dataStride = bytesPerLine;
2367 cmd.
args.subImage.rowStartAlign = (dataStride & 3) ? 1 : 4;
2368 cmd.
args.subImage.rowLength =
caps.unpackRowLength ? (bytesPerPixel ? dataStride / bytesPerPixel : 0) : 0;
2381 if (
caps.unpackRowLength) {
2392 }
else if (!rawData.
isEmpty() && isCompressed) {
2393 const int depth =
qMax(1, texD->m_depth);
2394 const int arraySize =
qMax(0, texD->m_arraySize);
2396 && !texD->zeroInitialized)
2408 byteSize *= arraySize;
2412 cmd.
args.compressedImage.target = texD->target;
2413 cmd.
args.compressedImage.texture = texD->texture;
2414 cmd.
args.compressedImage.faceTarget = effectiveTarget;
2416 cmd.
args.compressedImage.glintformat = texD->glintformat;
2417 cmd.
args.compressedImage.w = texD->m_pixelSize.width();
2418 cmd.
args.compressedImage.h = is1D && isArray ? arraySize : texD->m_pixelSize.height();
2419 cmd.
args.compressedImage.depth = is3D ?
depth : (isArray ? arraySize : 0);
2420 cmd.
args.compressedImage.size = byteSize;
2422 texD->zeroInitialized =
true;
2427 if (texD->specified || texD->zeroInitialized) {
2430 cmd.
args.compressedSubImage.target = texD->target;
2431 cmd.
args.compressedSubImage.texture = texD->texture;
2432 cmd.
args.compressedSubImage.faceTarget = effectiveTarget;
2433 cmd.
args.compressedSubImage.level =
level;
2434 cmd.
args.compressedSubImage.dx = dp.x();
2435 cmd.
args.compressedSubImage.dy = is1D && isArray ?
layer : dp.y();
2436 cmd.
args.compressedSubImage.dz = is3D || isArray ?
layer : 0;
2437 cmd.
args.compressedSubImage.w =
size.width();
2438 cmd.
args.compressedSubImage.h =
size.height();
2439 cmd.
args.compressedSubImage.glintformat = texD->glintformat;
2440 cmd.
args.compressedSubImage.size = rawData.
size();
2445 cmd.
args.compressedImage.target = texD->target;
2446 cmd.
args.compressedImage.texture = texD->texture;
2447 cmd.
args.compressedImage.faceTarget = effectiveTarget;
2449 cmd.
args.compressedImage.glintformat = texD->glintformat;
2450 cmd.
args.compressedImage.w =
size.width();
2451 cmd.
args.compressedImage.h = is1D && isArray ? arraySize :
size.height();
2452 cmd.
args.compressedImage.depth = is3D ?
depth : (isArray ? arraySize : 0);
2453 cmd.
args.compressedImage.size = rawData.
size();
2456 }
else if (!rawData.
isEmpty()) {
2471 for (
int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
2482 cmd.
args.bufferSubData.target = bufD->targetForDataOps;
2483 cmd.
args.bufferSubData.buffer = bufD->buffer;
2498 cmd.
args.bufferSubData.target = bufD->targetForDataOps;
2499 cmd.
args.bufferSubData.buffer = bufD->buffer;
2515 cmd.
args.getBufferSubData.target = bufD->targetForDataOps;
2516 cmd.
args.getBufferSubData.buffer = bufD->buffer;
2523 for (
int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
2533 texD->specified =
true;
2561 cmd.
args.copyTex.srcTarget = srcD->target;
2563 cmd.
args.copyTex.srcTexture = srcD->texture;
2565 cmd.
args.copyTex.srcX =
sp.x();
2566 cmd.
args.copyTex.srcY =
sp.y();
2569 cmd.
args.copyTex.dstTarget = dstD->target;
2571 cmd.
args.copyTex.dstTexture = dstD->texture;
2573 cmd.
args.copyTex.dstX = dp.x();
2577 cmd.
args.copyTex.w = copySize.width();
2578 cmd.
args.copyTex.h = copySize.height();
2586 cmd.
args.readPixels.texture = texD ? texD->texture : 0;
2587 cmd.
args.readPixels.slice3D = -1;
2589 const QSize readImageSize =
q->sizeForMipLevel(u.
rb.
level(), texD->m_pixelSize);
2590 cmd.
args.readPixels.w = readImageSize.width();
2591 cmd.
args.readPixels.h = readImageSize.height();
2592 cmd.
args.readPixels.format = texD->m_format;
2596 cmd.
args.readPixels.readTarget = texD->target;
2610 cmd.
args.genMip.target = texD->target;
2611 cmd.
args.genMip.texture = texD->texture;
2622 return GL_TRIANGLES;
2624 return GL_TRIANGLE_STRIP;
2626 return GL_TRIANGLE_FAN;
2630 return GL_LINE_STRIP;
2636 Q_UNREACHABLE_RETURN(GL_TRIANGLES);
2648 Q_UNREACHABLE_RETURN(GL_BACK);
2660 Q_UNREACHABLE_RETURN(GL_CCW);
2672 return GL_SRC_COLOR;
2674 return GL_ONE_MINUS_SRC_COLOR;
2676 return GL_DST_COLOR;
2678 return GL_ONE_MINUS_DST_COLOR;
2680 return GL_SRC_ALPHA;
2682 return GL_ONE_MINUS_SRC_ALPHA;
2684 return GL_DST_ALPHA;
2686 return GL_ONE_MINUS_DST_ALPHA;
2696 return GL_SRC_ALPHA_SATURATE;
2701 qWarning(
"Unsupported blend factor %d",
f);
2704 Q_UNREACHABLE_RETURN(GL_ZERO);
2746 Q_UNREACHABLE_RETURN(GL_ALWAYS);
2770 Q_UNREACHABLE_RETURN(GL_KEEP);
2782 Q_UNREACHABLE_RETURN(
GL_FILL);
2800 Q_UNREACHABLE_RETURN(GL_LINEAR);
2812 Q_UNREACHABLE_RETURN(GL_LINEAR);
2850 Q_UNREACHABLE_RETURN(GL_NEVER);
2880 u.
access = bufUsage.access;
2911 u.
access = texUsage.access;
2964 state->currentArrayBuffer = 0;
2965 state->currentElementArrayBuffer = 0;
2966 state->lastBindVertexBuffer.buffer = 0;
2979 if (cmd.
args.beginFrame.timestampQuery)
2981 if (
caps.coreProfile) {
2983 f->glGenVertexArrays(1, &
vao);
2984 f->glBindVertexArray(
vao);
2988 if (
state.instancedAttributesUsed) {
2990 if (
state.nonzeroAttribDivisor[
i])
2991 f->glVertexAttribDivisor(
GLuint(
i), 0);
2994 f->glVertexAttribDivisor(
GLuint(
i), 0);
2995 state.instancedAttributesUsed =
false;
2999 if (
state.enabledAttribArrays[
i]) {
3000 f->glDisableVertexAttribArray(
GLuint(
i));
3001 state.enabledAttribArrays[
i] =
false;
3006 f->glBindVertexArray(0);
3007 if (cmd.
args.endFrame.timestampQuery)
3012 f->glBindVertexArray(
vao);
3016 f->glDepthRangef(cmd.
args.viewport.d0, cmd.
args.viewport.d1);
3019 f->glScissor(cmd.
args.scissor.x, cmd.
args.scissor.y, cmd.
args.scissor.w, cmd.
args.scissor.h);
3022 f->glBlendColor(cmd.
args.blendConstants.r, cmd.
args.blendConstants.g, cmd.
args.blendConstants.b, cmd.
args.blendConstants.a);
3029 f->glStencilFuncSeparate(GL_FRONT,
toGlCompareOp(psD->m_stencilFront.compareOp),
ref, psD->m_stencilReadMask);
3030 f->glStencilFuncSeparate(GL_BACK,
toGlCompareOp(psD->m_stencilBack.compareOp),
ref, psD->m_stencilReadMask);
3033 qWarning(
"No graphics pipeline active for setStencilRef; ignored");
3041 if (
state.lastBindVertexBuffer.ps == psD
3042 &&
state.lastBindVertexBuffer.buffer == cmd.
args.bindVertexBuffer.buffer
3043 &&
state.lastBindVertexBuffer.offset == cmd.
args.bindVertexBuffer.offset
3044 &&
state.lastBindVertexBuffer.binding == cmd.
args.bindVertexBuffer.binding)
3051 state.lastBindVertexBuffer.ps = psD;
3052 state.lastBindVertexBuffer.buffer = cmd.
args.bindVertexBuffer.buffer;
3053 state.lastBindVertexBuffer.offset = cmd.
args.bindVertexBuffer.offset;
3054 state.lastBindVertexBuffer.binding = cmd.
args.bindVertexBuffer.binding;
3056 if (cmd.
args.bindVertexBuffer.buffer !=
state.currentArrayBuffer) {
3057 state.currentArrayBuffer = cmd.
args.bindVertexBuffer.buffer;
3061 for (
auto it = psD->m_vertexInputLayout.cbeginAttributes(), itEnd = psD->m_vertexInputLayout.cendAttributes();
3064 const int bindingIdx =
it->binding();
3065 if (bindingIdx != cmd.
args.bindVertexBuffer.binding)
3069 const int stride = int(inputBinding->stride());
3073 switch (
it->format()) {
3106 type = GL_UNSIGNED_INT;
3110 type = GL_UNSIGNED_INT;
3114 type = GL_UNSIGNED_INT;
3118 type = GL_UNSIGNED_INT;
3154 type = GL_UNSIGNED_SHORT;
3158 type = GL_UNSIGNED_SHORT;
3162 type = GL_UNSIGNED_SHORT;
3166 type = GL_UNSIGNED_SHORT;
3189 const int locationIdx =
it->location();
3190 quint32 ofs =
it->offset() + cmd.
args.bindVertexBuffer.offset;
3191 if (
type == GL_UNSIGNED_INT ||
type == GL_INT) {
3192 if (
caps.intAttributes) {
3194 reinterpret_cast<const GLvoid *
>(
quintptr(ofs)));
3196 qWarning(
"Current RHI backend does not support IntAttributes. Check supported features.");
3199 state.enabledAttribArrays[locationIdx] =
true;
3203 reinterpret_cast<const GLvoid *
>(
quintptr(ofs)));
3207 state.enabledAttribArrays[locationIdx] =
true;
3208 f->glEnableVertexAttribArray(
GLuint(locationIdx));
3211 f->glVertexAttribDivisor(
GLuint(locationIdx), inputBinding->instanceStepRate());
3213 state.nonzeroAttribDivisor[locationIdx] =
true;
3215 state.maxUntrackedInstancedAttribute =
qMax(
state.maxUntrackedInstancedAttribute, locationIdx);
3216 state.instancedAttributesUsed =
true;
3218 &&
state.nonzeroAttribDivisor[locationIdx])
3220 && locationIdx <=
state.maxUntrackedInstancedAttribute))
3222 f->glVertexAttribDivisor(
GLuint(locationIdx), 0);
3224 state.nonzeroAttribDivisor[locationIdx] =
false;
3228 qWarning(
"No graphics pipeline active for setVertexInput; ignored");
3233 state.indexType = cmd.
args.bindIndexBuffer.type;
3235 state.indexOffset = cmd.
args.bindIndexBuffer.offset;
3236 if (
state.currentElementArrayBuffer != cmd.
args.bindIndexBuffer.buffer) {
3237 state.currentElementArrayBuffer = cmd.
args.bindIndexBuffer.buffer;
3245 if (cmd.
args.draw.instanceCount == 1 || !
caps.instancing) {
3246 f->glDrawArrays(psD->drawMode,
GLint(cmd.
args.draw.firstVertex),
GLsizei(cmd.
args.draw.vertexCount));
3248 f->glDrawArraysInstanced(psD->drawMode,
GLint(cmd.
args.draw.firstVertex),
GLsizei(cmd.
args.draw.vertexCount),
3252 qWarning(
"No graphics pipeline active for draw; ignored");
3260 const GLvoid *ofs =
reinterpret_cast<const GLvoid *
>(
3262 if (cmd.
args.drawIndexed.instanceCount == 1 || !
caps.instancing) {
3263 if (cmd.
args.drawIndexed.baseVertex != 0 &&
caps.baseVertex) {
3264 f->glDrawElementsBaseVertex(psD->drawMode,
3268 cmd.
args.drawIndexed.baseVertex);
3270 f->glDrawElements(psD->drawMode,
3276 if (cmd.
args.drawIndexed.baseVertex != 0 &&
caps.baseVertex) {
3277 f->glDrawElementsInstancedBaseVertex(psD->drawMode,
3282 cmd.
args.drawIndexed.baseVertex);
3284 f->glDrawElementsInstanced(psD->drawMode,
3292 qWarning(
"No graphics pipeline active for drawIndexed; ignored");
3301 cmd.
args.bindShaderResources.maybeGraphicsPs,
3302 cmd.
args.bindShaderResources.maybeComputePs,
3303 cmd.
args.bindShaderResources.srb,
3304 cmd.
args.bindShaderResources.dynamicOffsetPairs,
3305 cmd.
args.bindShaderResources.dynamicOffsetCount);
3309 QVarLengthArray<GLenum, 8>
bufs;
3310 if (cmd.
args.bindFramebuffer.fbo) {
3312 const int colorAttCount = cmd.
args.bindFramebuffer.colorAttCount;
3314 if (
caps.maxDrawBuffers > 1) {
3315 for (
int i = 1;
i < colorAttCount; ++
i)
3325 if (
caps.hasDrawBuffersFunc)
3326 f->glDrawBuffers(
bufs.count(),
bufs.constData());
3327 if (
caps.srgbWriteControl) {
3328 if (cmd.
args.bindFramebuffer.srgb)
3336 f->glDisable(GL_SCISSOR_TEST);
3337 if (cmd.
args.clear.mask & GL_COLOR_BUFFER_BIT) {
3338 f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3339 f->glClearColor(cmd.
args.clear.c[0], cmd.
args.clear.c[1], cmd.
args.clear.c[2], cmd.
args.clear.c[3]);
3341 if (cmd.
args.clear.mask & GL_DEPTH_BUFFER_BIT) {
3342 f->glDepthMask(GL_TRUE);
3343 f->glClearDepthf(cmd.
args.clear.d);
3345 if (cmd.
args.clear.mask & GL_STENCIL_BUFFER_BIT) {
3346 f->glStencilMask(0xFF);
3349 f->glClear(cmd.
args.clear.mask);
3354 f->glBufferSubData(cmd.
args.bufferSubData.target, cmd.
args.bufferSubData.offset, cmd.
args.bufferSubData.size,
3355 cmd.
args.bufferSubData.data);
3362 if (
caps.properMapBuffer) {
3363 void *
p =
f->glMapBufferRange(cmd.
args.getBufferSubData.target,
3364 cmd.
args.getBufferSubData.offset,
3365 cmd.
args.getBufferSubData.size,
3368 result->data.resize(cmd.
args.getBufferSubData.size);
3369 memcpy(
result->data.data(),
p,
size_t(cmd.
args.getBufferSubData.size));
3370 f->glUnmapBuffer(cmd.
args.getBufferSubData.target);
3374 result->data.resize(cmd.
args.getBufferSubData.size);
3375 f->glGetBufferSubData(cmd.
args.getBufferSubData.target,
3376 cmd.
args.getBufferSubData.offset,
3377 cmd.
args.getBufferSubData.size,
3387 f->glGenFramebuffers(1, &fbo);
3393 cmd.
args.copyTex.srcLevel, cmd.
args.copyTex.srcZ);
3396 cmd.
args.copyTex.srcTarget, cmd.
args.copyTex.srcTexture,
3397 cmd.
args.copyTex.srcLevel);
3400 cmd.
args.copyTex.srcFaceTarget, cmd.
args.copyTex.srcTexture, cmd.
args.copyTex.srcLevel);
3402 f->glBindTexture(cmd.
args.copyTex.dstTarget, cmd.
args.copyTex.dstTexture);
3404 f->glCopyTexSubImage3D(cmd.
args.copyTex.dstTarget, cmd.
args.copyTex.dstLevel,
3405 cmd.
args.copyTex.dstX, cmd.
args.copyTex.dstY, cmd.
args.copyTex.dstZ,
3406 cmd.
args.copyTex.srcX, cmd.
args.copyTex.srcY,
3407 cmd.
args.copyTex.w, cmd.
args.copyTex.h);
3409 glCopyTexSubImage1D(cmd.
args.copyTex.dstTarget, cmd.
args.copyTex.dstLevel,
3410 cmd.
args.copyTex.dstX, cmd.
args.copyTex.srcX,
3411 cmd.
args.copyTex.srcY, cmd.
args.copyTex.w);
3413 f->glCopyTexSubImage2D(cmd.
args.copyTex.dstFaceTarget, cmd.
args.copyTex.dstLevel,
3414 cmd.
args.copyTex.dstX, cmd.
args.copyTex.dstY,
3415 cmd.
args.copyTex.srcX, cmd.
args.copyTex.srcY,
3416 cmd.
args.copyTex.w, cmd.
args.copyTex.h);
3419 f->glDeleteFramebuffers(1, &fbo);
3431 mipLevel = cmd.
args.readPixels.level;
3432 if (mipLevel == 0 ||
caps.nonBaseLevelFramebufferTexture) {
3433 f->glGenFramebuffers(1, &fbo);
3435 if (cmd.
args.readPixels.slice3D >= 0) {
3437 tex, mipLevel, cmd.
args.readPixels.slice3D);
3440 cmd.
args.readPixels.readTarget, tex, mipLevel);
3443 cmd.
args.readPixels.readTarget, tex, mipLevel);
3452 const int h =
result->pixelSize.height();
3453 if (mipLevel == 0 ||
caps.nonBaseLevelFramebufferTexture) {
3461 const quint8 *srcBase =
reinterpret_cast<const quint8 *
>(tmpBuf.constData());
3464 for (
int y = 0;
y <
h; ++
y) {
3468 while (
count-- > 0) {
3469 *
dst++ =
src[componentIndex];
3474 switch (
result->format) {
3510 f->glDeleteFramebuffers(1, &fbo);
3517 f->glBindTexture(cmd.
args.subImage.target, cmd.
args.subImage.texture);
3518 if (cmd.
args.subImage.rowStartAlign != 4)
3519 f->glPixelStorei(GL_UNPACK_ALIGNMENT, cmd.
args.subImage.rowStartAlign);
3520 if (cmd.
args.subImage.rowLength != 0)
3523 f->glTexSubImage3D(cmd.
args.subImage.target, cmd.
args.subImage.level,
3524 cmd.
args.subImage.dx, cmd.
args.subImage.dy, cmd.
args.subImage.dz,
3525 cmd.
args.subImage.w, cmd.
args.subImage.h, 1,
3526 cmd.
args.subImage.glformat, cmd.
args.subImage.gltype,
3527 cmd.
args.subImage.data);
3529 glTexSubImage1D(cmd.
args.subImage.target, cmd.
args.subImage.level,
3530 cmd.
args.subImage.dx, cmd.
args.subImage.w,
3531 cmd.
args.subImage.glformat, cmd.
args.subImage.gltype,
3532 cmd.
args.subImage.data);
3534 f->glTexSubImage2D(cmd.
args.subImage.faceTarget, cmd.
args.subImage.level,
3535 cmd.
args.subImage.dx, cmd.
args.subImage.dy,
3536 cmd.
args.subImage.w, cmd.
args.subImage.h,
3537 cmd.
args.subImage.glformat, cmd.
args.subImage.gltype,
3538 cmd.
args.subImage.data);
3540 if (cmd.
args.subImage.rowStartAlign != 4)
3541 f->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
3542 if (cmd.
args.subImage.rowLength != 0)
3546 f->glBindTexture(cmd.
args.compressedImage.target, cmd.
args.compressedImage.texture);
3548 f->glCompressedTexImage3D(cmd.
args.compressedImage.target, cmd.
args.compressedImage.level,
3549 cmd.
args.compressedImage.glintformat,
3550 cmd.
args.compressedImage.w, cmd.
args.compressedImage.h, cmd.
args.compressedImage.depth,
3551 0, cmd.
args.compressedImage.size, cmd.
args.compressedImage.data);
3553 glCompressedTexImage1D(
3554 cmd.
args.compressedImage.target, cmd.
args.compressedImage.level,
3555 cmd.
args.compressedImage.glintformat, cmd.
args.compressedImage.w, 0,
3556 cmd.
args.compressedImage.size, cmd.
args.compressedImage.data);
3558 f->glCompressedTexImage2D(cmd.
args.compressedImage.faceTarget, cmd.
args.compressedImage.level,
3559 cmd.
args.compressedImage.glintformat,
3560 cmd.
args.compressedImage.w, cmd.
args.compressedImage.h,
3561 0, cmd.
args.compressedImage.size, cmd.
args.compressedImage.data);
3565 f->glBindTexture(cmd.
args.compressedSubImage.target, cmd.
args.compressedSubImage.texture);
3567 f->glCompressedTexSubImage3D(cmd.
args.compressedSubImage.target, cmd.
args.compressedSubImage.level,
3568 cmd.
args.compressedSubImage.dx, cmd.
args.compressedSubImage.dy, cmd.
args.compressedSubImage.dz,
3569 cmd.
args.compressedSubImage.w, cmd.
args.compressedSubImage.h, 1,
3570 cmd.
args.compressedSubImage.glintformat,
3571 cmd.
args.compressedSubImage.size, cmd.
args.compressedSubImage.data);
3573 glCompressedTexSubImage1D(
3574 cmd.
args.compressedSubImage.target, cmd.
args.compressedSubImage.level,
3575 cmd.
args.compressedSubImage.dx, cmd.
args.compressedSubImage.w,
3576 cmd.
args.compressedSubImage.glintformat, cmd.
args.compressedSubImage.size,
3577 cmd.
args.compressedSubImage.data);
3579 f->glCompressedTexSubImage2D(cmd.
args.compressedSubImage.faceTarget, cmd.
args.compressedSubImage.level,
3580 cmd.
args.compressedSubImage.dx, cmd.
args.compressedSubImage.dy,
3581 cmd.
args.compressedSubImage.w, cmd.
args.compressedSubImage.h,
3582 cmd.
args.compressedSubImage.glintformat,
3583 cmd.
args.compressedSubImage.size, cmd.
args.compressedSubImage.data);
3591 f->glDisable(GL_SCISSOR_TEST);
3593 f->glGenFramebuffers(2, fbo);
3595 const bool ds = cmd.
args.blitFromRenderbuffer.isDepthStencil;
3609 cmd.
args.blitFromRenderbuffer.dstTexture,
3610 cmd.
args.blitFromRenderbuffer.dstLevel,
3611 cmd.
args.blitFromRenderbuffer.dstLayer);
3613 cmd.
args.blitFromRenderbuffer.dstTexture,
3614 cmd.
args.blitFromRenderbuffer.dstLevel,
3615 cmd.
args.blitFromRenderbuffer.dstLayer);
3618 cmd.
args.blitFromRenderbuffer.dstTexture,
3619 cmd.
args.blitFromRenderbuffer.dstLevel,
3620 cmd.
args.blitFromRenderbuffer.dstLayer);
3625 cmd.
args.blitFromRenderbuffer.dstTexture, cmd.
args.blitFromRenderbuffer.dstLevel);
3627 cmd.
args.blitFromRenderbuffer.dstTexture, cmd.
args.blitFromRenderbuffer.dstLevel);
3630 cmd.
args.blitFromRenderbuffer.dstTexture, cmd.
args.blitFromRenderbuffer.dstLevel);
3633 f->glBlitFramebuffer(0, 0, cmd.
args.blitFromRenderbuffer.w, cmd.
args.blitFromRenderbuffer.h,
3634 0, 0, cmd.
args.blitFromRenderbuffer.w, cmd.
args.blitFromRenderbuffer.h,
3635 ds ? GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT : GL_COLOR_BUFFER_BIT,
3638 f->glDeleteFramebuffers(2, fbo);
3646 f->glDisable(GL_SCISSOR_TEST);
3648 f->glGenFramebuffers(2, fbo);
3650 const bool ds = cmd.
args.blitFromTexture.isDepthStencil;
3654 cmd.
args.blitFromTexture.srcTexture,
3655 cmd.
args.blitFromTexture.srcLevel,
3656 cmd.
args.blitFromTexture.srcLayer);
3658 cmd.
args.blitFromTexture.srcTexture,
3659 cmd.
args.blitFromTexture.srcLevel,
3660 cmd.
args.blitFromTexture.srcLayer);
3663 cmd.
args.blitFromTexture.srcTexture,
3664 cmd.
args.blitFromTexture.srcLevel,
3665 cmd.
args.blitFromTexture.srcLayer);
3670 cmd.
args.blitFromTexture.srcTexture, cmd.
args.blitFromTexture.srcLevel);
3672 cmd.
args.blitFromTexture.srcTexture, cmd.
args.blitFromTexture.srcLevel);
3675 cmd.
args.blitFromTexture.srcTexture, cmd.
args.blitFromTexture.srcLevel);
3682 cmd.
args.blitFromTexture.dstTexture,
3683 cmd.
args.blitFromTexture.dstLevel,
3684 cmd.
args.blitFromTexture.dstLayer);
3686 cmd.
args.blitFromTexture.dstTexture,
3687 cmd.
args.blitFromTexture.dstLevel,
3688 cmd.
args.blitFromTexture.dstLayer);
3691 cmd.
args.blitFromTexture.dstTexture,
3692 cmd.
args.blitFromTexture.dstLevel,
3693 cmd.
args.blitFromTexture.dstLayer);
3698 cmd.
args.blitFromTexture.dstTexture, cmd.
args.blitFromTexture.dstLevel);
3700 cmd.
args.blitFromTexture.dstTexture, cmd.
args.blitFromTexture.dstLevel);
3703 cmd.
args.blitFromTexture.dstTexture, cmd.
args.blitFromTexture.dstLevel);
3706 f->glBlitFramebuffer(0, 0, cmd.
args.blitFromTexture.w, cmd.
args.blitFromTexture.h,
3707 0, 0, cmd.
args.blitFromTexture.w, cmd.
args.blitFromTexture.h,
3708 ds ? GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT : GL_COLOR_BUFFER_BIT,
3711 f->glDeleteFramebuffers(2, fbo);
3715 f->glBindTexture(cmd.
args.genMip.target, cmd.
args.genMip.texture);
3716 f->glGenerateMipmap(cmd.
args.genMip.target);
3721 f->glUseProgram(psD->program);
3725 f->glDispatchCompute(cmd.
args.dispatch.x, cmd.
args.dispatch.y, cmd.
args.dispatch.z);
3740 for (
auto it = tracker.cbeginBuffers(), itEnd = tracker.cendBuffers();
it != itEnd; ++
it) {
3745 for (
auto it = tracker.cbeginTextures(), itEnd = tracker.cendTextures();
it != itEnd; ++
it) {
3751 f->glMemoryBarrier(barriers);
3756 f->glMemoryBarrier(cmd.
args.barrier.barriers);
3759 if (
caps.gles &&
caps.ctxMajor >= 3) {
3761 cmd.
args.invalidateFramebuffer.attCount,
3762 cmd.
args.invalidateFramebuffer.att);
3769 if (
state.instancedAttributesUsed) {
3771 if (
state.nonzeroAttribDivisor[
i])
3772 f->glVertexAttribDivisor(
GLuint(
i), 0);
3775 f->glVertexAttribDivisor(
GLuint(
i), 0);
3787 state.scissor = scissor;
3789 f->glEnable(GL_SCISSOR_TEST);
3791 f->glDisable(GL_SCISSOR_TEST);
3797 state.cullFace = cullFace;
3798 state.cullMode = cullMode;
3800 f->glEnable(GL_CULL_FACE);
3801 f->glCullFace(cullMode);
3803 f->glDisable(GL_CULL_FACE);
3809 state.frontFace = frontFace;
3810 f->glFrontFace(frontFace);
3815 state.polygonMode = polygonMode;
3816 glPolygonMode(GL_FRONT_AND_BACK, polygonMode);
3819 if (!psD->m_targetBlends.isEmpty()) {
3835 state.colorMask = colorMask;
3836 f->glColorMask(colorMask.
r, colorMask.
g, colorMask.
b, colorMask.
a);
3839 const bool blendEnabled = targetBlend.
enable;
3849 state.blendEnabled = blendEnabled;
3851 state.blend = blend;
3852 f->glEnable(GL_BLEND);
3856 f->glDisable(GL_BLEND);
3862 state.colorMask = colorMask;
3863 f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3865 const bool blendEnabled =
false;
3867 state.blendEnabled = blendEnabled;
3868 f->glDisable(GL_BLEND);
3872 const bool depthTest = psD->m_depthTest;
3874 state.depthTest = depthTest;
3876 f->glEnable(GL_DEPTH_TEST);
3878 f->glDisable(GL_DEPTH_TEST);
3881 const bool depthWrite = psD->m_depthWrite;
3883 state.depthWrite = depthWrite;
3884 f->glDepthMask(depthWrite);
3889 state.depthFunc = depthFunc;
3890 f->glDepthFunc(depthFunc);
3893 const bool stencilTest = psD->m_stencilTest;
3894 const GLuint stencilReadMask = psD->m_stencilReadMask;
3895 const GLuint stencilWriteMask = psD->m_stencilWriteMask;
3910 && (stencilReadMask !=
state.stencilReadMask || stencilWriteMask !=
state.stencilWriteMask
3911 || stencilFront !=
state.stencil[0] || stencilBack !=
state.stencil[1])))
3913 state.stencilTest = stencilTest;
3915 state.stencilReadMask = stencilReadMask;
3916 state.stencilWriteMask = stencilWriteMask;
3917 state.stencil[0] = stencilFront;
3918 state.stencil[1] = stencilBack;
3920 f->glEnable(GL_STENCIL_TEST);
3922 f->glStencilFuncSeparate(GL_FRONT, stencilFront.
func,
state.dynamic.stencilRef, stencilReadMask);
3924 f->glStencilMaskSeparate(GL_FRONT, stencilWriteMask);
3926 f->glStencilFuncSeparate(GL_BACK, stencilBack.
func,
state.dynamic.stencilRef, stencilReadMask);
3928 f->glStencilMaskSeparate(GL_BACK, stencilWriteMask);
3930 f->glDisable(GL_STENCIL_TEST);
3934 const bool polyOffsetFill = psD->m_depthBias != 0 || !
qFuzzyIsNull(psD->m_slopeScaledDepthBias);
3935 const float polyOffsetFactor = psD->m_slopeScaledDepthBias;
3936 const float polyOffsetUnits = psD->m_depthBias;
3938 || polyOffsetFactor !=
state.polyOffsetFactor || polyOffsetUnits !=
state.polyOffsetUnits)
3940 state.polyOffsetFill = polyOffsetFill;
3941 state.polyOffsetFactor = polyOffsetFactor;
3942 state.polyOffsetUnits = polyOffsetUnits;
3943 if (polyOffsetFill) {
3944 f->glPolygonOffset(polyOffsetFactor, polyOffsetUnits);
3945 f->glEnable(GL_POLYGON_OFFSET_FILL);
3947 f->glDisable(GL_POLYGON_OFFSET_FILL);
3952 const float lineWidth = psD->m_lineWidth;
3954 state.lineWidth = lineWidth;
3955 f->glLineWidth(lineWidth);
3960 const int cpCount = psD->m_patchControlPointCount;
3962 state.cpCount = cpCount;
3967 f->glUseProgram(psD->program);
3970template <
typename T>
3973 const T *
p =
reinterpret_cast<const T *
>(
src);
3974 for (
int i = 0;
i < elemCount; ++
i) {
3975 for (
int j = 0;
j < vecSize; ++
j)
3976 dst[vecSize *
i +
j] = *
p++;
3982 void *ps,
uint psGeneration,
int glslLocation,
3983 int *texUnit,
bool *activeTexUnitAltered)
3985 const bool samplerStateValid = texD->samplerState == samplerD->d;
3986 const bool cachedStateInRange = *texUnit < 16;
3987 bool updateTextureBinding =
true;
3988 if (samplerStateValid && cachedStateInRange) {
4000 updateTextureBinding =
false;
4003 if (updateTextureBinding) {
4005 *activeTexUnitAltered =
true;
4006 f->glBindTexture(texD->target, texD->texture);
4007 f->glUniform1i(glslLocation, *texUnit);
4008 if (cachedStateInRange) {
4015 if (!samplerStateValid) {
4016 f->glTexParameteri(texD->target, GL_TEXTURE_MIN_FILTER,
GLint(samplerD->d.glminfilter));
4017 f->glTexParameteri(texD->target, GL_TEXTURE_MAG_FILTER,
GLint(samplerD->d.glmagfilter));
4018 f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_S,
GLint(samplerD->d.glwraps));
4019 f->glTexParameteri(texD->target, GL_TEXTURE_WRAP_T,
GLint(samplerD->d.glwrapt));
4022 if (
caps.textureCompareMode) {
4023 if (samplerD->d.gltexcomparefunc != GL_NEVER) {
4030 texD->samplerState = samplerD->d;
4037 const uint *dynOfsPairs,
int dynOfsCount)
4041 bool activeTexUnitAltered =
false;
4046 QVarLengthArray<data32_t, 256> packedArray;
4051 struct SeparateTexture {
4056 QVarLengthArray<SeparateTexture, 8> separateTextureBindings;
4057 struct SeparateSampler {
4061 QVarLengthArray<SeparateSampler, 4> separateSamplerBindings;
4063 for (
int i = 0, ie = srbD->m_bindings.size();
i != ie; ++
i) {
4069 int viewOffset =
b->u.ubuf.offset;
4070 for (
int j = 0;
j < dynOfsCount; ++
j) {
4071 if (dynOfsPairs[2 *
j] ==
uint(
b->binding)) {
4072 viewOffset = int(dynOfsPairs[2 *
j + 1]);
4077 const char *bufView = bufD->data.constData() + viewOffset;
4079 if (uniform.binding ==
b->binding) {
4082 const void *
src = bufView + uniform.offset;
4085 if (uniform.arrayDim > 0
4097 qWarning(
"Uniform with buffer binding %d, buffer offset %d, type %d is an array, "
4098 "but arrays are only supported for float, vec2, vec3, vec4, int, "
4099 "ivec2, ivec3, ivec4, mat3 and mat4. "
4100 "Only the first element will be set.",
4101 uniform.binding, uniform.offset, uniform.type);
4111 switch (uniform.type) {
4114 const int elemCount = uniform.arrayDim;
4115 if (elemCount < 1) {
4116 const float v = *
reinterpret_cast<const float *
>(
src);
4119 if (thisUniformState.componentCount != 1 || thisUniformState.v[0] !=
v) {
4120 thisUniformState.componentCount = 1;
4121 thisUniformState.v[0] =
v;
4122 f->glUniform1f(uniform.glslLocation,
v);
4125 f->glUniform1f(uniform.glslLocation,
v);
4129 packedArray.resize(elemCount);
4131 f->glUniform1fv(uniform.glslLocation, elemCount, &packedArray.constData()->f);
4137 const int elemCount = uniform.arrayDim;
4138 if (elemCount < 1) {
4139 const float *
v =
reinterpret_cast<const float *
>(
src);
4142 if (thisUniformState.componentCount != 2
4143 || thisUniformState.v[0] !=
v[0]
4144 || thisUniformState.v[1] !=
v[1])
4146 thisUniformState.componentCount = 2;
4147 thisUniformState.v[0] =
v[0];
4148 thisUniformState.v[1] =
v[1];
4149 f->glUniform2fv(uniform.glslLocation, 1,
v);
4152 f->glUniform2fv(uniform.glslLocation, 1,
v);
4155 packedArray.resize(elemCount * 2);
4157 f->glUniform2fv(uniform.glslLocation, elemCount, &packedArray.constData()->f);
4163 const int elemCount = uniform.arrayDim;
4164 if (elemCount < 1) {
4165 const float *
v =
reinterpret_cast<const float *
>(
src);
4168 if (thisUniformState.componentCount != 3
4169 || thisUniformState.v[0] !=
v[0]
4170 || thisUniformState.v[1] !=
v[1]
4171 || thisUniformState.v[2] !=
v[2])
4173 thisUniformState.componentCount = 3;
4174 thisUniformState.v[0] =
v[0];
4175 thisUniformState.v[1] =
v[1];
4176 thisUniformState.v[2] =
v[2];
4177 f->glUniform3fv(uniform.glslLocation, 1,
v);
4180 f->glUniform3fv(uniform.glslLocation, 1,
v);
4183 packedArray.resize(elemCount * 3);
4185 f->glUniform3fv(uniform.glslLocation, elemCount, &packedArray.constData()->f);
4191 const int elemCount = uniform.arrayDim;
4192 if (elemCount < 1) {
4193 const float *
v =
reinterpret_cast<const float *
>(
src);
4196 if (thisUniformState.componentCount != 4
4197 || thisUniformState.v[0] !=
v[0]
4198 || thisUniformState.v[1] !=
v[1]
4199 || thisUniformState.v[2] !=
v[2]
4200 || thisUniformState.v[3] !=
v[3])
4202 thisUniformState.componentCount = 4;
4203 thisUniformState.v[0] =
v[0];
4204 thisUniformState.v[1] =
v[1];
4205 thisUniformState.v[2] =
v[2];
4206 thisUniformState.v[3] =
v[3];
4207 f->glUniform4fv(uniform.glslLocation, 1,
v);
4210 f->glUniform4fv(uniform.glslLocation, 1,
v);
4213 f->glUniform4fv(uniform.glslLocation, elemCount,
reinterpret_cast<const float *
>(
src));
4218 f->glUniformMatrix2fv(uniform.glslLocation, 1, GL_FALSE,
reinterpret_cast<const float *
>(
src));
4222 const int elemCount = uniform.arrayDim;
4223 if (elemCount < 1) {
4226 const float *srcMat =
reinterpret_cast<const float *
>(
src);
4227 memcpy(mat, srcMat, 3 *
sizeof(
float));
4228 memcpy(mat + 3, srcMat + 4, 3 *
sizeof(
float));
4229 memcpy(mat + 6, srcMat + 8, 3 *
sizeof(
float));
4230 f->glUniformMatrix3fv(uniform.glslLocation, 1, GL_FALSE, mat);
4232 packedArray.resize(elemCount * 9);
4234 f->glUniformMatrix3fv(uniform.glslLocation, elemCount, GL_FALSE, &packedArray.constData()->f);
4239 f->glUniformMatrix4fv(uniform.glslLocation,
qMax(1, uniform.arrayDim), GL_FALSE,
reinterpret_cast<const float *
>(
src));
4243 const int elemCount = uniform.arrayDim;
4244 if (elemCount < 1) {
4245 f->glUniform1i(uniform.glslLocation, *
reinterpret_cast<const qint32 *
>(
src));
4247 packedArray.resize(elemCount);
4249 f->glUniform1iv(uniform.glslLocation, elemCount, &packedArray.constData()->i);
4255 const int elemCount = uniform.arrayDim;
4256 if (elemCount < 1) {
4257 f->glUniform2iv(uniform.glslLocation, 1,
reinterpret_cast<const qint32 *
>(
src));
4259 packedArray.resize(elemCount * 2);
4261 f->glUniform2iv(uniform.glslLocation, elemCount, &packedArray.constData()->i);
4267 const int elemCount = uniform.arrayDim;
4268 if (elemCount < 1) {
4269 f->glUniform3iv(uniform.glslLocation, 1,
reinterpret_cast<const qint32 *
>(
src));
4271 packedArray.resize(elemCount * 3);
4273 f->glUniform3iv(uniform.glslLocation, elemCount, &packedArray.constData()->i);
4278 f->glUniform4iv(uniform.glslLocation,
qMax(1, uniform.arrayDim),
reinterpret_cast<const qint32 *
>(
src));
4281 f->glUniform1ui(uniform.glslLocation, *
reinterpret_cast<const quint32 *
>(
src));
4284 f->glUniform2uiv(uniform.glslLocation, 1,
reinterpret_cast<const quint32 *
>(
src));
4287 f->glUniform3uiv(uniform.glslLocation, 1,
reinterpret_cast<const quint32 *
>(
src));
4290 f->glUniform4uiv(uniform.glslLocation, 1,
reinterpret_cast<const quint32 *
>(
src));
4293 f->glUniform1i(uniform.glslLocation, *
reinterpret_cast<const qint32 *
>(
src));
4296 f->glUniform2iv(uniform.glslLocation, 1,
reinterpret_cast<const qint32 *
>(
src));
4299 f->glUniform3iv(uniform.glslLocation, 1,
reinterpret_cast<const qint32 *
>(
src));
4302 f->glUniform4iv(uniform.glslLocation, 1,
reinterpret_cast<const qint32 *
>(
src));
4305 qWarning(
"Uniform with buffer binding %d, buffer offset %d has unsupported type %d",
4306 uniform.binding, uniform.offset, uniform.type);
4319 if (maybeGraphicsPs) {
4320 ps = maybeGraphicsPs;
4323 ps = maybeComputePs;
4326 for (
int elem = 0; elem <
b->u.stex.count; ++elem) {
4330 if (shaderSampler.combinedBinding ==
b->binding) {
4331 const int loc = shaderSampler.glslLocation + elem;
4332 bindCombinedSampler(cbD, texD, samplerD, ps, psGeneration, loc, &texUnit, &activeTexUnitAltered);
4340 for (
int elem = 0; elem <
b->u.stex.count; ++elem) {
4342 separateTextureBindings.append({ texD,
b->binding, elem });
4348 separateSamplerBindings.append({ samplerD,
b->binding });
4363 f->glBindImageTexture(
GLuint(
b->binding), texD->texture,
4365 access, texD->glsizedintformat);
4374 if (
b->u.sbuf.offset == 0 &&
b->u.sbuf.maybeSize == 0)
4378 b->u.sbuf.offset,
b->u.sbuf.maybeSize ?
b->u.sbuf.maybeSize : bufD->m_size);
4387 if (!separateTextureBindings.isEmpty() || !separateSamplerBindings.isEmpty()) {
4392 if (maybeGraphicsPs) {
4393 ps = maybeGraphicsPs;
4396 ps = maybeComputePs;
4400 if (shaderSampler.combinedBinding >= 0)
4402 for (
const SeparateSampler &sepSampler : separateSamplerBindings) {
4403 if (sepSampler.binding != shaderSampler.sbinding)
4405 for (
const SeparateTexture &sepTex : separateTextureBindings) {
4406 if (sepTex.binding != shaderSampler.tbinding)
4408 const int loc = shaderSampler.glslLocation + sepTex.elem;
4410 loc, &texUnit, &activeTexUnitAltered);
4416 if (activeTexUnitAltered)
4428 bool *wantsColorClear,
bool *wantsDsClear)
4442 if (wantsColorClear)
4443 *wantsColorClear = doClearBuffers && doClearColorBuffer;
4445 *wantsDsClear = doClearBuffers;
4446 fbCmd.args.bindFramebuffer.fbo = 0;
4447 fbCmd.args.bindFramebuffer.colorAttCount = 1;
4448 fbCmd.args.bindFramebuffer.stereo = rtD->stereoTarget.has_value();
4449 if (fbCmd.args.bindFramebuffer.stereo)
4450 fbCmd.args.bindFramebuffer.stereoTarget = rtD->stereoTarget.value();
4456 if (wantsColorClear)
4460 fbCmd.args.bindFramebuffer.fbo = rtTex->framebuffer;
4461 fbCmd.args.bindFramebuffer.colorAttCount = rtD->colorAttCount;
4462 fbCmd.args.bindFramebuffer.stereo =
false;
4464 for (
auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments();
4495 fbCmd.args.bindFramebuffer.srgb = rtD->srgbUpdateAndBlend;
4511 const QColor &colorClearValue,
4514 QRhiCommandBuffer::BeginPassFlags
flags)
4519 if (resourceUpdates)
4528 if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QGles2Texture, QGles2RenderBuffer>(rtTex->description(), rtTex->d.currentResIdList))
4532 bool wantsColorClear, wantsDsClear;
4537 clearCmd.args.clear.mask = 0;
4538 if (rtD->colorAttCount && wantsColorClear)
4539 clearCmd.args.clear.mask |= GL_COLOR_BUFFER_BIT;
4540 if (rtD->dsAttCount && wantsDsClear)
4541 clearCmd.args.clear.mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
4542 clearCmd.args.clear.c[0] = float(colorClearValue.redF());
4543 clearCmd.args.clear.c[1] = float(colorClearValue.greenF());
4544 clearCmd.args.clear.c[2] = float(colorClearValue.blueF());
4545 clearCmd.args.clear.c[3] = float(colorClearValue.alphaF());
4546 clearCmd.args.clear.d = depthStencilClearValue.depthClearValue();
4547 clearCmd.args.clear.s = depthStencilClearValue.stencilClearValue();
4563 for (
auto it = rtTex->m_desc.cbeginColorAttachments(), itEnd = rtTex->m_desc.cendColorAttachments();
4571 const QSize size = resolveTexD->pixelSize();
4574 if (rbD->pixelSize() !=
size) {
4575 qWarning(
"Resolve source (%dx%d) and target (%dx%d) size does not match",
4576 rbD->pixelSize().width(), rbD->pixelSize().height(),
size.width(),
size.height());
4580 cmd.
args.blitFromRenderbuffer.renderbuffer = rbD->renderbuffer;
4581 cmd.
args.blitFromRenderbuffer.w =
size.width();
4582 cmd.
args.blitFromRenderbuffer.h =
size.height();
4586 cmd.
args.blitFromRenderbuffer.target = resolveTexD->target;
4587 cmd.
args.blitFromRenderbuffer.dstTexture = resolveTexD->texture;
4591 cmd.
args.blitFromRenderbuffer.dstLayer = hasZ ? colorAtt.
resolveLayer() : 0;
4592 cmd.
args.blitFromRenderbuffer.isDepthStencil =
false;
4593 }
else if (
caps.glesMultisampleRenderToTexture) {
4599 if (texD->pixelSize() !=
size) {
4600 qWarning(
"Resolve source (%dx%d) and target (%dx%d) size does not match",
4601 texD->pixelSize().width(), texD->pixelSize().height(),
size.width(),
size.height());
4604 for (
int resolveIdx = 0; resolveIdx < resolveCount; ++resolveIdx) {
4605 const int srcLayer = colorAtt.
layer() + resolveIdx;
4606 const int dstLayer = colorAtt.
resolveLayer() + resolveIdx;
4612 cmd.
args.blitFromTexture.srcTarget = texD->target;
4613 cmd.
args.blitFromTexture.srcTexture = texD->texture;
4614 cmd.
args.blitFromTexture.srcLevel = colorAtt.
level();
4615 cmd.
args.blitFromTexture.srcLayer = 0;
4617 cmd.
args.blitFromTexture.srcLayer = srcLayer;
4618 cmd.
args.blitFromTexture.w =
size.width();
4619 cmd.
args.blitFromTexture.h =
size.height();
4623 cmd.
args.blitFromTexture.dstTarget = resolveTexD->target;
4624 cmd.
args.blitFromTexture.dstTexture = resolveTexD->texture;
4626 cmd.
args.blitFromTexture.dstLayer = 0;
4628 cmd.
args.blitFromTexture.dstLayer = dstLayer;
4629 cmd.
args.blitFromTexture.isDepthStencil =
false;
4634 if (rtTex->m_desc.depthResolveTexture()) {
4636 const QSize size = depthResolveTexD->pixelSize();
4637 if (rtTex->m_desc.depthStencilBuffer()) {
4641 cmd.
args.blitFromRenderbuffer.renderbuffer = rbD->renderbuffer;
4642 cmd.
args.blitFromRenderbuffer.w =
size.width();
4643 cmd.
args.blitFromRenderbuffer.h =
size.height();
4644 cmd.
args.blitFromRenderbuffer.target = depthResolveTexD->target;
4645 cmd.
args.blitFromRenderbuffer.dstTexture = depthResolveTexD->texture;
4646 cmd.
args.blitFromRenderbuffer.dstLevel = 0;
4647 cmd.
args.blitFromRenderbuffer.dstLayer = 0;
4648 cmd.
args.blitFromRenderbuffer.isDepthStencil =
true;
4649 }
else if (
caps.glesMultisampleRenderToTexture) {
4653 const int resolveCount = depthTexD->arraySize() >= 2 ? depthTexD->arraySize() : 1;
4654 for (
int resolveIdx = 0; resolveIdx < resolveCount; ++resolveIdx) {
4657 cmd.
args.blitFromTexture.srcTarget = depthTexD->target;
4658 cmd.
args.blitFromTexture.srcTexture = depthTexD->texture;
4659 cmd.
args.blitFromTexture.srcLevel = 0;
4660 cmd.
args.blitFromTexture.srcLayer = resolveIdx;
4661 cmd.
args.blitFromTexture.w =
size.width();
4662 cmd.
args.blitFromTexture.h =
size.height();
4663 cmd.
args.blitFromTexture.dstTarget = depthResolveTexD->target;
4664 cmd.
args.blitFromTexture.dstTexture = depthResolveTexD->texture;
4665 cmd.
args.blitFromTexture.dstLevel = 0;
4666 cmd.
args.blitFromTexture.dstLayer = resolveIdx;
4667 cmd.
args.blitFromTexture.isDepthStencil =
true;
4672 const bool mayDiscardDepthStencil =
4673 (rtTex->m_desc.depthStencilBuffer()
4675 && !rtTex->m_desc.depthResolveTexture();
4676 if (mayDiscardDepthStencil) {
4679 if (
caps.needsDepthStencilCombinedAttach) {
4680 cmd.
args.invalidateFramebuffer.attCount = 1;
4683 cmd.
args.invalidateFramebuffer.attCount = 2;
4693 if (resourceUpdates)
4699 QRhiCommandBuffer::BeginPassFlags)
4704 if (resourceUpdates)
4721 if (resourceUpdates)
4732 if (pipelineChanged) {
4739 cmd.
args.bindComputePipeline.ps = ps;
4746 int loadTypeVal,
int storeTypeVal,
int loadStoreTypeVal)
4749 if (bindingType == loadTypeVal) {
4753 if (bindingType == loadStoreTypeVal)
4756 auto it = writtenResources->find(resource);
4757 if (
it != writtenResources->end())
4759 else if (bindingType == storeTypeVal || bindingType == loadStoreTypeVal)
4760 writtenResources->insert(resource, {
access,
true });
4775 accessAndIsNewFlag = { 0,
false };
4778 const int bindingCount = srbD->m_bindings.size();
4779 for (
int i = 0;
i < bindingCount; ++
i) {
4808 const int accessInThisDispatch =
it->first;
4809 const bool isNewInThisDispatch =
it->second;
4810 if (accessInThisDispatch && !isNewInThisDispatch) {
4828 cmd.
args.barrier.barriers = barriers;
4862 QList<int> versionsToTry;
4865 if (
caps.ctxMajor > 3 || (
caps.ctxMajor == 3 &&
caps.ctxMinor >= 2)) {
4866 versionsToTry << 320 << 310 << 300 << 100;
4867 }
else if (
caps.ctxMajor == 3 &&
caps.ctxMinor == 1) {
4868 versionsToTry << 310 << 300 << 100;
4869 }
else if (
caps.ctxMajor == 3 &&
caps.ctxMinor == 0) {
4870 versionsToTry << 300 << 100;
4872 versionsToTry << 100;
4874 for (
int v : versionsToTry) {
4879 *shaderVersion = ver;
4884 if (
caps.ctxMajor > 4 || (
caps.ctxMajor == 4 &&
caps.ctxMinor >= 6)) {
4885 versionsToTry << 460 << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150 << 140 << 130;
4886 }
else if (
caps.ctxMajor == 4 &&
caps.ctxMinor == 5) {
4887 versionsToTry << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150 << 140 << 130;
4888 }
else if (
caps.ctxMajor == 4 &&
caps.ctxMinor == 4) {
4889 versionsToTry << 440 << 430 << 420 << 410 << 400 << 330 << 150 << 140 << 130;
4890 }
else if (
caps.ctxMajor == 4 &&
caps.ctxMinor == 3) {
4891 versionsToTry << 430 << 420 << 410 << 400 << 330 << 150 << 140 << 130;
4892 }
else if (
caps.ctxMajor == 4 &&
caps.ctxMinor == 2) {
4893 versionsToTry << 420 << 410 << 400 << 330 << 150 << 140 << 130;
4894 }
else if (
caps.ctxMajor == 4 &&
caps.ctxMinor == 1) {
4895 versionsToTry << 410 << 400 << 330 << 150 << 140 << 130;
4896 }
else if (
caps.ctxMajor == 4 &&
caps.ctxMinor == 0) {
4897 versionsToTry << 400 << 330 << 150 << 140 << 130;
4898 }
else if (
caps.ctxMajor == 3 &&
caps.ctxMinor == 3) {
4899 versionsToTry << 330 << 150 << 140 << 130;
4900 }
else if (
caps.ctxMajor == 3 &&
caps.ctxMinor == 2) {
4901 versionsToTry << 150 << 140 << 130;
4902 }
else if (
caps.ctxMajor == 3 &&
caps.ctxMinor == 1) {
4903 versionsToTry << 140 << 130;
4904 }
else if (
caps.ctxMajor == 3 &&
caps.ctxMinor == 0) {
4905 versionsToTry << 130;
4907 if (!
caps.coreProfile)
4908 versionsToTry << 120;
4909 for (
int v : versionsToTry) {
4919 qWarning() <<
"No GLSL shader code found (versions tried: " << versionsToTry
4920 <<
") in baked shader" << bakedShader;
4937 const char *srcStr =
source.constData();
4939 f->glShaderSource(
shader, 1, &srcStr, &srcLength);
4944 GLint infoLogLength = 0;
4947 if (infoLogLength > 1) {
4949 log.
resize(infoLogLength);
4975 GLint infoLogLength = 0;
4978 if (infoLogLength > 1) {
4980 log.
resize(infoLogLength);
4994 QDuplicateTracker<int, 256> *activeUniformLocations,
4998 qWarning(
"Nested structs are not supported at the moment. '%s' ignored.",
5010 uniform.glslLocation =
f->glGetUniformLocation(
program,
name.constData());
5011 if (uniform.glslLocation >= 0 && !activeUniformLocations->hasSeen(uniform.glslLocation)) {
5012 if (
var.arrayDims.size() > 1) {
5013 qWarning(
"Array '%s' has more than one dimension. This is not supported.",
5017 uniform.binding = binding;
5018 uniform.offset =
uint(baseOffset +
var.offset);
5019 uniform.size =
var.size;
5020 uniform.arrayDim =
var.arrayDims.isEmpty() ? 0 :
var.arrayDims.first();
5021 dst->append(uniform);
5027 QDuplicateTracker<int, 256> *activeUniformLocations,
5033 QByteArray structPrefix = prefix + blockMember.name;
5035 const int baseOffset = blockMember.offset;
5036 if (blockMember.arrayDims.isEmpty()) {
5039 baseOffset,
program, activeUniformLocations,
dst);
5041 if (blockMember.arrayDims.size() > 1) {
5042 qWarning(
"Array of struct '%s' has more than one dimension. Only the first "
5043 "dimension is used.",
5044 blockMember.name.constData());
5046 const int dim = blockMember.arrayDims.first();
5047 const int elemSize = blockMember.size / dim;
5048 int elemOffset = baseOffset;
5049 for (
int di = 0; di < dim; ++di) {
5053 elemOffset += elemSize;
5068 if (
sampler.glslLocation >= 0) {
5069 sampler.combinedBinding =
v.binding;
5082 if (
sampler.glslLocation >= 0) {
5092 if (!vsDesc.isValid() || !fsDesc.isValid())
5101 if (inVar.location == outVar.location) {
5102 if (inVar.name != outVar.name) {
5103 qWarning(
"Vertex output name '%s' does not match fragment input '%s'. "
5104 "This should be avoided because it causes problems with older GLSL versions.",
5105 outVar.name.constData(), inVar.name.constData());
5144 const QVector<QShaderDescription::InOutVariable> &inputVars,
5156 if (legacyDiskCacheEnabled || pipelineCacheEnabled) {
5158 for (
int i = 0;
i < stageCount; ++
i) {
5181 QMap<QByteArray, int> inputLocations;
5183 inputLocations.insert(
var.name,
var.location);
5185 for (
auto it = inputLocations.
cbegin(),
end = inputLocations.cend();
it !=
end; ++
it) {
5200 if (pipelineCacheEnabled) {
5205 err =
f->glGetError();
5210 err =
f->glGetError();
5211 if (err == GL_NO_ERROR) {
5212 GLint linkStatus = 0;
5214 if (linkStatus == GL_TRUE)
5222 qCDebug(lcOpenGLProgramDiskCache,
"Program binary received from cache, program %u, key %s",
5237 qCDebug(lcOpenGLProgramDiskCache,
"Saving program binary, program %u, key %s",
5255 if (blobSize == outSize)
5284 rhiD->releaseQueue.append(e);
5285 rhiD->unregisterResource(
this);
5300 qWarning(
"Uniform buffer: multiple usages specified, this is not supported by the OpenGL backend");
5307 if (!rhiD->ensureContext())
5316 rhiD->f->glGenBuffers(1, &
buffer);
5320 if (rhiD->glObjectLabel)
5325 rhiD->registerResource(
this);
5334 return { { &
buffer }, 1 };
5343 if (rhiD->caps.properMapBuffer) {
5359 if (rhiD->caps.properMapBuffer)
5367 int sampleCount, QRhiRenderBuffer::Flags
flags,
5395 rhiD->releaseQueue.append(e);
5396 rhiD->unregisterResource(
this);
5412 qWarning(
"RenderBuffer: UsedWithSwapChainOnly is meaningless in combination with Color");
5415 if (!rhiD->ensureContext())
5425 if (rhiD->caps.msaaRenderBuffer &&
samples > 1) {
5429 }
else if (rhiD->caps.packedDepthStencil || rhiD->caps.needsDepthStencilCombinedAttach) {
5435 GLenum depthStorage = GL_DEPTH_COMPONENT;
5436 if (rhiD->caps.gles) {
5437 if (rhiD->caps.depth24)
5454 if (rhiD->caps.rgba8Format) {
5457 GLenum glintformat, glformat, gltype;
5463 if (rhiD->caps.msaaRenderBuffer &&
samples > 1) {
5477 if (rhiD->glObjectLabel)
5482 rhiD->registerResource(
this);
5498 qWarning(
"RenderBuffer: UsedWithSwapChainOnly is meaningless when importing an existing native object");
5500 if (!rhiD->ensureContext())
5507 rhiD->registerResource(
this);
5547 rhiD->releaseQueue.append(e);
5548 rhiD->unregisterResource(
this);
5558 if (!rhiD->ensureContext())
5565 const bool isCompressed = rhiD->isCompressedFormat(
m_format);
5571 if (is3D && !rhiD->caps.texture3D) {
5572 qWarning(
"3D textures are not supported");
5575 if (isCube && is3D) {
5576 qWarning(
"Texture cannot be both cube and 3D");
5579 if (isArray && is3D) {
5580 qWarning(
"Texture cannot be both array and 3D");
5583 if (is1D && !rhiD->caps.texture1D) {
5584 qWarning(
"1D textures are not supported");
5588 qWarning(
"Texture cannot be both 1D and 3D");
5591 if (is1D && isCube) {
5592 qWarning(
"Texture cannot be both 1D and cube");
5597 qWarning(
"Texture cannot have a depth of %d when it is not 3D",
m_depth);
5625 qWarning(
"Compressed texture cannot be used with image load/store");
5630 qWarning(
"Compressed format %d not mappable to GL compressed format",
m_format);
5645 *adjustedSize =
size;
5657 rhiD->f->glGenTextures(1, &
texture);
5663 const bool isCompressed = rhiD->isCompressedFormat(
m_format);
5666 if (!isCompressed) {
5679 }
else if (is3D || isArray) {
5691 }
else if (hasMipMaps || isCube) {
5693 for (
int layer = 0, layerCount = isCube ? 6 : 1;
layer != layerCount; ++
layer) {
5697 mipSize.width(), mipSize.height(), 0,
5707 size.width(),
size.height(), GL_TRUE);
5717 if (is1D && !isArray)
5719 else if (!is1D && (is3D || isArray))
5724 size.width(),
size.height(), GL_TRUE);
5737 if (rhiD->glObjectLabel)
5743 rhiD->registerResource(
this);
5764 rhiD->registerResource(
this);
5775 :
QRhiSampler(rhi, magFilter, minFilter, mipmapMode, u,
v,
w)
5788 rhiD->unregisterResource(
this);
5802 rhiD->registerResource(
this,
false);
5821 rhiD->unregisterResource(
this);
5834 rhiD->registerResource(rpD,
false);
5903 rhiD->releaseQueue.append(e);
5904 rhiD->unregisterResource(
this);
5912 rhiD->registerResource(rpD,
false);
5928 if (hasColorAttachments) {
5930 if (
count > rhiD->caps.maxDrawBuffers) {
5931 qWarning(
"QGles2TextureRenderTarget: Too many color attachments (%d, max is %d)",
5932 count, rhiD->caps.maxDrawBuffers);
5936 qWarning(
"QGles2TextureRenderTarget: Depth texture is not supported and will be ignored");
5938 if (!rhiD->ensureContext())
5946 int multiViewCount = 0;
5955 Q_ASSERT(texD->texture && texD->specified);
5962 if (texD->sampleCount() > 1 && rhiD->caps.glesMultiviewMultisampleRenderToTexture && colorAtt.
resolveTexture()) {
5968 rhiD->glFramebufferTextureMultisampleMultiviewOVR(
GL_FRAMEBUFFER,
5970 resolveTexD->texture,
5972 texD->sampleCount(),
5986 texD->target +
uint(colorAtt.
layer()), texD->texture,
5989 if (texD->sampleCount() > 1 && rhiD->caps.glesMultisampleRenderToTexture && colorAtt.
resolveTexture()) {
5997 resolveTexD->texture, colorAtt.
level(), texD->sampleCount());
6001 texD->texture, colorAtt.
level());
6004 if (attIndex == 0) {
6005 d.
pixelSize = rhiD->q->sizeForMipLevel(colorAtt.
level(), texD->pixelSize());
6008 }
else if (renderBuffer) {
6011 if (attIndex == 0) {
6018 if (hasDepthStencil) {
6021 if (rhiD->caps.needsDepthStencilCombinedAttach) {
6023 depthRbD->renderbuffer);
6026 depthRbD->renderbuffer);
6027 if (depthRbD->stencilRenderbuffer) {
6029 depthRbD->stencilRenderbuffer);
6033 depthRbD->renderbuffer);
6042 if (multiViewCount < 2) {
6049 depthResolveTexD->texture, 0, depthTexD->sampleCount());
6050 if (rhiD->isStencilSupportingFormat(depthResolveTexD->format())) {
6052 depthResolveTexD->texture, 0, depthTexD->sampleCount());
6056 depthTexD->texture, 0);
6057 if (rhiD->isStencilSupportingFormat(depthTexD->format())) {
6059 depthTexD->texture, 0);
6063 if (depthTexD->sampleCount() > 1 && rhiD->caps.glesMultiviewMultisampleRenderToTexture) {
6082 qWarning(
"Attempted to create a multiview+multisample QRhiTextureRenderTarget, but DoNotStoreDepthStencilContents was not set."
6083 " This path has no choice but to behave as if DoNotStoreDepthStencilContents was set, because QRhi is forced to create"
6084 " a throwaway non-multisample depth texture here. Set the flag to silence this warning, or set a depthResolveTexture.");
6088 rhiD->glFramebufferTextureMultisampleMultiviewOVR(
GL_FRAMEBUFFER,
6090 depthResolveTexD->texture,
6092 depthTexD->sampleCount(),
6095 if (rhiD->isStencilSupportingFormat(depthResolveTexD->format())) {
6096 rhiD->glFramebufferTextureMultisampleMultiviewOVR(
GL_FRAMEBUFFER,
6098 depthResolveTexD->texture,
6100 depthTexD->sampleCount(),
6109 depthTexD->pixelSize().width(), depthTexD->pixelSize().height(), multiViewCount);
6111 rhiD->glFramebufferTextureMultisampleMultiviewOVR(
GL_FRAMEBUFFER,
6115 depthTexD->sampleCount(),
6118 rhiD->glFramebufferTextureMultisampleMultiviewOVR(
GL_FRAMEBUFFER,
6122 depthTexD->sampleCount(),
6131 0, 0, multiViewCount);
6132 if (rhiD->isStencilSupportingFormat(depthTexD->format())) {
6134 0, 0, multiViewCount);
6153 qWarning(
"Framebuffer incomplete: 0x%x", status);
6157 if (rhiD->glObjectLabel)
6160 QRhiRenderTargetAttachmentTracker::updateResIdList<QGles2Texture, QGles2RenderBuffer>(
m_desc, &
d.
currentResIdList);
6162 rhiD->registerResource(
this);
6168 if (!QRhiRenderTargetAttachmentTracker::isUpToDate<QGles2Texture, QGles2RenderBuffer>(
m_desc,
d.
currentResIdList))
6198 rhiD->unregisterResource(
this);
6204 if (!rhiD->sanityCheckShaderResourceBindings(
this))
6211 if (
b->u.ubuf.hasDynamicOffset) {
6218 rhiD->updateLayoutDesc(
this);
6221 rhiD->registerResource(
this,
false);
6257 rhiD->releaseQueue.append(e);
6258 rhiD->unregisterResource(
this);
6279 if (!rhiD->ensureContext())
6282 rhiD->pipelineCreationStart();
6283 if (!rhiD->sanityCheckGraphicsPipeline(
this))
6288 program = rhiD->f->glCreateProgram();
6299 switch (shaderStage.type()) {
6313 Q_UNREACHABLE_RETURN(VtxIdx);
6317 bool vertexFragmentOnly =
true;
6320 const int idx = descIdxForStage(shaderStage);
6321 if (idx != VtxIdx && idx != FragIdx)
6322 vertexFragmentOnly =
false;
6325 desc[idx] =
shader.description();
6326 if (!rhiD->shaderSource(shaderStage, &shaderVersion).isEmpty()) {
6327 samplerMappingList[idx] =
shader.separateToCombinedImageSamplerMappingList(
6337 desc[VtxIdx].inputVariables(),
6345 if (!rhiD->compileShader(
program, shaderStage,
nullptr))
6352 rhiD->f->glBindAttribLocation(
program,
GLuint(inVar.location), inVar.name);
6354 if (vertexFragmentOnly)
6355 rhiD->sanityCheckVertexFragmentInterface(desc[VtxIdx], desc[FragIdx]);
6357 if (!rhiD->linkProgram(
program))
6381 QDuplicateTracker<int, 256> activeUniformLocations;
6385 const int idx = descIdxForStage(shaderStage);
6387 rhiD->gatherUniforms(
program, ub, &activeUniformLocations, &
uniforms);
6398 return a.offset < b.offset;
6406 if (rhiD->glObjectLabel)
6409 rhiD->pipelineCreationEnd();
6411 rhiD->registerResource(
this);
6441 rhiD->releaseQueue.append(e);
6442 rhiD->unregisterResource(
this);
6453 if (!rhiD->ensureContext())
6456 rhiD->pipelineCreationStart();
6461 if (!rhiD->shaderSource(
m_shaderStage, &shaderVersion).isEmpty()) {
6466 program = rhiD->f->glCreateProgram();
6477 if (!rhiD->linkProgram(
program))
6498 QDuplicateTracker<int, 256> activeUniformLocations;
6500 rhiD->gatherUniforms(
program, ub, &activeUniformLocations, &
uniforms);
6513 rhiD->pipelineCreationEnd();
6515 rhiD->registerResource(
this);
6553 rhiD->unregisterResource(
this);
6573 Q_UNREACHABLE_RETURN(
nullptr);
6582 return platformWindow->geometry().size() * platformWindow->devicePixelRatio();
6596 rhiD->registerResource(rpD,
false);
6648 if (needsRegistration)
6649 rhiD->registerResource(
this,
false);
6683 rhiD->glGetQueryObjectui64v(tsStart,
GL_QUERY_RESULT, ×tamps[0]);
6686 if (timestamps[1] >= timestamps[0]) {
6687 const quint64 nanoseconds = timestamps[1] - timestamps[0];
6688 *elapsedSec = nanoseconds / 1000000000.0;
6692 active[pairIndex] =
false;
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
The QColor class provides colors based on RGB, HSV or CMYK values.
qsizetype size() const noexcept
Returns the number of items in the hash.
const_iterator constFind(const Key &key) const noexcept
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
bool isNull() const
Returns true if it is a null image, otherwise returns false.
bool isEmpty() const noexcept
void append(parameter_type t)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
void setFormat(const QSurfaceFormat &format)
Sets the offscreen surface format.
QOpenGLContext * shareContext() const
Returns the share context this context was created with.
void setFormat(const QSurfaceFormat &format)
Sets the format the OpenGL context should be compatible with.
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
QScreen * screen() const
Returns the screen the context was created for.
QOpenGLProgramBinarySupportCheck * get(QOpenGLContext *context)
\inmodule QtCore\reentrant
constexpr bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0, otherwise returns false.
const char * constData() const
Type
Specifies storage type of buffer resource.
QRhiRenderBuffer * renderBuffer() const
int multiViewCount() const
QRhiTexture * texture() const
QRhiTexture * resolveTexture() const
@ DoNotTrackResourcesForCompute
QPair< int, quint32 > DynamicOffset
Synonym for QPair<int, quint32>.
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
IndexFormat
Specifies the index data type.
QRhiShaderStage m_shaderStage
\variable QRhiGles2InitParams::format
QHash< QRhiShaderStage, uint > m_shaderCache
QRhiStats statistics() override
void gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub, QDuplicateTracker< int, 256 > *activeUniformLocations, QGles2UniformDescriptionVector *dst)
void registerUniformIfActive(const QShaderDescription::BlockVariable &var, const QByteArray &namePrefix, int binding, int baseOffset, GLuint program, QDuplicateTracker< int, 256 > *activeUniformLocations, QGles2UniformDescriptionVector *dst)
const GLvoid const GLvoid GLuint
void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance) override
QOpenGLContext * maybeShareContext
void trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *bufD, QGles2Buffer::Access access)
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override
void enqueueBarriersForPass(QGles2CommandBuffer *cbD)
QList< DeferredReleaseEntry > releaseQueue
int resourceLimit(QRhi::ResourceLimit limit) const override
void setVertexInput(QRhiCommandBuffer *cb, int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat) override
bool isFeatureSupported(QRhi::Feature feature) const override
QRhiGraphicsPipeline * createGraphicsPipeline() override
void bindShaderResources(QGles2CommandBuffer *cbD, QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs, QRhiShaderResourceBindings *srb, const uint *dynOfsPairs, int dynOfsCount)
bool create(QRhi::Flags flags) override
void trackedRegisterTexture(QRhiPassResourceTracker *passResTracker, QGles2Texture *texD, QRhiPassResourceTracker::TextureAccess access, QRhiPassResourceTracker::TextureStage stage)
void executeBindGraphicsPipeline(QGles2CommandBuffer *cbD, QGles2GraphicsPipeline *psD)
QRhiDriverInfo driverInfo() const override
QSurfaceFormat requestedFormat
QHash< QByteArray, PipelineCacheData > m_pipelineCache
bool isProgramBinaryDiskCacheEnabled() const
bool needsMakeCurrentDueToSwap
void trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Texture::Access access)
void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker, QGles2Buffer *bufD, QRhiPassResourceTracker::BufferAccess access, QRhiPassResourceTracker::BufferStage stage)
QRhiComputePipeline * createComputePipeline() override
QRhiDriverInfo driverInfoStruct
QSurface * evaluateFallbackSurface() const
void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
void sanityCheckVertexFragmentInterface(const QShaderDescription &vsDesc, const QShaderDescription &fsDesc)
QRhiGles2NativeHandles nativeHandlesStruct
QMatrix4x4 clipSpaceCorrMatrix() const override
QRhi::FrameOpResult finish() override
void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override
QList< int > supportedSampleCounts() const override
void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v, QGles2SamplerDescriptionVector *dst)
QSet< GLint > supportedCompressedFormats
QRhiSwapChain * createSwapChain() override
void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override
QRhiRenderBuffer * createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, QRhiRenderBuffer::Flags flags, QRhiTexture::Format backingFormatHint) override
void executeCommandBuffer(QRhiCommandBuffer *cb)
void setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps) override
QSurface * fallbackSurface
QRhiGles2(QRhiGles2InitParams *params, QRhiGles2NativeHandles *importDevice=nullptr)
void trySaveToDiskCache(GLuint program, const QByteArray &cacheKey)
struct QRhiGles2::Caps caps
bool compileShader(GLuint program, const QRhiShaderStage &shaderStage, QShaderVersion *shaderVersion)
QRhiTexture * createTexture(QRhiTexture::Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, QRhiTexture::Flags flags) override
void bindCombinedSampler(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Sampler *samplerD, void *ps, uint psGeneration, int glslLocation, int *texUnit, bool *activeTexUnitAltered)
void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override
QRhiTextureRenderTarget * createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags) override
QRhiSampler * createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w) override
void beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
QGles2SwapChain * currentSwapChain
bool isDeviceLost() const override
QRhiShaderResourceBindings * createShaderResourceBindings() override
bool isYUpInNDC() const override
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override
void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
bool makeThreadLocalNativeContextCurrent() override
int ubufAlignment() const override
void beginExternal(QRhiCommandBuffer *cb) override
void endExternal(QRhiCommandBuffer *cb) override
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override
QByteArray shaderSource(const QRhiShaderStage &shaderStage, QShaderVersion *shaderVersion)
QRhiBuffer * createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size) override
void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override
void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override
bool ensureContext(QSurface *surface=nullptr) const
void draw(QRhiCommandBuffer *cb, quint32 vertexCount, quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override
void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
ProgramCacheResult tryLoadFromDiskOrPipelineCache(const QRhiShaderStage *stages, int stageCount, GLuint program, const QVector< QShaderDescription::InOutVariable > &inputVars, QByteArray *cacheKey)
void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
bool isYUpInFramebuffer() const override
bool linkProgram(GLuint program)
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override
QGles2RenderTargetData * enqueueBindFramebuffer(QRhiRenderTarget *rt, QGles2CommandBuffer *cbD, bool *wantsColorClear=nullptr, bool *wantsDsClear=nullptr)
void debugMarkEnd(QRhiCommandBuffer *cb) override
void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override
void setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb, int dynamicOffsetCount, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override
void releaseCachedResources() override
bool isClipDepthZeroToOne() const override
void trySaveToPipelineCache(GLuint program, const QByteArray &cacheKey, bool force=false)
void executeDeferredReleases()
QByteArray pipelineCacheData() override
double lastCompletedGpuTime(QRhiCommandBuffer *cb) override
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override
QList< int > supportedSampleCountList
QPointer< QWindow > maybeWindow
void enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cbD, int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
struct QRhiGles2::OffscreenFrame ofr
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override
void setPipelineCacheData(const QByteArray &data) override
QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override
void gatherGeneratedSamplers(GLuint program, const QShader::SeparateToCombinedImageSamplerMapping &mapping, QGles2SamplerDescriptionVector *dst)
const QRhiNativeHandles * nativeHandles() override
BlendOp
Specifies the blend operation.
PolygonMode
Specifies the polygon rasterization mode.
FrontFace
Specifies the front face winding order.
BlendFactor
Specifies the blend factor.
CompareOp
Specifies the depth or stencil comparison function.
CullMode
Specifies the culling mode.
QVarLengthArray< QRhiShaderStage, 4 > m_shaderStages
Topology
Specifies the primitive topology.
StencilOp
Specifies the stencil operation.
bool isCompressedFormat(QRhiTexture::Format format) const
static const QRhiShaderResourceBinding::Data * shaderResourceBindingData(const QRhiShaderResourceBinding &binding)
quint32 pipelineCacheRhiId() const
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size, quint32 *bpl, quint32 *byteSize, QSize *blockDim) const
static const int MAX_SHADER_CACHE_ENTRIES
qint64 totalPipelineCreationTime() const
void textureFormatInfo(QRhiTexture::Format format, const QSize &size, quint32 *bpl, quint32 *byteSize, quint32 *bytesPerPixel) const
static TextureStage toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages)
static BufferStage toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages)
QRhiTexture * texture() const
void setPixelSize(const QSize &sz)
Sets the size (in pixels) to sz.
QRhiTexture::Format m_backingFormatHint
Type
Specifies the type of the renderbuffer.
virtual bool create()=0
Creates the corresponding native graphics resources.
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc)
Sets the QRhiRenderPassDescriptor desc for use with this render target.
QRhiRenderPassDescriptor * m_renderPassDesc
static QRhiResourceUpdateBatchPrivate * get(QRhiResourceUpdateBatch *b)
virtual Type resourceType() const =0
QRhiImplementation * m_rhi
Filter
Specifies the minification, magnification, or mipmap filtering.
AddressMode
Specifies the addressing mode.
CompareOp
Specifies the texture comparison function.
std::array< int, 4 > scissor() const
Type
Specifies type of the shader resource bound to a binding point.
QVarLengthArray< QRhiShaderResourceBinding, BINDING_PREALLOC > m_bindings
QShader::Variant shaderVariant() const
Type
Specifies the type of the shader stage.
QRhiRenderPassDescriptor * m_renderPassDesc
Format
Describes the swapchain format.
StereoTargetBuffer
Selects the backbuffer to use with a stereoscopic swapchain.
QRhiRenderBuffer * m_depthStencil
QPoint destinationTopLeft() const
QPoint sourceTopLeft() const
int destinationLevel() const
int destinationLayer() const
const QRhiColorAttachment * cbeginColorAttachments() const
QRhiTexture * depthTexture() const
const QRhiColorAttachment * cendColorAttachments() const
QRhiRenderBuffer * depthStencilBuffer() const
qsizetype colorAttachmentCount() const
QRhiTexture * depthResolveTexture() const
QRhiTextureRenderTargetDescription m_desc
@ DoNotStoreDepthStencilContents
@ PreserveDepthStencilContents
quint32 dataStride() const
QPoint sourceTopLeft() const
QPoint destinationTopLeft() const
Format
Specifies the texture format.
static constexpr int MAX_MIP_LEVELS
ResourceLimit
Describes the resource limit to query.
@ MaxThreadsPerThreadGroup
@ MaxThreadGroupsPerDimension
Feature
Flag values to indicate what features are supported by the backend currently in use.
@ NonDynamicUniformBuffers
@ RenderToNonBaseMipLevel
@ MultisampleRenderBuffer
@ PipelineCacheDataLoadSave
@ ReadBackNonUniformBuffer
@ RenderToOneDimensionalTexture
@ OneDimensionalTextureMipmaps
@ ReadBackNonBaseMipLevel
@ ThreeDimensionalTextureMipmaps
@ NonFourAlignedEffectiveIndexBufferOffset
@ ThreeDimensionalTextures
@ ReadBackAnyTextureFormat
FrameOpResult
Describes the result of operations that can have a soft failure.
@ EnablePipelineCacheDataSave
bool contains(const T &value) const
const_iterator cbegin() const noexcept
iterator insert(const T &value)
SeparateToCombinedImageSamplerMappingList separateToCombinedImageSamplerMappingList(const QShaderKey &key) const
\variable QShader::SeparateToCombinedImageSamplerMapping::combinedSamplerName
QShaderCode shader(const QShaderKey &key) const
QShaderDescription description() const
Stage
Describes the stage of the graphics pipeline the shader is suitable for.
@ TessellationEvaluationStage
@ TessellationControlStage
constexpr int width() const noexcept
Returns the width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
SurfaceClass surfaceClass() const
Returns the surface class of this surface.
virtual QPlatformSurface * surfaceHandle() const =0
Returns a handle to the platform-specific implementation of the surface.
constexpr size_type size() const noexcept
const T & at(qsizetype idx) const
const T * constData() const
iterator begin() noexcept
const void * constData() const
QSurfaceFormat format() const override
Returns the actual format of this window.
QSize size() const override
Returns the size of the window excluding any window frame.
QSet< QString >::iterator it
Combined button and popup list for selecting options.
constexpr Initialization Uninitialized
#define Q_STATIC_ASSERT(Condition)
#define QByteArrayLiteral(str)
static QString header(const QString &name)
static bool isCubeMap(const DDSHeader &dds)
static const qint64 headerSize
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
bool qFuzzyIsNull(qfloat16 f) noexcept
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
static QByteArray cacheKey(Args &&...args)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
#define QOPENGLF_APIENTRYP
QOpenGLContext * qt_gl_global_share_context()
GLboolean GLboolean GLboolean b
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLuint GLint level
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLenum GLint components
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
const void GLsizei GLsizei stride
#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLenum GLuint GLenum GLsizei const GLchar * buf
#define GL_TEXTURE_2D_MULTISAMPLE
GLenum GLuint GLintptr offset
GLsizei GLsizei GLenum * binaryFormat
#define GL_TEXTURE_2D_ARRAY
#define GL_TEXTURE_EXTERNAL_OES
GLint GLsizei GLsizei GLenum format
GLsizei GLenum internalFormat
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
#define GL_NUM_PROGRAM_BINARY_FORMATS
#define GL_MIRRORED_REPEAT
#define GL_TEXTURE_COMPARE_FUNC
#define GL_MAX_VARYING_VECTORS
#define GL_MAX_COMPUTE_WORK_GROUP_COUNT
#define GL_FRAGMENT_SHADER
#define GL_TEXTURE_WRAP_R
#define GL_DEPTH24_STENCIL8
#define GL_DEPTH_COMPONENT16
#define GL_TEXTURE_CUBE_MAP
#define GL_PRIMITIVE_RESTART_FIXED_INDEX
#define GL_ONE_MINUS_CONSTANT_ALPHA
#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
#define GL_COMPRESSED_TEXTURE_FORMATS
#define GL_CONSTANT_COLOR
#define GL_FRAMEBUFFER_SRGB
#define GL_MAX_VERTEX_OUTPUT_COMPONENTS
#define GL_COLOR_ATTACHMENT0
#define GL_DEPTH_STENCIL_ATTACHMENT
#define GL_TEXTURE_CUBE_MAP_SEAMLESS
#define GL_COMPARE_REF_TO_TEXTURE
#define GL_SHADER_STORAGE_BUFFER
#define GL_ALL_BARRIER_BITS
#define GL_MAX_VERTEX_ATTRIBS
#define GL_STENCIL_INDEX8
#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
typedef GLbitfield(APIENTRYP PFNGLQUERYMATRIXXOESPROC)(GLfixed *mantissa
#define GL_FRAMEBUFFER_COMPLETE
#define GL_MAX_COMPUTE_WORK_GROUP_SIZE
#define GL_VERTEX_PROGRAM_POINT_SIZE
#define GL_DRAW_FRAMEBUFFER
#define GL_PROGRAM_BINARY_LENGTH
#define GL_FUNC_REVERSE_SUBTRACT
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS
#define GL_TEXTURE_RECTANGLE
#define GL_TEXTURE_1D_ARRAY
#define GL_COMPILE_STATUS
GLdouble GLdouble GLdouble GLdouble q
#define GL_MAX_DRAW_BUFFERS
#define GL_QUERY_RESULT_AVAILABLE
GLenum GLenum GLenum GLenum mapping
#define GL_MAX_ARRAY_TEXTURE_LAYERS
#define GL_CONSTANT_ALPHA
#define GL_ONE_MINUS_CONSTANT_COLOR
#define GL_MAX_VERTEX_UNIFORM_VECTORS
#define GL_READ_FRAMEBUFFER
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS
#define GL_DEPTH_ATTACHMENT
#define GL_SHADER_STORAGE_BARRIER_BIT
#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS
#define GL_ELEMENT_ARRAY_BUFFER
#define GL_DEPTH_COMPONENT24
#define GL_PATCH_VERTICES
#define GL_MAX_VERTEX_UNIFORM_COMPONENTS
#define GL_INFO_LOG_LENGTH
#define GL_STENCIL_ATTACHMENT
#define GL_MAX_VARYING_COMPONENTS
#define GL_MAX_VARYING_FLOATS
#define GL_TEXTURE_COMPARE_MODE
GLsizeiptr const void GLenum usage
static void normalize(double &x, double &y)
void forceUpdate(QQuickItem *item)
static GLenum toGlMinFilter(QRhiSampler::Filter f, QRhiSampler::Filter m)
static QGles2Buffer::Access toGlAccess(QRhiPassResourceTracker::BufferAccess access)
static GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags)
#define GL_DEPTH_COMPONENT32F
static GLenum toGlTextureCompareFunc(QRhiSampler::CompareOp op)
#define GL_GEOMETRY_SHADER
static GLenum toGlCompareOp(QRhiGraphicsPipeline::CompareOp op)
#define GL_DEPTH24_STENCIL8
#define GL_DEPTH_COMPONENT16
static GLenum toGlWrapMode(QRhiSampler::AddressMode m)
static GLenum toGlBlendFactor(QRhiGraphicsPipeline::BlendFactor f)
#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
static GLbitfield barriersForTexture()
#define GL_TESS_CONTROL_SHADER
static GLenum toGlFrontFace(QRhiGraphicsPipeline::FrontFace f)
#define GL_BGRA
\variable QRhiGles2NativeHandles::context
#define GL_UNIFORM_BARRIER_BIT
#define GL_ELEMENT_ARRAY_BARRIER_BIT
#define GL_TEXTURE_FETCH_BARRIER_BIT
static void addBoundaryCommand(QGles2CommandBuffer *cbD, QGles2CommandBuffer::Command::Cmd type, GLuint tsQuery=0)
#define GL_UNSIGNED_INT_24_8
#define GL_COMPUTE_SHADER
static QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const QGles2Buffer::UsageState &bufUsage)
static bool bufferAccessIsWrite(QGles2Buffer::Access access)
static bool isGraphicsStage(const QRhiShaderStage &shaderStage)
static QShader::Stage toShaderStage(QRhiShaderStage::Type type)
static GLenum toGlBlendOp(QRhiGraphicsPipeline::BlendOp op)
#define GL_TESS_EVALUATION_SHADER
#define GL_PIXEL_BUFFER_BARRIER_BIT
static void toGlTextureFormat(QRhiTexture::Format format, const QRhiGles2::Caps &caps, GLenum *glintformat, GLenum *glsizedintformat, GLenum *glformat, GLenum *gltype)
#define GL_TEXTURE_UPDATE_BARRIER_BIT
static GLenum toGlShaderType(QRhiShaderStage::Type type)
#define GL_BUFFER_UPDATE_BARRIER_BIT
static GLenum toGlCullMode(QRhiGraphicsPipeline::CullMode c)
static GLenum toGlStencilOp(QRhiGraphicsPipeline::StencilOp op)
static GLbitfield barriersForBuffer()
static GLenum toGlTopology(QRhiGraphicsPipeline::Topology t)
#define GL_SHADER_STORAGE_BARRIER_BIT
void qrhigl_accumulateComputeResource(T *writtenResources, QRhiResource *resource, QRhiShaderResourceBinding::Type bindingType, int loadTypeVal, int storeTypeVal, int loadStoreTypeVal)
static void bindVertexIndexBufferWithStateReset(CommandBufferExecTrackedState *state, QOpenGLExtensions *f, GLenum target, GLuint buffer)
#define GL_DEPTH_COMPONENT24
static bool textureAccessIsWrite(QGles2Texture::Access access)
static GLenum toGlMagFilter(QRhiSampler::Filter f)
#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT
#define GL_FRAMEBUFFER_BARRIER_BIT
static void qrhi_std140_to_packed(T *dst, int vecSize, int elemCount, const void *src)
#define GL_UNSIGNED_INT_2_10_10_10_REV
static GLenum toGlPolygonMode(QRhiGraphicsPipeline::PolygonMode mode)
static QSurface * currentSurfaceForCurrentContext(QOpenGLContext *ctx)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
unsigned long long quint64
QVideoFrameFormat::PixelFormat fmt
view viewport() -> scroll(dx, dy, deviceRect)
QSvgRenderer * renderer
[0]
struct CommandBufferExecTrackedState::@364 lastBindVertexBuffer
bool nonzeroAttribDivisor[TRACKED_ATTRIB_COUNT]
GLuint currentArrayBuffer
GLuint currentElementArrayBuffer
int maxUntrackedInstancedAttribute
bool instancedAttributesUsed
static const int TRACKED_ATTRIB_COUNT
QRhiGraphicsPipeline * ps
bool enabledAttribArrays[TRACKED_ATTRIB_COUNT]
QGles2Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
char * beginFullDynamicBufferUpdateForCurrentFrame() override
void endFullDynamicBufferUpdateForCurrentFrame() override
To be called when the entire contents of the buffer data has been updated in the memory block returne...
QRhiBuffer::NativeBuffer nativeBuffer() override
bool create() override
Creates the corresponding native graphics resources.
union QGles2CommandBuffer::Command::Args args
struct QGles2CommandBuffer::ComputePassState computePassState
QRhiShaderResourceBindings * currentGraphicsSrb
uint currentPipelineGeneration
int currentPassResTrackerIndex
uint currentSrbGeneration
static const int MAX_DYNAMIC_OFFSET_COUNT
struct QGles2CommandBuffer::GraphicsPassState graphicsPassState
QRhiBackendCommandList< Command > commands
QRhiComputePipeline * currentComputePipeline
QRhiRenderTarget * currentTarget
QRhiShaderResourceBindings * currentComputeSrb
QVarLengthArray< QRhiPassResourceTracker, 8 > passResTrackers
bool passNeedsResourceTracking
QGles2CommandBuffer(QRhiImplementation *rhi)
const void * retainImage(const QImage &image)
const void * retainData(const QByteArray &data)
const uchar * retainBufferData(const QRhiBufferData &data)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
struct QGles2CommandBuffer::TextureUnitState textureUnitState[16]
QRhiGraphicsPipeline * currentGraphicsPipeline
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QGles2UniformState uniformState[QGles2UniformState::MAX_TRACKED_LOCATION+1]
QGles2UniformDescriptionVector uniforms
QRhiShaderResourceBindings * currentSrb
QGles2ComputePipeline(QRhiImplementation *rhi)
uint currentSrbGeneration
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
bool create() override
Creates the corresponding native graphics resources.
QGles2GraphicsPipeline(QRhiImplementation *rhi)
~QGles2GraphicsPipeline()
QRhiShaderResourceBindings * currentSrb
uint currentSrbGeneration
QGles2UniformDescriptionVector uniforms
QGles2UniformState uniformState[QGles2UniformState::MAX_TRACKED_LOCATION+1]
bool create() override
Creates the corresponding native graphics resources.
QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, int sampleCount, QRhiRenderBuffer::Flags flags, QRhiTexture::Format backingFormatHint)
bool createFrom(NativeRenderBuffer src) override
Similar to create() except that no new native renderbuffer objects are created.
QRhiTexture::Format backingFormat() const override
GLuint stencilRenderbuffer
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QVector< quint32 > serializedFormat() const override
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() const override
bool isCompatible(const QRhiRenderPassDescriptor *other) const override
~QGles2RenderPassDescriptor()
QGles2RenderPassDescriptor(QRhiImplementation *rhi)
std::optional< QRhiSwapChain::StereoTargetBuffer > stereoTarget
QGles2RenderPassDescriptor * rp
QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QGles2Sampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode, AddressMode u, AddressMode v, AddressMode w)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
void updateResources(UpdateFlags flags) override
~QGles2ShaderResourceBindings()
QGles2ShaderResourceBindings(QRhiImplementation *rhi)
float devicePixelRatio() const override
QGles2SwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain)
QSize pixelSize() const override
int sampleCount() const override
~QGles2SwapChainRenderTarget()
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
void prepare(QRhiGles2 *rhiD)
bool active[TIMESTAMP_PAIRS]
bool tryQueryTimestamps(int pairIndex, QRhiGles2 *rhiD, double *elapsedSec)
static const int TIMESTAMP_PAIRS
void destroy(QRhiGles2 *rhiD)
void initSwapChainRenderTarget(QGles2SwapChainRenderTarget *rt)
QGles2SwapChainRenderTarget rtRight
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QGles2SwapChainRenderTarget rt
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() override
bool isFormatSupported(Format f) override
bool createOrResize() override
Creates the swapchain if not already done and resizes the swapchain buffers to match the current size...
QGles2SwapChainTimestamps timestamps
QGles2SwapChain(QRhiImplementation *rhi)
QRhiCommandBuffer * currentFrameCommandBuffer() override
QGles2SwapChainRenderTarget rtLeft
QSize surfacePixelSize() override
QRhiRenderTarget * currentFrameRenderTarget() override
int sampleCount() const override
QGles2TextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags)
~QGles2TextureRenderTarget()
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
float devicePixelRatio() const override
QSize pixelSize() const override
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() override
bool create() override
Creates the corresponding native graphics resources.
GLuint nonMsaaThrowawayDepthTexture
bool createFrom(NativeTexture src) override
Similar to create(), except that no new native textures are created.
QGles2Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, Flags flags)
QGles2SamplerData samplerState
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
bool prepareCreate(QSize *adjustedSize=nullptr)
bool create() override
Creates the corresponding native graphics resources.
NativeTexture nativeTexture() override
QList< ShaderDesc > shaders
QByteArray cacheKey() const
struct QRhiGles2::DeferredReleaseEntry::@302::@308 textureRenderTarget
struct QRhiGles2::DeferredReleaseEntry::@302::@305 pipeline
\variable QRhiReadbackResult::completed
std::function< void()> completed
QRhiReadbackResult * result
QRhiTextureCopyDescription desc
QRhiReadbackDescription rb
QVarLengthArray< MipLevelUploadList, 6 > subresDesc
QRhiReadbackResult * result
qint64 totalPipelineCreationTime
\variable QShaderDescription::InOutVariable::name