From 00d90969b270f4ebf9591904827de0fb17368b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Thu, 2 Jan 2020 14:24:12 +0100 Subject: First triangle Change-Id: I1db75f3840c2776acfb18c1907dc7d868e8bfba4 --- dependencies.yaml | 3 + src/core/resources/qloadgltf_p.h | 2 +- .../rhi/graphicshelpers/graphicscontext.cpp | 772 ++++++------ .../rhi/graphicshelpers/graphicscontext_p.h | 21 +- .../rhi/graphicshelpers/submissioncontext.cpp | 1318 ++++++++++---------- .../rhi/graphicshelpers/submissioncontext_p.h | 1 - src/plugins/renderers/rhi/io/buffer.cpp | 110 +- src/plugins/renderers/rhi/io/buffer_p.h | 20 +- .../renderers/rhi/managers/handle_types_p.h | 1 + .../renderers/rhi/renderer/commandexecuter.cpp | 146 +-- .../renderers/rhi/renderer/rendercommand_p.h | 10 + src/plugins/renderers/rhi/renderer/renderer.cpp | 748 +++++++---- src/plugins/renderers/rhi/renderer/renderer_p.h | 7 +- src/plugins/renderers/rhi/renderer/renderview.cpp | 4 +- .../renderers/rhi/renderer/renderviewbuilder.cpp | 1 + src/plugins/renderers/rhi/renderer/shader.cpp | 10 +- src/plugins/renderers/rhi/rhi.pro | 2 +- src/render/geometry/attribute.cpp | 6 + src/render/geometry/attribute_p.h | 2 + src/render/geometry/qattribute.cpp | 22 + src/render/geometry/qattribute.h | 4 + src/render/geometry/qattribute_p.h | 2 + src/render/materialsystem/qgraphicsapifilter.h | 3 +- src/src.pro | 2 +- tests/manual/manual.pro | 3 +- tests/manual/rhi/main.cpp | 410 ++++++ tests/manual/rhi/rhi.pro | 8 + 27 files changed, 2304 insertions(+), 1334 deletions(-) create mode 100644 tests/manual/rhi/main.cpp create mode 100644 tests/manual/rhi/rhi.pro diff --git a/dependencies.yaml b/dependencies.yaml index c06c22130..8daf46129 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -11,3 +11,6 @@ dependencies: ../qtimageformats: ref: b9b0e50aa3b7ff7c4b39bdb84e6c0b8027447fb8 required: false + ../qtshadertools: + ref: ff102f01ed25b80abb770c6c6ef82d877dd508a3 + required: false diff --git a/src/core/resources/qloadgltf_p.h b/src/core/resources/qloadgltf_p.h index be7ee0d5f..21b775441 100644 --- a/src/core/resources/qloadgltf_p.h +++ b/src/core/resources/qloadgltf_p.h @@ -60,7 +60,7 @@ inline QJsonDocument qLoadGLTF(const QByteArray &gltfData) { -#if QT_CONFIG(binaryjson) +#if 0 //QT_CONFIG(binaryjson) { QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(gltfData); if (!sceneDocument.isNull()) diff --git a/src/plugins/renderers/rhi/graphicshelpers/graphicscontext.cpp b/src/plugins/renderers/rhi/graphicshelpers/graphicscontext.cpp index 3358f47f3..4cb0104ac 100644 --- a/src/plugins/renderers/rhi/graphicshelpers/graphicscontext.cpp +++ b/src/plugins/renderers/rhi/graphicshelpers/graphicscontext.cpp @@ -135,11 +135,12 @@ GraphicsContext::GraphicsContext() , m_maxTextureUnits(0) , m_maxImageUnits(0) , m_defaultFBO(0) - , m_gl(nullptr) - , m_glHelper(nullptr) +//* , m_gl(nullptr) +//* , m_glHelper(nullptr) , m_debugLogger(nullptr) , m_currentVAO(nullptr) { + m_contextInfo.m_api = QGraphicsApiFilter::RHI; } GraphicsContext::~GraphicsContext() @@ -148,32 +149,34 @@ GraphicsContext::~GraphicsContext() void GraphicsContext::setOpenGLContext(QOpenGLContext* ctx) { - Q_ASSERT(ctx); - m_gl = ctx; + RHI_UNIMPLEMENTED; +//* Q_ASSERT(ctx); +//* m_gl = ctx; } void GraphicsContext::initialize() { m_initialized = true; - Q_ASSERT(m_gl); +//* Q_ASSERT(m_gl); +//* +//* m_gl->functions()->glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_maxTextureUnits); +//* qCDebug(Backend) << "context supports" << m_maxTextureUnits << "texture units"; +//* m_gl->functions()->glGetIntegerv(GL_MAX_IMAGE_UNITS, &m_maxImageUnits); +//* qCDebug(Backend) << "context supports" << m_maxImageUnits << "image units"; +//* +//* if (m_gl->format().majorVersion() >= 3) { +//* m_supportsVAO = true; +//* } else { +//* QSet extensions = m_gl->extensions(); +//* m_supportsVAO = extensions.contains(QByteArrayLiteral("GL_OES_vertex_array_object")) +//* || extensions.contains(QByteArrayLiteral("GL_ARB_vertex_array_object")) +//* || extensions.contains(QByteArrayLiteral("GL_APPLE_vertex_array_object")); +//* } +//* +//* m_defaultFBO = m_gl->defaultFramebufferObject(); +//* qCDebug(Backend) << "VAO support = " << m_supportsVAO; - m_gl->functions()->glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_maxTextureUnits); - qCDebug(Backend) << "context supports" << m_maxTextureUnits << "texture units"; - m_gl->functions()->glGetIntegerv(GL_MAX_IMAGE_UNITS, &m_maxImageUnits); - qCDebug(Backend) << "context supports" << m_maxImageUnits << "image units"; - - if (m_gl->format().majorVersion() >= 3) { - m_supportsVAO = true; - } else { - QSet extensions = m_gl->extensions(); - m_supportsVAO = extensions.contains(QByteArrayLiteral("GL_OES_vertex_array_object")) - || extensions.contains(QByteArrayLiteral("GL_ARB_vertex_array_object")) - || extensions.contains(QByteArrayLiteral("GL_APPLE_vertex_array_object")); - } - - m_defaultFBO = m_gl->defaultFramebufferObject(); - qCDebug(Backend) << "VAO support = " << m_supportsVAO; } void GraphicsContext::clearBackBuffer(QClearBuffers::BufferTypeFlags buffers) @@ -188,13 +191,16 @@ void GraphicsContext::clearBackBuffer(QClearBuffers::BufferTypeFlags buffers) if (buffers & QClearBuffers::StencilBuffer) mask |= GL_STENCIL_BUFFER_BIT; - m_gl->functions()->glClear(mask); + RHI_UNIMPLEMENTED; +//* m_gl->functions()->glClear(mask); } } bool GraphicsContext::hasValidGLHelper() const { - return m_glHelper != nullptr; + RHI_UNIMPLEMENTED; +//* return m_glHelper != nullptr; + return true; } bool GraphicsContext::isInitialized() const @@ -204,79 +210,85 @@ bool GraphicsContext::isInitialized() const bool GraphicsContext::makeCurrent(QSurface *surface) { - Q_ASSERT(m_gl); - if (!m_gl->makeCurrent(surface)) { - qCWarning(Backend) << Q_FUNC_INFO << "makeCurrent failed"; - return false; - } - - initializeHelpers(surface); + RHI_UNIMPLEMENTED; +//* Q_ASSERT(m_gl); +//* if (!m_gl->makeCurrent(surface)) { +//* qCWarning(Backend) << Q_FUNC_INFO << "makeCurrent failed"; +//* return false; +//* } +//* +//* initializeHelpers(surface); return true; } void GraphicsContext::initializeHelpers(QSurface *surface) { + RHI_UNIMPLEMENTED; // Set the correct GL Helper depending on the surface // If no helper exists, create one - m_glHelper = m_glHelpers.value(surface); - if (!m_glHelper) { - m_glHelper = resolveHighestOpenGLFunctions(); - m_glHelpers.insert(surface, m_glHelper); - } +//* m_glHelper = m_glHelpers.value(surface); +//* if (!m_glHelper) { +//* m_glHelper = resolveHighestOpenGLFunctions(); +//* m_glHelpers.insert(surface, m_glHelper); +//* } } void GraphicsContext::doneCurrent() { - Q_ASSERT(m_gl); - m_gl->doneCurrent(); - m_glHelper = nullptr; + RHI_UNIMPLEMENTED; + //* Q_ASSERT(m_gl); + //* m_gl->doneCurrent(); + //* m_glHelper = nullptr; } // Called by GL Command Thread GraphicsContext::ShaderCreationInfo GraphicsContext::createShaderProgram(RHIShader *shader) { - QOpenGLShaderProgram *shaderProgram = shader->shaderProgram(); - - // Compile shaders - const auto shaderCode = shader->shaderCode(); - - QString logs; - for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) { - const QShaderProgram::ShaderType type = static_cast(i); - if (!shaderCode.at(i).isEmpty()) { - // Note: logs only return the error but not all the shader code - // we could append it - if (!shaderProgram->addCacheableShaderFromSourceCode(shaderType(type), shaderCode.at(i))) - logs += shaderProgram->log(); - } - } - - // Call glBindFragDataLocation and link the program - // Since we are sharing shaders in the backend, we assume that if using custom - // fragOutputs, they should all be the same for a given shader - bindFragOutputs(shaderProgram->programId(), shader->fragOutputs()); - - const bool linkSucceeded = shaderProgram->link(); - logs += shaderProgram->log(); - - // Perform shader introspection - introspectShaderInterface(shader); - - return {linkSucceeded, logs}; + RHI_UNIMPLEMENTED; + return {true, {}}; +//* QOpenGLShaderProgram *shaderProgram = shader->shaderProgram(); +//* +//* // Compile shaders +//* const auto shaderCode = shader->shaderCode(); +//* +//* QString logs; +//* for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) { +//* const QShaderProgram::ShaderType type = static_cast(i); +//* if (!shaderCode.at(i).isEmpty()) { +//* // Note: logs only return the error but not all the shader code +//* // we could append it +//* if (!shaderProgram->addCacheableShaderFromSourceCode(shaderType(type), shaderCode.at(i))) +//* logs += shaderProgram->log(); +//* } +//* } +//* +//* // Call glBindFragDataLocation and link the program +//* // Since we are sharing shaders in the backend, we assume that if using custom +//* // fragOutputs, they should all be the same for a given shader +//* bindFragOutputs(shaderProgram->programId(), shader->fragOutputs()); +//* +//* const bool linkSucceeded = shaderProgram->link(); +//* logs += shaderProgram->log(); +//* +//* // Perform shader introspection +//* introspectShaderInterface(shader); +//* +//* return {linkSucceeded, logs}; } // That assumes that the shaderProgram in Shader stays the same void GraphicsContext::introspectShaderInterface(RHIShader *shader) { - QOpenGLShaderProgram *shaderProgram = shader->shaderProgram(); - GraphicsHelperInterface *glHelper = resolveHighestOpenGLFunctions(); - shader->initializeUniforms(glHelper->programUniformsAndLocations(shaderProgram->programId())); - shader->initializeAttributes(glHelper->programAttributesAndLocations(shaderProgram->programId())); - if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject)) - shader->initializeUniformBlocks(m_glHelper->programUniformBlocks(shaderProgram->programId())); - if (m_glHelper->supportsFeature(GraphicsHelperInterface::ShaderStorageObject)) - shader->initializeShaderStorageBlocks(m_glHelper->programShaderStorageBlocks(shaderProgram->programId())); + RHI_UNIMPLEMENTED; +//* QOpenGLShaderProgram *shaderProgram = shader->shaderProgram(); +//* GraphicsHelperInterface *glHelper = resolveHighestOpenGLFunctions(); +//* shader->initializeUniforms(glHelper->programUniformsAndLocations(shaderProgram->programId())); +//* shader->initializeAttributes(glHelper->programAttributesAndLocations(shaderProgram->programId())); +//* if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject)) +//* shader->initializeUniformBlocks(m_glHelper->programUniformBlocks(shaderProgram->programId())); +//* if (m_glHelper->supportsFeature(GraphicsHelperInterface::ShaderStorageObject)) +//* shader->initializeShaderStorageBlocks(m_glHelper->programShaderStorageBlocks(shaderProgram->programId())); } @@ -285,6 +297,7 @@ void GraphicsContext::loadShader(Shader *shaderNode, ShaderManager *shaderManager, RHIShaderManager *rhiShaderManager) { + RHI_UNIMPLEMENTED; const Qt3DCore::QNodeId shaderId = shaderNode->peerId(); RHIShader *glShader = rhiShaderManager->lookupResource(shaderId); @@ -326,23 +339,25 @@ void GraphicsContext::loadShader(Shader *shaderNode, void GraphicsContext::activateDrawBuffers(const AttachmentPack &attachments) { - const QVector activeDrawBuffers = attachments.getGlDrawBuffers(); - - if (m_glHelper->checkFrameBufferComplete()) { - if (activeDrawBuffers.size() > 1) {// We need MRT - if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT)) { - // Set up MRT, glDrawBuffers... - m_glHelper->drawBuffers(activeDrawBuffers.size(), activeDrawBuffers.data()); - } - } - } else { - qWarning() << "FBO incomplete"; - } + RHI_UNIMPLEMENTED; +//* const QVector activeDrawBuffers = attachments.getGlDrawBuffers(); +//* +//* if (m_glHelper->checkFrameBufferComplete()) { +//* if (activeDrawBuffers.size() > 1) {// We need MRT +//* if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT)) { +//* // Set up MRT, glDrawBuffers... +//* m_glHelper->drawBuffers(activeDrawBuffers.size(), activeDrawBuffers.data()); +//* } +//* } +//* } else { +//* qWarning() << "FBO incomplete"; +//* } } void GraphicsContext::rasterMode(GLenum faceMode, GLenum rasterMode) { - m_glHelper->rasterMode(faceMode, rasterMode); + RHI_UNIMPLEMENTED; +//* m_glHelper->rasterMode(faceMode, rasterMode); } /*! @@ -352,88 +367,91 @@ void GraphicsContext::rasterMode(GLenum faceMode, GLenum rasterMode) */ GraphicsHelperInterface *GraphicsContext::resolveHighestOpenGLFunctions() { - Q_ASSERT(m_gl); - GraphicsHelperInterface *glHelper = nullptr; - - if (m_gl->isOpenGLES()) { - if (m_gl->format().majorVersion() >= 3) { - if (m_gl->format().minorVersion() >= 2) { - glHelper = new GraphicsHelperES3_2; - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.2 Helper"; - } else if (m_gl->format().minorVersion() >= 1) { - glHelper = new GraphicsHelperES3_1; - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.1 Helper"; - } else { - glHelper = new GraphicsHelperES3(); - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.0 Helper"; - } - } else { - glHelper = new GraphicsHelperES2(); - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES2 Helper"; - } - glHelper->initializeHelper(m_gl, nullptr); - } -#ifndef QT_OPENGL_ES_2 - else { - QAbstractOpenGLFunctions *glFunctions = nullptr; - if ((glFunctions = m_gl->versionFunctions()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 4.3"; - glHelper = new GraphicsHelperGL4(); - } else if ((glFunctions = m_gl->versionFunctions()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 3.3"; - glHelper = new GraphicsHelperGL3_3(); - } else if ((glFunctions = m_gl->versionFunctions()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 3.2"; - glHelper = new GraphicsHelperGL3_2(); - } else if ((glFunctions = m_gl->versionFunctions()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 2 Helper"; - glHelper = new GraphicsHelperGL2(); - } - Q_ASSERT_X(glHelper, "GraphicsContext::resolveHighestOpenGLFunctions", "unable to create valid helper for available OpenGL version"); - glHelper->initializeHelper(m_gl, glFunctions); - } -#endif - - // Note: at this point we are certain the context (m_gl) is current with a surface - const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING"); - const bool enableDebugLogging = !debugLoggingMode.isEmpty(); - - if (enableDebugLogging && !m_debugLogger) { - if (m_gl->hasExtension("GL_KHR_debug")) { - qCDebug(Backend) << "Qt3D: Enabling OpenGL debug logging"; - m_debugLogger.reset(new QOpenGLDebugLogger); - if (m_debugLogger->initialize()) { - QObject::connect(m_debugLogger.data(), &QOpenGLDebugLogger::messageLogged, &logOpenGLDebugMessage); - const QString mode = QString::fromLocal8Bit(debugLoggingMode); - m_debugLogger->startLogging(mode.startsWith(QLatin1String("sync"), Qt::CaseInsensitive) - ? QOpenGLDebugLogger::SynchronousLogging - : QOpenGLDebugLogger::AsynchronousLogging); - - const auto msgs = m_debugLogger->loggedMessages(); - for (const QOpenGLDebugMessage &msg : msgs) - logOpenGLDebugMessage(msg); - } - } else { - qCDebug(Backend) << "Qt3D: OpenGL debug logging requested but GL_KHR_debug not supported"; - } - } - + RHI_UNIMPLEMENTED; +//* Q_ASSERT(m_gl); +//* GraphicsHelperInterface *glHelper = nullptr; +//* +//* if (m_gl->isOpenGLES()) { +//* if (m_gl->format().majorVersion() >= 3) { +//* if (m_gl->format().minorVersion() >= 2) { +//* glHelper = new GraphicsHelperES3_2; +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.2 Helper"; +//* } else if (m_gl->format().minorVersion() >= 1) { +//* glHelper = new GraphicsHelperES3_1; +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.1 Helper"; +//* } else { +//* glHelper = new GraphicsHelperES3(); +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.0 Helper"; +//* } +//* } else { +//* glHelper = new GraphicsHelperES2(); +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES2 Helper"; +//* } +//* glHelper->initializeHelper(m_gl, nullptr); +//* } +//*#ifndef QT_OPENGL_ES_2 +//* else { +//* QAbstractOpenGLFunctions *glFunctions = nullptr; +//* if ((glFunctions = m_gl->versionFunctions()) != nullptr) { +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 4.3"; +//* glHelper = new GraphicsHelperGL4(); +//* } else if ((glFunctions = m_gl->versionFunctions()) != nullptr) { +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 3.3"; +//* glHelper = new GraphicsHelperGL3_3(); +//* } else if ((glFunctions = m_gl->versionFunctions()) != nullptr) { +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 3.2"; +//* glHelper = new GraphicsHelperGL3_2(); +//* } else if ((glFunctions = m_gl->versionFunctions()) != nullptr) { +//* qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 2 Helper"; +//* glHelper = new GraphicsHelperGL2(); +//* } +//* Q_ASSERT_X(glHelper, "GraphicsContext::resolveHighestOpenGLFunctions", "unable to create valid helper for available OpenGL version"); +//* glHelper->initializeHelper(m_gl, glFunctions); +//* } +//*#endif +//* +//* // Note: at this point we are certain the context (m_gl) is current with a surface +//* const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING"); +//* const bool enableDebugLogging = !debugLoggingMode.isEmpty(); +//* +//* if (enableDebugLogging && !m_debugLogger) { +//* if (m_gl->hasExtension("GL_KHR_debug")) { +//* qCDebug(Backend) << "Qt3D: Enabling OpenGL debug logging"; +//* m_debugLogger.reset(new QOpenGLDebugLogger); +//* if (m_debugLogger->initialize()) { +//* QObject::connect(m_debugLogger.data(), &QOpenGLDebugLogger::messageLogged, &logOpenGLDebugMessage); +//* const QString mode = QString::fromLocal8Bit(debugLoggingMode); +//* m_debugLogger->startLogging(mode.startsWith(QLatin1String("sync"), Qt::CaseInsensitive) +//* ? QOpenGLDebugLogger::SynchronousLogging +//* : QOpenGLDebugLogger::AsynchronousLogging); +//* +//* const auto msgs = m_debugLogger->loggedMessages(); +//* for (const QOpenGLDebugMessage &msg : msgs) +//* logOpenGLDebugMessage(msg); +//* } +//* } else { +//* qCDebug(Backend) << "Qt3D: OpenGL debug logging requested but GL_KHR_debug not supported"; +//* } +//* } +//* // Set Vendor and Extensions of reference GraphicsApiFilter // TO DO: would that vary like the glHelper ? QStringList extensions; - const auto exts = m_gl->extensions(); - for (const QByteArray &ext : exts) - extensions << QString::fromUtf8(ext); - m_contextInfo.m_major = m_gl->format().version().first; - m_contextInfo.m_minor = m_gl->format().version().second; - m_contextInfo.m_api = m_gl->isOpenGLES() ? QGraphicsApiFilter::OpenGLES : QGraphicsApiFilter::OpenGL; - m_contextInfo.m_profile = static_cast(m_gl->format().profile()); + //const auto exts = m_gl->extensions(); + //for (const QByteArray &ext : exts) + // extensions << QString::fromUtf8(ext); + m_contextInfo.m_major = 3; + m_contextInfo.m_minor = 2; + // m_contextInfo.m_major = m_gl->format().version().first; + // m_contextInfo.m_minor = m_gl->format().version().second; + m_contextInfo.m_api = QGraphicsApiFilter::RHI; + //m_contextInfo.m_profile = static_cast(m_gl->format().profile()); m_contextInfo.m_extensions = extensions; - m_contextInfo.m_vendor = QString::fromUtf8(reinterpret_cast(m_gl->functions()->glGetString(GL_VENDOR))); + //m_contextInfo.m_vendor = QString::fromUtf8(reinterpret_cast(m_gl->functions()->glGetString(GL_VENDOR))); - return glHelper; + return nullptr; } const GraphicsApiFilterData *GraphicsContext::contextInfo() const @@ -443,7 +461,8 @@ const GraphicsApiFilterData *GraphicsContext::contextInfo() const bool GraphicsContext::supportsDrawBuffersBlend() const { - return m_glHelper->supportsFeature(GraphicsHelperInterface::DrawBuffersBlend); + return false; +//* return m_glHelper->supportsFeature(GraphicsHelperInterface::DrawBuffersBlend); } /*! @@ -460,13 +479,14 @@ void GraphicsContext::drawElementsInstancedBaseVertexBaseInstance(GLenum primiti GLint baseVertex, GLint baseInstance) { - m_glHelper->drawElementsInstancedBaseVertexBaseInstance(primitiveType, - primitiveCount, - indexType, - indices, - instances, - baseVertex, - baseInstance); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawElementsInstancedBaseVertexBaseInstance(primitiveType, +//* primitiveCount, +//* indexType, +//* indices, +//* instances, +//* baseVertex, +//* baseInstance); } /*! @@ -478,19 +498,21 @@ void GraphicsContext::drawArraysInstanced(GLenum primitiveType, GLsizei count, GLsizei instances) { - m_glHelper->drawArraysInstanced(primitiveType, - first, - count, - instances); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawArraysInstanced(primitiveType, +//* first, +//* count, +//* instances); } void GraphicsContext::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseinstance) { - m_glHelper->drawArraysInstancedBaseInstance(primitiveType, - first, - count, - instances, - baseinstance); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawArraysInstancedBaseInstance(primitiveType, +//* first, +//* count, +//* instances, +//* baseinstance); } /*! @@ -503,18 +525,20 @@ void GraphicsContext::drawElements(GLenum primitiveType, void *indices, GLint baseVertex) { - m_glHelper->drawElements(primitiveType, - primitiveCount, - indexType, - indices, - baseVertex); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawElements(primitiveType, +//* primitiveCount, +//* indexType, +//* indices, +//* baseVertex); } void GraphicsContext::drawElementsIndirect(GLenum mode, GLenum type, void *indirect) { - m_glHelper->drawElementsIndirect(mode, type, indirect); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawElementsIndirect(mode, type, indirect); } /*! @@ -525,350 +549,398 @@ void GraphicsContext::drawArrays(GLenum primitiveType, GLint first, GLsizei count) { - m_glHelper->drawArrays(primitiveType, - first, - count); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawArrays(primitiveType, +//* first, +//* count); } void GraphicsContext::drawArraysIndirect(GLenum mode, void *indirect) { - m_glHelper->drawArraysIndirect(mode, indirect); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawArraysIndirect(mode, indirect); } void GraphicsContext::setVerticesPerPatch(GLint verticesPerPatch) { - m_glHelper->setVerticesPerPatch(verticesPerPatch); + RHI_UNIMPLEMENTED; +//* m_glHelper->setVerticesPerPatch(verticesPerPatch); } void GraphicsContext::blendEquation(GLenum mode) { - m_glHelper->blendEquation(mode); + RHI_UNIMPLEMENTED; +//* m_glHelper->blendEquation(mode); } void GraphicsContext::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) { - m_glHelper->blendFunci(buf, sfactor, dfactor); + RHI_UNIMPLEMENTED; +//* m_glHelper->blendFunci(buf, sfactor, dfactor); } void GraphicsContext::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) { - m_glHelper->blendFuncSeparatei(buf, sRGB, dRGB, sAlpha, dAlpha); + RHI_UNIMPLEMENTED; +//* m_glHelper->blendFuncSeparatei(buf, sRGB, dRGB, sAlpha, dAlpha); } void GraphicsContext::alphaTest(GLenum mode1, GLenum mode2) { - m_glHelper->alphaTest(mode1, mode2); + RHI_UNIMPLEMENTED; +//* m_glHelper->alphaTest(mode1, mode2); } void GraphicsContext::bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBindMode mode) { - m_glHelper->bindFrameBufferObject(fbo, mode); + RHI_UNIMPLEMENTED; +//* m_glHelper->bindFrameBufferObject(fbo, mode); } void GraphicsContext::depthRange(GLdouble nearValue, GLdouble farValue) { - m_glHelper->depthRange(nearValue, farValue); + RHI_UNIMPLEMENTED; +//* m_glHelper->depthRange(nearValue, farValue); } void GraphicsContext::depthTest(GLenum mode) { - m_glHelper->depthTest(mode); + RHI_UNIMPLEMENTED; +//* m_glHelper->depthTest(mode); } void GraphicsContext::depthMask(GLenum mode) { - m_glHelper->depthMask(mode); + RHI_UNIMPLEMENTED; +//* m_glHelper->depthMask(mode); } void GraphicsContext::frontFace(GLenum mode) { - m_glHelper->frontFace(mode); + RHI_UNIMPLEMENTED; +//* m_glHelper->frontFace(mode); } void GraphicsContext::bindFragOutputs(GLuint shader, const QHash &outputs) { - if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT) && - m_glHelper->supportsFeature(GraphicsHelperInterface::BindableFragmentOutputs)) - m_glHelper->bindFragDataLocation(shader, outputs); + RHI_UNIMPLEMENTED; +//* if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT) && +//* m_glHelper->supportsFeature(GraphicsHelperInterface::BindableFragmentOutputs)) +//* m_glHelper->bindFragDataLocation(shader, outputs); } void GraphicsContext::bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) { - m_glHelper->bindImageTexture(imageUnit, - texture, - mipLevel, - layered, - layer, - access, - format); + RHI_UNIMPLEMENTED; +//* m_glHelper->bindImageTexture(imageUnit, +//* texture, +//* mipLevel, +//* layered, +//* layer, +//* access, +//* format); } void GraphicsContext::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { - m_glHelper->bindUniformBlock(programId, uniformBlockIndex, uniformBlockBinding); + RHI_UNIMPLEMENTED; +//* m_glHelper->bindUniformBlock(programId, uniformBlockIndex, uniformBlockBinding); } void GraphicsContext::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) { - m_glHelper->bindShaderStorageBlock(programId, shaderStorageBlockIndex, shaderStorageBlockBinding); + RHI_UNIMPLEMENTED; +//* m_glHelper->bindShaderStorageBlock(programId, shaderStorageBlockIndex, shaderStorageBlockBinding); } void GraphicsContext::bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer) { - m_glHelper->bindBufferBase(target, bindingIndex, buffer); + RHI_UNIMPLEMENTED; +//* m_glHelper->bindBufferBase(target, bindingIndex, buffer); } void GraphicsContext::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) { - m_glHelper->buildUniformBuffer(v, description, buffer); + RHI_UNIMPLEMENTED; +//* m_glHelper->buildUniformBuffer(v, description, buffer); } void GraphicsContext::setMSAAEnabled(bool enabled) { - m_glHelper->setMSAAEnabled(enabled); + RHI_UNIMPLEMENTED; +//* m_glHelper->setMSAAEnabled(enabled); } void GraphicsContext::setAlphaCoverageEnabled(bool enabled) { - m_glHelper->setAlphaCoverageEnabled(enabled); + RHI_UNIMPLEMENTED; +//* m_glHelper->setAlphaCoverageEnabled(enabled); } void GraphicsContext::clearBufferf(GLint drawbuffer, const QVector4D &values) { - m_glHelper->clearBufferf(drawbuffer, values); + RHI_UNIMPLEMENTED; +//* m_glHelper->clearBufferf(drawbuffer, values); } GLuint GraphicsContext::boundFrameBufferObject() { - return m_glHelper->boundFrameBufferObject(); + RHI_UNIMPLEMENTED; + return false; +//* return m_glHelper->boundFrameBufferObject(); } void GraphicsContext::clearColor(const QColor &color) { - m_gl->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + RHI_UNIMPLEMENTED; +//* m_gl->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); } void GraphicsContext::clearDepthValue(float depth) { - m_gl->functions()->glClearDepthf(depth); + RHI_UNIMPLEMENTED; +//* m_gl->functions()->glClearDepthf(depth); } void GraphicsContext::clearStencilValue(int stencil) { - m_gl->functions()->glClearStencil(stencil); + RHI_UNIMPLEMENTED; +//* m_gl->functions()->glClearStencil(stencil); } void GraphicsContext::enableClipPlane(int clipPlane) { - m_glHelper->enableClipPlane(clipPlane); + RHI_UNIMPLEMENTED; +//* m_glHelper->enableClipPlane(clipPlane); } void GraphicsContext::disableClipPlane(int clipPlane) { - m_glHelper->disableClipPlane(clipPlane); + RHI_UNIMPLEMENTED; +//* m_glHelper->disableClipPlane(clipPlane); } void GraphicsContext::setClipPlane(int clipPlane, const QVector3D &normal, float distance) { - m_glHelper->setClipPlane(clipPlane, normal, distance); + RHI_UNIMPLEMENTED; +//* m_glHelper->setClipPlane(clipPlane, normal, distance); } GLint GraphicsContext::maxClipPlaneCount() { - return m_glHelper->maxClipPlaneCount(); + RHI_UNIMPLEMENTED; +//* return m_glHelper->maxClipPlaneCount(); } GLint GraphicsContext::maxTextureUnitsCount() const { - return m_maxTextureUnits; + RHI_UNIMPLEMENTED; +//* return m_maxTextureUnits; } GLint GraphicsContext::maxImageUnitsCount() const { - return m_maxImageUnits; + RHI_UNIMPLEMENTED; +//* return m_maxImageUnits; } void GraphicsContext::enablePrimitiveRestart(int restartIndex) { - if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart)) - m_glHelper->enablePrimitiveRestart(restartIndex); + RHI_UNIMPLEMENTED; +//* if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart)) +//* m_glHelper->enablePrimitiveRestart(restartIndex); } void GraphicsContext::disablePrimitiveRestart() { - if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart)) - m_glHelper->disablePrimitiveRestart(); + RHI_UNIMPLEMENTED; +//* if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart)) +//* m_glHelper->disablePrimitiveRestart(); } void GraphicsContext::pointSize(bool programmable, GLfloat value) { - m_glHelper->pointSize(programmable, value); + RHI_UNIMPLEMENTED; +//* m_glHelper->pointSize(programmable, value); } void GraphicsContext::dispatchCompute(int x, int y, int z) { - if (m_glHelper->supportsFeature(GraphicsHelperInterface::Compute)) - m_glHelper->dispatchCompute(x, y, z); + RHI_UNIMPLEMENTED; +//* if (m_glHelper->supportsFeature(GraphicsHelperInterface::Compute)) +//* m_glHelper->dispatchCompute(x, y, z); } GLboolean GraphicsContext::unmapBuffer(GLenum target) { - return m_glHelper->unmapBuffer(target); + RHI_UNIMPLEMENTED; + return true; +//* return m_glHelper->unmapBuffer(target); } char *GraphicsContext::mapBuffer(GLenum target, GLsizeiptr size) { - return m_glHelper->mapBuffer(target, size); + RHI_UNIMPLEMENTED; + return nullptr; +//* return m_glHelper->mapBuffer(target, size); } void GraphicsContext::enablei(GLenum cap, GLuint index) { - m_glHelper->enablei(cap, index); + RHI_UNIMPLEMENTED; +//* m_glHelper->enablei(cap, index); } void GraphicsContext::disablei(GLenum cap, GLuint index) { - m_glHelper->disablei(cap, index); + RHI_UNIMPLEMENTED; +//* m_glHelper->disablei(cap, index); } void GraphicsContext::setSeamlessCubemap(bool enable) { - m_glHelper->setSeamlessCubemap(enable); + RHI_UNIMPLEMENTED; +//* m_glHelper->setSeamlessCubemap(enable); } void GraphicsContext::readBuffer(GLenum mode) { - m_glHelper->readBuffer(mode); + RHI_UNIMPLEMENTED; +//* m_glHelper->readBuffer(mode); } void GraphicsContext::drawBuffer(GLenum mode) { - m_glHelper->drawBuffer(mode); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawBuffer(mode); } void GraphicsContext::drawBuffers(GLsizei n, const int *bufs) { - m_glHelper->drawBuffers(n, bufs); + RHI_UNIMPLEMENTED; +//* m_glHelper->drawBuffers(n, bufs); } void GraphicsContext::applyUniform(const ShaderUniform &description, const UniformValue &v) { - const UniformType type = m_glHelper->uniformTypeFromGLType(description.m_type); - - switch (type) { - case UniformType::Float: - // See QTBUG-57510 and uniform_p.h - if (v.storedType() == Int) { - float value = float(*v.constData()); - UniformValue floatV(value); - applyUniformHelper(description, floatV); - } else { - applyUniformHelper(description, v); - } - break; - case UniformType::Vec2: - applyUniformHelper(description, v); - break; - case UniformType::Vec3: - applyUniformHelper(description, v); - break; - case UniformType::Vec4: - applyUniformHelper(description, v); - break; - - case UniformType::Double: - applyUniformHelper(description, v); - break; - case UniformType::DVec2: - applyUniformHelper(description, v); - break; - case UniformType::DVec3: - applyUniformHelper(description, v); - break; - case UniformType::DVec4: - applyUniformHelper(description, v); - break; - - case UniformType::Sampler: - case UniformType::Image: - case UniformType::Int: - applyUniformHelper(description, v); - break; - case UniformType::IVec2: - applyUniformHelper(description, v); - break; - case UniformType::IVec3: - applyUniformHelper(description, v); - break; - case UniformType::IVec4: - applyUniformHelper(description, v); - break; - - case UniformType::UInt: - applyUniformHelper(description, v); - break; - case UniformType::UIVec2: - applyUniformHelper(description, v); - break; - case UniformType::UIVec3: - applyUniformHelper(description, v); - break; - case UniformType::UIVec4: - applyUniformHelper(description, v); - break; - - case UniformType::Bool: - applyUniformHelper(description, v); - break; - case UniformType::BVec2: - applyUniformHelper(description, v); - break; - case UniformType::BVec3: - applyUniformHelper(description, v); - break; - case UniformType::BVec4: - applyUniformHelper(description, v); - break; - - case UniformType::Mat2: - applyUniformHelper(description, v); - break; - case UniformType::Mat3: - applyUniformHelper(description, v); - break; - case UniformType::Mat4: - applyUniformHelper(description, v); - break; - case UniformType::Mat2x3: - applyUniformHelper(description, v); - break; - case UniformType::Mat3x2: - applyUniformHelper(description, v); - break; - case UniformType::Mat2x4: - applyUniformHelper(description, v); - break; - case UniformType::Mat4x2: - applyUniformHelper(description, v); - break; - case UniformType::Mat3x4: - applyUniformHelper(description, v); - break; - case UniformType::Mat4x3: - applyUniformHelper(description, v); - break; - - default: - break; - } + RHI_UNIMPLEMENTED; + //* const UniformType type = m_glHelper->uniformTypeFromGLType(description.m_type); + //* + //* switch (type) { + //* case UniformType::Float: + //* // See QTBUG-57510 and uniform_p.h + //* if (v.storedType() == Int) { + //* float value = float(*v.constData()); + //* UniformValue floatV(value); + //* applyUniformHelper(description, floatV); + //* } else { + //* applyUniformHelper(description, v); + //* } + //* break; + //* case UniformType::Vec2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Vec3: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Vec4: + //* applyUniformHelper(description, v); + //* break; + //* + //* case UniformType::Double: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::DVec2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::DVec3: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::DVec4: + //* applyUniformHelper(description, v); + //* break; + //* + //* case UniformType::Sampler: + //* case UniformType::Image: + //* case UniformType::Int: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::IVec2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::IVec3: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::IVec4: + //* applyUniformHelper(description, v); + //* break; + //* + //* case UniformType::UInt: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::UIVec2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::UIVec3: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::UIVec4: + //* applyUniformHelper(description, v); + //* break; + //* + //* case UniformType::Bool: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::BVec2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::BVec3: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::BVec4: + //* applyUniformHelper(description, v); + //* break; + //* + //* case UniformType::Mat2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat3: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat4: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat2x3: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat3x2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat2x4: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat4x2: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat3x4: + //* applyUniformHelper(description, v); + //* break; + //* case UniformType::Mat4x3: + //* applyUniformHelper(description, v); + //* break; + //* + //* default: + //* break; + //* } } void GraphicsContext::memoryBarrier(QMemoryBarrier::Operations barriers) { - m_glHelper->memoryBarrier(barriers); + RHI_UNIMPLEMENTED; + //* m_glHelper->memoryBarrier(barriers); } GLint GraphicsContext::elementType(GLint type) diff --git a/src/plugins/renderers/rhi/graphicshelpers/graphicscontext_p.h b/src/plugins/renderers/rhi/graphicshelpers/graphicscontext_p.h index 0583e3f11..89da47371 100644 --- a/src/plugins/renderers/rhi/graphicshelpers/graphicscontext_p.h +++ b/src/plugins/renderers/rhi/graphicshelpers/graphicscontext_p.h @@ -80,6 +80,10 @@ class QOpenGLShaderProgram; class QAbstractOpenGLFunctions; class QOpenGLDebugLogger; +class QRhi; +class QRhiSwapChain; +class QRhiResourceUpdateBatch; + namespace Qt3DRender { namespace Render { @@ -93,7 +97,6 @@ namespace Rhi { class GraphicsHelperInterface; class RHIShader; class RHIShaderManager; - typedef QPair NamedUniformLocation; class Q_AUTOTEST_EXPORT GraphicsContext @@ -103,7 +106,7 @@ public: ~GraphicsContext(); void setOpenGLContext(QOpenGLContext* ctx); - QOpenGLContext *openGLContext() { return m_gl; } + //QOpenGLContext *openGLContext() { return m_gl; } bool makeCurrent(QSurface *surface); void doneCurrent(); bool hasValidGLHelper() const; @@ -196,16 +199,20 @@ public: GLint m_maxTextureUnits; GLint m_maxImageUnits; GLuint m_defaultFBO; - QOpenGLContext *m_gl; - GraphicsHelperInterface *m_glHelper; + //* QOpenGLContext *m_gl; + //* GraphicsHelperInterface *m_glHelper; - QHash m_glHelpers; + //* QHash m_glHelpers; GraphicsApiFilterData m_contextInfo; QScopedPointer m_debugLogger; friend class RHIVertexArrayObject; RHIVertexArrayObject *m_currentVAO; + QRhi* m_rhi{}; + QRhiSwapChain* m_sc{}; + QRhiResourceUpdateBatch *m_currentUpdates{}; + void applyUniform(const ShaderUniform &description, const UniformValue &v); template @@ -223,8 +230,8 @@ void GraphicsContext::applyUniformHelper(const ShaderUniform &d template<> \ void GraphicsContext::applyUniformHelper(const ShaderUniform &description, const UniformValue &value) const \ { \ - const int count = qMin(description.m_size, int(value.byteSize() / description.m_rawByteSize)); \ - m_glHelper->Func(description.m_location, count, value.constData()); \ + /*/ const int count = qMin(description.m_size, int(value.byteSize() / description.m_rawByteSize)); \ + m_glHelper->Func(description.m_location, count, value.constData()); */ \ } diff --git a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp index f7ba1815d..23c1dcb33 100644 --- a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp +++ b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext.cpp @@ -159,6 +159,7 @@ void copyGLFramebufferDataToImage(QImage &img, const uchar *srcData, uint stride } // Render States Helpers +/* template void applyStateHelper(const GenericState *state, SubmissionContext *gc) { @@ -355,7 +356,7 @@ void applyStateHelper(const LineWidth *state, SubmissionContext *gc) gc->openGLContext()->functions()->glLineWidth(std::get<0>(values)); } - +*/ } // anonymous @@ -371,7 +372,6 @@ SubmissionContext::SubmissionContext() , m_currClearColorValue(0,0,0,0) , m_material(nullptr) , m_activeFBO(0) - , m_boundArrayBuffer(nullptr) , m_stateSet(nullptr) , m_renderer(nullptr) , m_uboTempArray(QByteArray(1024, 0)) @@ -396,33 +396,35 @@ void SubmissionContext::initialize() void SubmissionContext::resolveRenderTargetFormat() { - const QSurfaceFormat format = m_gl->format(); - const uint a = (format.alphaBufferSize() == -1) ? 0 : format.alphaBufferSize(); - const uint r = format.redBufferSize(); - const uint g = format.greenBufferSize(); - const uint b = format.blueBufferSize(); - -#define RGBA_BITS(r,g,b,a) (r | (g << 6) | (b << 12) | (a << 18)) - - const uint bits = RGBA_BITS(r,g,b,a); - switch (bits) { - case RGBA_BITS(8,8,8,8): - m_renderTargetFormat = QAbstractTexture::RGBA8_UNorm; - break; - case RGBA_BITS(8,8,8,0): - m_renderTargetFormat = QAbstractTexture::RGB8_UNorm; - break; - case RGBA_BITS(5,6,5,0): - m_renderTargetFormat = QAbstractTexture::R5G6B5; - break; - } -#undef RGBA_BITS + RHI_UNIMPLEMENTED; + +//* const QSurfaceFormat format = m_gl->format(); +//* const uint a = (format.alphaBufferSize() == -1) ? 0 : format.alphaBufferSize(); +//* const uint r = format.redBufferSize(); +//* const uint g = format.greenBufferSize(); +//* const uint b = format.blueBufferSize(); +//* +//* #define RGBA_BITS(r,g,b,a) (r | (g << 6) | (b << 12) | (a << 18)) +//* +//* const uint bits = RGBA_BITS(r,g,b,a); +//* switch (bits) { +//* case RGBA_BITS(8,8,8,8): +//* m_renderTargetFormat = QAbstractTexture::RGBA8_UNorm; +//* break; +//* case RGBA_BITS(8,8,8,0): +//* m_renderTargetFormat = QAbstractTexture::RGB8_UNorm; +//* break; +//* case RGBA_BITS(5,6,5,0): +//* m_renderTargetFormat = QAbstractTexture::R5G6B5; +//* break; +//* } +//* #undef RGBA_BITS } bool SubmissionContext::beginDrawing(QSurface *surface) { Q_ASSERT(surface); - Q_ASSERT(m_gl); +//* Q_ASSERT(m_gl); m_surface = surface; @@ -436,9 +438,9 @@ bool SubmissionContext::beginDrawing(QSurface *surface) // Makes the surface current on the OpenGLContext // and sets the right glHelper - m_ownCurrent = !(m_gl->surface() == m_surface); - if (m_ownCurrent && !makeCurrent(m_surface)) - return false; + // m_ownCurrent = !(m_gl->surface() == m_surface); + // if (m_ownCurrent && !makeCurrent(m_surface)) + // return false; // TODO: cache surface format somewhere rather than doing this every time render surface changes resolveRenderTargetFormat(); @@ -452,33 +454,41 @@ bool SubmissionContext::beginDrawing(QSurface *surface) if (!isInitialized()) initialize(); - initializeHelpers(m_surface); + // initializeHelpers(m_surface); // need to reset these values every frame, may get overwritten elsewhere - m_gl->functions()->glClearColor(m_currClearColorValue.redF(), m_currClearColorValue.greenF(), m_currClearColorValue.blueF(), m_currClearColorValue.alphaF()); - m_gl->functions()->glClearDepthf(m_currClearDepthValue); - m_gl->functions()->glClearStencil(m_currClearStencilValue); + RHI_UNIMPLEMENTED; +//* m_gl->functions()->glClearColor(m_currClearColorValue.redF(), m_currClearColorValue.greenF(), m_currClearColorValue.blueF(), m_currClearColorValue.alphaF()); +//* m_gl->functions()->glClearDepthf(m_currClearDepthValue); +//* m_gl->functions()->glClearStencil(m_currClearStencilValue); if (m_activeShader) { m_activeShader = nullptr; } - m_boundArrayBuffer = nullptr; + + m_rhi->beginFrame(m_sc); return true; } void SubmissionContext::endDrawing(bool swapBuffers) { - if (swapBuffers) - m_gl->swapBuffers(m_surface); - if (m_ownCurrent) - m_gl->doneCurrent(); + m_rhi->endFrame(m_sc, {}); + RHI_UNIMPLEMENTED; +//* if (swapBuffers) +//* m_gl->swapBuffers(m_surface); +//* if (m_ownCurrent) +//* m_gl->doneCurrent(); m_textureContext.endDrawing(); m_imageContext.endDrawing(); +//* static int i = 0; +//* if(i++ == 10) +//* std::exit(0); } void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, GLuint defaultFboId) { + RHI_UNIMPLEMENTED; GLuint fboId = defaultFboId; // Default FBO if (renderTargetNodeId) { // New RenderTarget @@ -488,246 +498,256 @@ void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeI // Insert FBO into hash m_renderTargets.insert(renderTargetNodeId, fboId); } else { + RHI_UNIMPLEMENTED; fboId = createRenderTarget(renderTargetNodeId, attachments); } } else { + RHI_UNIMPLEMENTED; fboId = updateRenderTarget(renderTargetNodeId, attachments, true); } } m_activeFBO = fboId; - m_glHelper->bindFrameBufferObject(m_activeFBO, GraphicsHelperInterface::FBODraw); +//* m_glHelper->bindFrameBufferObject(m_activeFBO, GraphicsHelperInterface::FBODraw); // Set active drawBuffers activateDrawBuffers(attachments); } GLuint SubmissionContext::createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments) { - const GLuint fboId = m_glHelper->createFrameBufferObject(); - if (fboId) { - // The FBO is created and its attachments are set once - // Insert FBO into hash - m_renderTargets.insert(renderTargetNodeId, fboId); - // Bind FBO - m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); - bindFrameBufferAttachmentHelper(fboId, attachments); - } else { - qCritical("Failed to create FBO"); - } - return fboId; + RHI_UNIMPLEMENTED; + return 0; +//* const GLuint fboId = m_glHelper->createFrameBufferObject(); +//* if (fboId) { +//* // The FBO is created and its attachments are set once +//* // Insert FBO into hash +//* m_renderTargets.insert(renderTargetNodeId, fboId); +//* // Bind FBO +//* m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); +//* bindFrameBufferAttachmentHelper(fboId, attachments); +//* } else { +//* qCritical("Failed to create FBO"); +//* } +//* return fboId; } GLuint SubmissionContext::updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget) { - const GLuint fboId = m_renderTargets.value(renderTargetNodeId); - - // We need to check if one of the attachment was resized - bool needsResize = !m_renderTargetsSize.contains(fboId); // not even initialized yet? - if (!needsResize) { - // render target exists, has attachment been resized? - RHITextureManager *rhiTextureManager = m_renderer->rhiResourceManagers()->rhiTextureManager(); - const QSize s = m_renderTargetsSize[fboId]; - const auto attachments_ = attachments.attachments(); - for (const Attachment &attachment : attachments_) { - RHITexture *rTex = rhiTextureManager->lookupResource(attachment.m_textureUuid); - // ### TODO QTBUG-64757 this check is insufficient since the - // texture may have changed to another one with the same size. That - // case is not handled atm. - if (rTex) { - needsResize |= rTex->size() != s; - if (isActiveRenderTarget && attachment.m_point == QRenderTargetOutput::Color0) - m_renderTargetFormat = rTex->properties().format; - } - } - } - - if (needsResize) { - m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); - bindFrameBufferAttachmentHelper(fboId, attachments); - } - - return fboId; + RHI_UNIMPLEMENTED; + return 0; +//* const GLuint fboId = m_renderTargets.value(renderTargetNodeId); +//* +//* // We need to check if one of the attachment was resized +//* bool needsResize = !m_renderTargetsSize.contains(fboId); // not even initialized yet? +//* if (!needsResize) { +//* // render target exists, has attachment been resized? +//* RHITextureManager *rhiTextureManager = m_renderer->rhiResourceManagers()->rhiTextureManager(); +//* const QSize s = m_renderTargetsSize[fboId]; +//* const auto attachments_ = attachments.attachments(); +//* for (const Attachment &attachment : attachments_) { +//* RHITexture *rTex = rhiTextureManager->lookupResource(attachment.m_textureUuid); +//* // ### TODO QTBUG-64757 this check is insufficient since the +//* // texture may have changed to another one with the same size. That +//* // case is not handled atm. +//* if (rTex) { +//* needsResize |= rTex->size() != s; +//* if (isActiveRenderTarget && attachment.m_point == QRenderTargetOutput::Color0) +//* m_renderTargetFormat = rTex->properties().format; +//* } +//* } +//* } +//* +//* if (needsResize) { +//* m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); +//* bindFrameBufferAttachmentHelper(fboId, attachments); +//* } +//* +//* return fboId; } QSize SubmissionContext::renderTargetSize(const QSize &surfaceSize) const { - QSize renderTargetSize; - if (m_activeFBO != m_defaultFBO) { - // For external FBOs we may not have a m_renderTargets entry. - if (m_renderTargetsSize.contains(m_activeFBO)) { - renderTargetSize = m_renderTargetsSize[m_activeFBO]; - } else if (surfaceSize.isValid()) { - renderTargetSize = surfaceSize; - } else { - // External FBO (when used with QtQuick2 Scene3D) - - // Query FBO color attachment 0 size - GLint attachmentObjectType = GL_NONE; - GLint attachment0Name = 0; - m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, - &attachmentObjectType); - m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, - &attachment0Name); - - if (attachmentObjectType == GL_RENDERBUFFER && m_glHelper->supportsFeature(GraphicsHelperInterface::RenderBufferDimensionRetrieval)) - renderTargetSize = m_glHelper->getRenderBufferDimensions(attachment0Name); - else if (attachmentObjectType == GL_TEXTURE && m_glHelper->supportsFeature(GraphicsHelperInterface::TextureDimensionRetrieval)) - // Assumes texture level 0 and GL_TEXTURE_2D target - renderTargetSize = m_glHelper->getTextureDimensions(attachment0Name, GL_TEXTURE_2D); - else - return renderTargetSize; - } - } else { - renderTargetSize = m_surface->size(); - if (m_surface->surfaceClass() == QSurface::Window) { - const float dpr = static_cast(m_surface)->devicePixelRatio(); - renderTargetSize *= dpr; - } - } - return renderTargetSize; + RHI_UNIMPLEMENTED; + return surfaceSize; +//* QSize renderTargetSize{}; +//* if (m_activeFBO != m_defaultFBO) { +//* // For external FBOs we may not have a m_renderTargets entry. +//* if (m_renderTargetsSize.contains(m_activeFBO)) { +//* renderTargetSize = m_renderTargetsSize[m_activeFBO]; +//* } else if (surfaceSize.isValid()) { +//* renderTargetSize = surfaceSize; +//* } else { +//* // External FBO (when used with QtQuick2 Scene3D) +//* +//* // Query FBO color attachment 0 size +//* GLint attachmentObjectType = GL_NONE; +//* GLint attachment0Name = 0; +//* m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, +//* GL_COLOR_ATTACHMENT0, +//* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, +//* &attachmentObjectType); +//* m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, +//* GL_COLOR_ATTACHMENT0, +//* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, +//* &attachment0Name); +//* +//* if (attachmentObjectType == GL_RENDERBUFFER && m_glHelper->supportsFeature(GraphicsHelperInterface::RenderBufferDimensionRetrieval)) +//* renderTargetSize = m_glHelper->getRenderBufferDimensions(attachment0Name); +//* else if (attachmentObjectType == GL_TEXTURE && m_glHelper->supportsFeature(GraphicsHelperInterface::TextureDimensionRetrieval)) +//* // Assumes texture level 0 and GL_TEXTURE_2D target +//* renderTargetSize = m_glHelper->getTextureDimensions(attachment0Name, GL_TEXTURE_2D); +//* else +//* return renderTargetSize; +//* } +//* } else { +//* renderTargetSize = m_surface->size(); +//* if (m_surface->surfaceClass() == QSurface::Window) { +//* const float dpr = static_cast(m_surface)->devicePixelRatio(); +//* renderTargetSize *= dpr; +//* } +//* } +//* return renderTargetSize; } QImage SubmissionContext::readFramebuffer(const QRect &rect) { - QImage img; - const unsigned int area = rect.width() * rect.height(); - unsigned int bytes; - GLenum format, type; - QImage::Format imageFormat; - uint stride; - - /* format value should match GL internalFormat */ - GLenum internalFormat = m_renderTargetFormat; - - switch (m_renderTargetFormat) { - case QAbstractTexture::RGBAFormat: - case QAbstractTexture::RGBA8_SNorm: - case QAbstractTexture::RGBA8_UNorm: - case QAbstractTexture::RGBA8U: - case QAbstractTexture::SRGB8_Alpha8: -#ifdef QT_OPENGL_ES_2 - format = GL_RGBA; - imageFormat = QImage::Format_RGBA8888_Premultiplied; -#else - format = GL_BGRA; - imageFormat = QImage::Format_ARGB32_Premultiplied; - internalFormat = GL_RGBA8; -#endif - type = GL_UNSIGNED_BYTE; - bytes = area * 4; - stride = rect.width() * 4; - break; - case QAbstractTexture::SRGB8: - case QAbstractTexture::RGBFormat: - case QAbstractTexture::RGB8U: - case QAbstractTexture::RGB8_UNorm: -#ifdef QT_OPENGL_ES_2 - format = GL_RGBA; - imageFormat = QImage::Format_RGBX8888; -#else - format = GL_BGRA; - imageFormat = QImage::Format_RGB32; - internalFormat = GL_RGB8; -#endif - type = GL_UNSIGNED_BYTE; - bytes = area * 4; - stride = rect.width() * 4; - break; -#ifndef QT_OPENGL_ES_2 - case QAbstractTexture::RG11B10F: - bytes = area * 4; - format = GL_RGB; - type = GL_UNSIGNED_INT_10F_11F_11F_REV; - imageFormat = QImage::Format_RGB30; - stride = rect.width() * 4; - break; - case QAbstractTexture::RGB10A2: - bytes = area * 4; - format = GL_RGBA; - type = GL_UNSIGNED_INT_2_10_10_10_REV; - imageFormat = QImage::Format_A2BGR30_Premultiplied; - stride = rect.width() * 4; - break; - case QAbstractTexture::R5G6B5: - bytes = area * 2; - format = GL_RGB; - type = GL_UNSIGNED_SHORT; - internalFormat = GL_UNSIGNED_SHORT_5_6_5_REV; - imageFormat = QImage::Format_RGB16; - stride = rect.width() * 2; - break; - case QAbstractTexture::RGBA16F: - case QAbstractTexture::RGBA16U: - case QAbstractTexture::RGBA32F: - case QAbstractTexture::RGBA32U: - bytes = area * 16; - format = GL_RGBA; - type = GL_FLOAT; - imageFormat = QImage::Format_ARGB32_Premultiplied; - stride = rect.width() * 16; - break; -#endif - default: - auto warning = qWarning(); - warning << "Unable to convert"; - QtDebugUtils::formatQEnum(warning, m_renderTargetFormat); - warning << "render target texture format to QImage."; - return img; - } - - GLint samples = 0; - m_gl->functions()->glGetIntegerv(GL_SAMPLES, &samples); - if (samples > 0 && !m_glHelper->supportsFeature(GraphicsHelperInterface::BlitFramebuffer)) { - qCWarning(Backend) << Q_FUNC_INFO << "Unable to capture multisampled framebuffer; " - "Required feature BlitFramebuffer is missing."; - return img; - } - - img = QImage(rect.width(), rect.height(), imageFormat); - - QScopedArrayPointer data(new uchar [bytes]); - - if (samples > 0) { - // resolve multisample-framebuffer to renderbuffer and read pixels from it - GLuint fbo, rb; - QOpenGLFunctions *gl = m_gl->functions(); - gl->glGenFramebuffers(1, &fbo); - gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); - gl->glGenRenderbuffers(1, &rb); - gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); - gl->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, rect.width(), rect.height()); - gl->glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); - - const GLenum status = gl->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - gl->glDeleteRenderbuffers(1, &rb); - gl->glDeleteFramebuffers(1, &fbo); - qCWarning(Backend) << Q_FUNC_INFO << "Copy-framebuffer not complete: " << status; - return img; - } - - m_glHelper->blitFramebuffer(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), - 0, 0, rect.width(), rect.height(), - GL_COLOR_BUFFER_BIT, GL_NEAREST); - gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); - gl->glReadPixels(0,0,rect.width(), rect.height(), format, type, data.data()); - - copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); - - gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); - gl->glDeleteRenderbuffers(1, &rb); - gl->glBindFramebuffer(GL_FRAMEBUFFER, m_activeFBO); - gl->glDeleteFramebuffers(1, &fbo); - } else { - // read pixels directly from framebuffer - m_gl->functions()->glReadPixels(rect.x(), rect.y(), rect.width(), rect.height(), format, type, data.data()); - copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); - } - - return img; + RHI_UNIMPLEMENTED; + return {}; +//* QImage img; +//* const unsigned int area = rect.width() * rect.height(); +//* unsigned int bytes; +//* GLenum format, type; +//* QImage::Format imageFormat; +//* uint stride; +//* +//* /* format value should match GL internalFormat */ +//* GLenum internalFormat = m_renderTargetFormat; +//* +//* switch (m_renderTargetFormat) { +//* case QAbstractTexture::RGBAFormat: +//* case QAbstractTexture::RGBA8_SNorm: +//* case QAbstractTexture::RGBA8_UNorm: +//* case QAbstractTexture::RGBA8U: +//* case QAbstractTexture::SRGB8_Alpha8: +//*#ifdef QT_OPENGL_ES_2 +//* format = GL_RGBA; +//* imageFormat = QImage::Format_RGBA8888_Premultiplied; +//*#else +//* format = GL_BGRA; +//* imageFormat = QImage::Format_ARGB32_Premultiplied; +//* internalFormat = GL_RGBA8; +//*#endif +//* type = GL_UNSIGNED_BYTE; +//* bytes = area * 4; +//* stride = rect.width() * 4; +//* break; +//* case QAbstractTexture::SRGB8: +//* case QAbstractTexture::RGBFormat: +//* case QAbstractTexture::RGB8U: +//* case QAbstractTexture::RGB8_UNorm: +//*#ifdef QT_OPENGL_ES_2 +//* format = GL_RGBA; +//* imageFormat = QImage::Format_RGBX8888; +//*#else +//* format = GL_BGRA; +//* imageFormat = QImage::Format_RGB32; +//* internalFormat = GL_RGB8; +//*#endif +//* type = GL_UNSIGNED_BYTE; +//* bytes = area * 4; +//* stride = rect.width() * 4; +//* break; +//*#ifndef QT_OPENGL_ES_2 +//* case QAbstractTexture::RG11B10F: +//* bytes = area * 4; +//* format = GL_RGB; +//* type = GL_UNSIGNED_INT_10F_11F_11F_REV; +//* imageFormat = QImage::Format_RGB30; +//* stride = rect.width() * 4; +//* break; +//* case QAbstractTexture::RGB10A2: +//* bytes = area * 4; +//* format = GL_RGBA; +//* type = GL_UNSIGNED_INT_2_10_10_10_REV; +//* imageFormat = QImage::Format_A2BGR30_Premultiplied; +//* stride = rect.width() * 4; +//* break; +//* case QAbstractTexture::R5G6B5: +//* bytes = area * 2; +//* format = GL_RGB; +//* type = GL_UNSIGNED_SHORT; +//* internalFormat = GL_UNSIGNED_SHORT_5_6_5_REV; +//* imageFormat = QImage::Format_RGB16; +//* stride = rect.width() * 2; +//* break; +//* case QAbstractTexture::RGBA16F: +//* case QAbstractTexture::RGBA16U: +//* case QAbstractTexture::RGBA32F: +//* case QAbstractTexture::RGBA32U: +//* bytes = area * 16; +//* format = GL_RGBA; +//* type = GL_FLOAT; +//* imageFormat = QImage::Format_ARGB32_Premultiplied; +//* stride = rect.width() * 16; +//* break; +//*#endif +//* default: +//* auto warning = qWarning(); +//* warning << "Unable to convert"; +//* QtDebugUtils::formatQEnum(warning, m_renderTargetFormat); +//* warning << "render target texture format to QImage."; +//* return img; +//* } +//* +//* GLint samples = 0; +//* m_gl->functions()->glGetIntegerv(GL_SAMPLES, &samples); +//* if (samples > 0 && !m_glHelper->supportsFeature(GraphicsHelperInterface::BlitFramebuffer)) { +//* qCWarning(Backend) << Q_FUNC_INFO << "Unable to capture multisampled framebuffer; " +//* "Required feature BlitFramebuffer is missing."; +//* return img; +//* } +//* +//* img = QImage(rect.width(), rect.height(), imageFormat); +//* +//* QScopedArrayPointer data(new uchar [bytes]); +//* +//* if (samples > 0) { +//* // resolve multisample-framebuffer to renderbuffer and read pixels from it +//* GLuint fbo, rb; +//* QOpenGLFunctions *gl = m_gl->functions(); +//* gl->glGenFramebuffers(1, &fbo); +//* gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); +//* gl->glGenRenderbuffers(1, &rb); +//* gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); +//* gl->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, rect.width(), rect.height()); +//* gl->glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); +//* +//* const GLenum status = gl->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); +//* if (status != GL_FRAMEBUFFER_COMPLETE) { +//* gl->glDeleteRenderbuffers(1, &rb); +//* gl->glDeleteFramebuffers(1, &fbo); +//* qCWarning(Backend) << Q_FUNC_INFO << "Copy-framebuffer not complete: " << status; +//* return img; +//* } +//* +//* m_glHelper->blitFramebuffer(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), +//* 0, 0, rect.width(), rect.height(), +//* GL_COLOR_BUFFER_BIT, GL_NEAREST); +//* gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); +//* gl->glReadPixels(0,0,rect.width(), rect.height(), format, type, data.data()); +//* +//* copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); +//* +//* gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); +//* gl->glDeleteRenderbuffers(1, &rb); +//* gl->glBindFramebuffer(GL_FRAMEBUFFER, m_activeFBO); +//* gl->glDeleteFramebuffers(1, &fbo); +//* } else { +//* // read pixels directly from framebuffer +//* m_gl->functions()->glReadPixels(rect.x(), rect.y(), rect.width(), rect.height(), format, type, data.data()); +//* copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); +//* } +//* +//* return img; } void SubmissionContext::setViewport(const QRectF &viewport, const QSize &surfaceSize) @@ -751,10 +771,12 @@ void SubmissionContext::setViewport(const QRectF &viewport, const QSize &surface // 1 0---------------------> 1 // The Viewport is defined between 0 and 1 which allows us to automatically // scale to the size of the provided window surface - m_gl->functions()->glViewport(m_viewport.x() * size.width(), - (1.0 - m_viewport.y() - m_viewport.height()) * size.height(), - m_viewport.width() * size.width(), - m_viewport.height() * size.height()); + + RHI_UNIMPLEMENTED; + //* m_gl->functions()->glViewport(m_viewport.x() * size.width(), + //* (1.0 - m_viewport.y() - m_viewport.height()) * size.height(), + //* m_viewport.width() * size.width(), + //* m_viewport.height() * size.height()); } void SubmissionContext::releaseOpenGL() @@ -771,83 +793,87 @@ void SubmissionContext::releaseOpenGL() // The OpenGLContext is not current on any surface at this point void SubmissionContext::setOpenGLContext(QOpenGLContext* ctx) { - Q_ASSERT(ctx); - - releaseOpenGL(); - m_gl = ctx; + RHI_UNIMPLEMENTED; + //* Q_ASSERT(ctx); + //* + //* releaseOpenGL(); + //* m_gl = ctx; } // Called only from RenderThread bool SubmissionContext::activateShader(RHIShader *shader) { - if (shader->shaderProgram() != m_activeShader) { - // Ensure material uniforms are re-applied - m_material = nullptr; - - m_activeShader = shader->shaderProgram(); - if (Q_LIKELY(m_activeShader != nullptr)) { - m_activeShader->bind(); - } else { - m_glHelper->useProgram(0); - qWarning() << "No shader program found"; - return false; - } - } + RHI_UNIMPLEMENTED; + //* if (shader->shaderProgram() != m_activeShader) { + //* // Ensure material uniforms are re-applied + //* m_material = nullptr; + //* + //* m_activeShader = shader->shaderProgram(); + //* if (Q_LIKELY(m_activeShader != nullptr)) { + //* m_activeShader->bind(); + //* } else { + //* m_glHelper->useProgram(0); + //* qWarning() << "No shader program found"; + //* return false; + //* } + //* } return true; } void SubmissionContext::bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments) { + RHI_UNIMPLEMENTED; // Set FBO attachments. These are normally textures, except that on Open GL // ES <= 3.1 we must use a renderbuffer if a combined depth+stencil is // desired since this cannot be achieved neither with a single texture (not // before GLES 3.2) nor with separate textures (no suitable format for // stencil before 3.1 with the appropriate extension). - QSize fboSize; - RHITextureManager *rhiTextureManager = m_renderer->rhiResourceManagers()->rhiTextureManager(); - const auto attachments_ = attachments.attachments(); - for (const Attachment &attachment : attachments_) { - RHITexture *rTex = rhiTextureManager->lookupResource(attachment.m_textureUuid); - if (!m_glHelper->frameBufferNeedsRenderBuffer(attachment)) { - QOpenGLTexture *glTex = rTex ? rTex->getGLTexture() : nullptr; - if (glTex != nullptr) { - // The texture can not be rendered simultaniously by another renderer - Q_ASSERT(!rTex->isExternalRenderingEnabled()); - if (fboSize.isEmpty()) - fboSize = QSize(glTex->width(), glTex->height()); - else - fboSize = QSize(qMin(fboSize.width(), glTex->width()), qMin(fboSize.height(), glTex->height())); - m_glHelper->bindFrameBufferAttachment(glTex, attachment); - } - } else { - RenderBuffer *renderBuffer = rTex ? rTex->getOrCreateRenderBuffer() : nullptr; - if (renderBuffer) { - if (fboSize.isEmpty()) - fboSize = QSize(renderBuffer->width(), renderBuffer->height()); - else - fboSize = QSize(qMin(fboSize.width(), renderBuffer->width()), qMin(fboSize.height(), renderBuffer->height())); - m_glHelper->bindFrameBufferAttachment(renderBuffer, attachment); - } - } - } - m_renderTargetsSize.insert(fboId, fboSize); + //* QSize fboSize; + //* RHITextureManager *rhiTextureManager = m_renderer->rhiResourceManagers()->rhiTextureManager(); + //* const auto attachments_ = attachments.attachments(); + //* for (const Attachment &attachment : attachments_) { + //* RHITexture *rTex = rhiTextureManager->lookupResource(attachment.m_textureUuid); + //* if (!m_glHelper->frameBufferNeedsRenderBuffer(attachment)) { + //* QOpenGLTexture *glTex = rTex ? rTex->getGLTexture() : nullptr; + //* if (glTex != nullptr) { + //* // The texture can not be rendered simultaniously by another renderer + //* Q_ASSERT(!rTex->isExternalRenderingEnabled()); + //* if (fboSize.isEmpty()) + //* fboSize = QSize(glTex->width(), glTex->height()); + //* else + //* fboSize = QSize(qMin(fboSize.width(), glTex->width()), qMin(fboSize.height(), glTex->height())); + //* m_glHelper->bindFrameBufferAttachment(glTex, attachment); + //* } + //* } else { + //* RenderBuffer *renderBuffer = rTex ? rTex->getOrCreateRenderBuffer() : nullptr; + //* if (renderBuffer) { + //* if (fboSize.isEmpty()) + //* fboSize = QSize(renderBuffer->width(), renderBuffer->height()); + //* else + //* fboSize = QSize(qMin(fboSize.width(), renderBuffer->width()), qMin(fboSize.height(), renderBuffer->height())); + //* m_glHelper->bindFrameBufferAttachment(renderBuffer, attachment); + //* } + //* } + //* } + //* m_renderTargetsSize.insert(fboId, fboSize); } void SubmissionContext::activateDrawBuffers(const AttachmentPack &attachments) { - const QVector activeDrawBuffers = attachments.getGlDrawBuffers(); - - if (m_glHelper->checkFrameBufferComplete()) { - if (activeDrawBuffers.size() > 1) {// We need MRT - if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT)) { - // Set up MRT, glDrawBuffers... - m_glHelper->drawBuffers(activeDrawBuffers.size(), activeDrawBuffers.data()); - } - } - } else { - qCWarning(Backend) << "FBO incomplete"; - } + RHI_UNIMPLEMENTED; + //* const QVector activeDrawBuffers = attachments.getGlDrawBuffers(); + //* + //* if (m_glHelper->checkFrameBufferComplete()) { + //* if (activeDrawBuffers.size() > 1) {// We need MRT + //* if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT)) { + //* // Set up MRT, glDrawBuffers... + //* m_glHelper->drawBuffers(activeDrawBuffers.size(), activeDrawBuffers.data()); + //* } + //* } + //* } else { + //* qCWarning(Backend) << "FBO incomplete"; + //* } } @@ -877,185 +903,188 @@ RenderStateSet *SubmissionContext::currentStateSet() const void SubmissionContext::applyState(const StateVariant &stateVariant) { - switch (stateVariant.type) { - - case AlphaCoverageStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - case AlphaTestMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - case BlendStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - case BlendEquationArgumentsMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - case MSAAEnabledStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case CullFaceStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case DepthWriteStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case DepthTestStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case DepthRangeMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case RasterModeMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case FrontFaceStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case ScissorStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case StencilTestStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case PointSizeMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case PolygonOffsetStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case ColorStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case ClipPlaneMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case SeamlessCubemapMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case StencilOpMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case StencilWriteStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case DitheringStateMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - - case LineWidthMask: { - applyStateHelper(static_cast(stateVariant.constState()), this); - break; - } - default: - Q_UNREACHABLE(); - } + RHI_UNIMPLEMENTED; + +//* switch (stateVariant.type) { +//* +//* case AlphaCoverageStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* case AlphaTestMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* case BlendStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* case BlendEquationArgumentsMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* case MSAAEnabledStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case CullFaceStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case DepthWriteStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case DepthTestStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case DepthRangeMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case RasterModeMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case FrontFaceStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case ScissorStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case StencilTestStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case PointSizeMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case PolygonOffsetStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case ColorStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case ClipPlaneMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case SeamlessCubemapMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case StencilOpMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case StencilWriteStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case DitheringStateMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* +//* case LineWidthMask: { +//* applyStateHelper(static_cast(stateVariant.constState()), this); +//* break; +//* } +//* default: +//* Q_UNREACHABLE(); +//* } } void SubmissionContext::resetMasked(qint64 maskOfStatesToReset) { - // TO DO -> Call gcHelper methods instead of raw GL - // QOpenGLFunctions shouldn't be used here directly - QOpenGLFunctions *funcs = m_gl->functions(); - - if (maskOfStatesToReset & ScissorStateMask) - funcs->glDisable(GL_SCISSOR_TEST); - - if (maskOfStatesToReset & BlendStateMask) - funcs->glDisable(GL_BLEND); - - if (maskOfStatesToReset & StencilWriteStateMask) - funcs->glStencilMask(0); - - if (maskOfStatesToReset & StencilTestStateMask) - funcs->glDisable(GL_STENCIL_TEST); - - if (maskOfStatesToReset & DepthRangeMask) - depthRange(0.0f, 1.0f); - - if (maskOfStatesToReset & DepthTestStateMask) - funcs->glDisable(GL_DEPTH_TEST); - - if (maskOfStatesToReset & DepthWriteStateMask) - funcs->glDepthMask(GL_TRUE); // reset to default - - if (maskOfStatesToReset & FrontFaceStateMask) - funcs->glFrontFace(GL_CCW); // reset to default - - if (maskOfStatesToReset & CullFaceStateMask) - funcs->glDisable(GL_CULL_FACE); - - if (maskOfStatesToReset & DitheringStateMask) - funcs->glDisable(GL_DITHER); - - if (maskOfStatesToReset & AlphaCoverageStateMask) - setAlphaCoverageEnabled(false); - - if (maskOfStatesToReset & PointSizeMask) - pointSize(false, 1.0f); // reset to default - - if (maskOfStatesToReset & PolygonOffsetStateMask) - funcs->glDisable(GL_POLYGON_OFFSET_FILL); - - if (maskOfStatesToReset & ColorStateMask) - funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - if (maskOfStatesToReset & ClipPlaneMask) { - GLint max = maxClipPlaneCount(); - for (GLint i = 0; i < max; ++i) - disableClipPlane(i); - } - - if (maskOfStatesToReset & SeamlessCubemapMask) - setSeamlessCubemap(false); - - if (maskOfStatesToReset & StencilOpMask) - funcs->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - if (maskOfStatesToReset & LineWidthMask) - funcs->glLineWidth(1.0f); - -#ifndef QT_OPENGL_ES_2 - if (maskOfStatesToReset & RasterModeMask) - m_glHelper->rasterMode(GL_FRONT_AND_BACK, GL_FILL); -#endif + RHI_UNIMPLEMENTED; +//* // TO DO -> Call gcHelper methods instead of raw GL +//* // QOpenGLFunctions shouldn't be used here directly +//* QOpenGLFunctions *funcs = m_gl->functions(); +//* +//* if (maskOfStatesToReset & ScissorStateMask) +//* funcs->glDisable(GL_SCISSOR_TEST); +//* +//* if (maskOfStatesToReset & BlendStateMask) +//* funcs->glDisable(GL_BLEND); +//* +//* if (maskOfStatesToReset & StencilWriteStateMask) +//* funcs->glStencilMask(0); +//* +//* if (maskOfStatesToReset & StencilTestStateMask) +//* funcs->glDisable(GL_STENCIL_TEST); +//* +//* if (maskOfStatesToReset & DepthRangeMask) +//* depthRange(0.0f, 1.0f); +//* +//* if (maskOfStatesToReset & DepthTestStateMask) +//* funcs->glDisable(GL_DEPTH_TEST); +//* +//* if (maskOfStatesToReset & DepthWriteStateMask) +//* funcs->glDepthMask(GL_TRUE); // reset to default +//* +//* if (maskOfStatesToReset & FrontFaceStateMask) +//* funcs->glFrontFace(GL_CCW); // reset to default +//* +//* if (maskOfStatesToReset & CullFaceStateMask) +//* funcs->glDisable(GL_CULL_FACE); +//* +//* if (maskOfStatesToReset & DitheringStateMask) +//* funcs->glDisable(GL_DITHER); +//* +//* if (maskOfStatesToReset & AlphaCoverageStateMask) +//* setAlphaCoverageEnabled(false); +//* +//* if (maskOfStatesToReset & PointSizeMask) +//* pointSize(false, 1.0f); // reset to default +//* +//* if (maskOfStatesToReset & PolygonOffsetStateMask) +//* funcs->glDisable(GL_POLYGON_OFFSET_FILL); +//* +//* if (maskOfStatesToReset & ColorStateMask) +//* funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +//* +//* if (maskOfStatesToReset & ClipPlaneMask) { +//* GLint max = maxClipPlaneCount(); +//* for (GLint i = 0; i < max; ++i) +//* disableClipPlane(i); +//* } +//* +//* if (maskOfStatesToReset & SeamlessCubemapMask) +//* setSeamlessCubemap(false); +//* +//* if (maskOfStatesToReset & StencilOpMask) +//* funcs->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); +//* +//* if (maskOfStatesToReset & LineWidthMask) +//* funcs->glLineWidth(1.0f); +//* +//* #ifndef QT_OPENGL_ES_2 +//* if (maskOfStatesToReset & RasterModeMask) +//* m_glHelper->rasterMode(GL_FRONT_AND_BACK, GL_FILL); +//* #endif } void SubmissionContext::applyStateSet(RenderStateSet *ss) @@ -1088,53 +1117,63 @@ void SubmissionContext::applyStateSet(RenderStateSet *ss) void SubmissionContext::clearColor(const QColor &color) { - if (m_currClearColorValue != color) { - m_currClearColorValue = color; - m_gl->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); - } + RHI_UNIMPLEMENTED; +//* if (m_currClearColorValue != color) { +//* m_currClearColorValue = color; +//* m_gl->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); +//* } } void SubmissionContext::clearDepthValue(float depth) { - if (m_currClearDepthValue != depth) { - m_currClearDepthValue = depth; - m_gl->functions()->glClearDepthf(depth); - } + RHI_UNIMPLEMENTED; +//* if (m_currClearDepthValue != depth) { +//* m_currClearDepthValue = depth; +//* m_gl->functions()->glClearDepthf(depth); +//* } } void SubmissionContext::clearStencilValue(int stencil) { - if (m_currClearStencilValue != stencil) { - m_currClearStencilValue = stencil; - m_gl->functions()->glClearStencil(stencil); - } + RHI_UNIMPLEMENTED; +//* if (m_currClearStencilValue != stencil) { +//* m_currClearStencilValue = stencil; +//* m_gl->functions()->glClearStencil(stencil); +//* } } RHIFence SubmissionContext::fenceSync() { - return m_glHelper->fenceSync(); + RHI_UNIMPLEMENTED; + return {}; +//* return m_glHelper->fenceSync(); } void SubmissionContext::clientWaitSync(RHIFence sync, GLuint64 nanoSecTimeout) { - qDebug() << Q_FUNC_INFO << sync; - m_glHelper->clientWaitSync(sync, nanoSecTimeout); + RHI_UNIMPLEMENTED; +//* qDebug() << Q_FUNC_INFO << sync; +//* m_glHelper->clientWaitSync(sync, nanoSecTimeout); } void SubmissionContext::waitSync(RHIFence sync) { - qDebug() << Q_FUNC_INFO << sync; - m_glHelper->waitSync(sync); + RHI_UNIMPLEMENTED; +//* qDebug() << Q_FUNC_INFO << sync; +//* m_glHelper->waitSync(sync); } bool SubmissionContext::wasSyncSignaled(RHIFence sync) { - return m_glHelper->wasSyncSignaled(sync); + RHI_UNIMPLEMENTED; + return true; +//* return m_glHelper->wasSyncSignaled(sync); } void SubmissionContext::deleteSync(RHIFence sync) { - m_glHelper->deleteSync(sync); + RHI_UNIMPLEMENTED; +//* m_glHelper->deleteSync(sync); } // It will be easier if the QGraphicContext applies the QUniformPack @@ -1155,31 +1194,33 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) // Fill Texture Uniform Value with proper texture units // so that they can be applied as regular uniforms in a second step for (int i = 0; i < parameterPack.textures().size(); ++i) { - const ShaderParameterPack::NamedResource &namedTex = parameterPack.textures().at(i); - // Given a Texture QNodeId, we retrieve the associated shared RHITexture - if (uniformValues.contains(namedTex.glslNameId)) { - RHITexture *t = m_renderer->rhiResourceManagers()->rhiTextureManager()->lookupResource(namedTex.nodeId); - if (t != nullptr) { - UniformValue &texUniform = uniformValues.value(namedTex.glslNameId); - if (texUniform.valueType() == UniformValue::TextureValue) { - const int texUnit = m_textureContext.activateTexture(TextureSubmissionContext::TextureScopeMaterial, m_gl, t); - texUniform.data()[namedTex.uniformArrayIndex] = texUnit; - if (texUnit == -1) { - if (namedTex.glslNameId != irradianceId && - namedTex.glslNameId != specularId) { - // Only return false if we are not dealing with env light textures - qCWarning(Backend) << "Unable to find suitable Texture Unit"; - return false; - } - } - } - } - } + RHI_UNIMPLEMENTED; + //* const ShaderParameterPack::NamedResource &namedTex = parameterPack.textures().at(i); + //* // Given a Texture QNodeId, we retrieve the associated shared RHITexture + //* if (uniformValues.contains(namedTex.glslNameId)) { + //* RHITexture *t = m_renderer->rhiResourceManagers()->rhiTextureManager()->lookupResource(namedTex.nodeId); + //* if (t != nullptr) { + //* UniformValue &texUniform = uniformValues.value(namedTex.glslNameId); + //* if (texUniform.valueType() == UniformValue::TextureValue) { + //* const int texUnit = m_textureContext.activateTexture(TextureSubmissionContext::TextureScopeMaterial, m_gl, t); + //* texUniform.data()[namedTex.uniformArrayIndex] = texUnit; + //* if (texUnit == -1) { + //* if (namedTex.glslNameId != irradianceId && + //* namedTex.glslNameId != specularId) { + //* // Only return false if we are not dealing with env light textures + //* qCWarning(Backend) << "Unable to find suitable Texture Unit"; + //* return false; + //* } + //* } + //* } + //* } + //* } } // Fill Image Uniform Value with proper image units // so that they can be applied as regular uniforms in a second step for (int i = 0; i < parameterPack.images().size(); ++i) { + RHI_UNIMPLEMENTED; const ShaderParameterPack::NamedResource &namedTex = parameterPack.images().at(i); // Given a Texture QNodeId, we retrieve the associated shared RHITexture if (uniformValues.contains(namedTex.glslNameId)) { @@ -1212,6 +1253,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) // Bind Shader Storage block to SSBO and update SSBO const QVector blockToSSBOs = parameterPack.shaderStorageBuffers(); for (const BlockToSSBO b : blockToSSBOs) { + RHI_UNIMPLEMENTED; Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); RHIBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer); // bindShaderStorageBlock @@ -1231,6 +1273,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) const QVector blockToUBOs = parameterPack.uniformBuffers(); int uboIndex = 0; for (const BlockToUBO &b : blockToUBOs) { + RHI_UNIMPLEMENTED; Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); RHIBuffer *ubo = glBufferForRenderBuffer(cpuBuffer); bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex); @@ -1264,26 +1307,29 @@ bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) void SubmissionContext::enableAttribute(const VAOVertexAttribute &attr) { - // Bind buffer within the current VAO - RHIBuffer *buf = m_renderer->rhiResourceManagers()->rhiBufferManager()->data(attr.bufferHandle); - Q_ASSERT(buf); - bindGLBuffer(buf, attr.attributeType); - - // Don't use QOpenGLShaderProgram::setAttributeBuffer() because of QTBUG-43199. - // Use the introspection data and set the attribute explicitly - m_glHelper->enableVertexAttributeArray(attr.location); - m_glHelper->vertexAttributePointer(attr.shaderDataType, - attr.location, - attr.vertexSize, - attr.dataType, - GL_TRUE, // TODO: Support normalization property on QAttribute - attr.byteStride, - reinterpret_cast(qintptr(attr.byteOffset))); - - - // Done by the helper if it supports it - if (attr.divisor != 0) - m_glHelper->vertexAttribDivisor(attr.location, attr.divisor); + RHI_UNIMPLEMENTED; +//* // Bind buffer within the current VAO +//* RHIBuffer *buf = m_renderer->rhiResourceManagers()->rhiBufferManager()->data(attr.bufferHandle); +//* Q_ASSERT(buf); +//* bindGLBuffer(buf, attr.attributeType); +//* +//* // Don't use QOpenGLShaderProgram::setAttributeBuffer() because of QTBUG-43199. +//* // Use the introspection data and set the attribute explicitly +//* m_glHelper->enableVertexAttributeArray(attr.location); +//* m_glHelper->vertexAttributePointer(attr.shaderDataType, +//* attr.location, +//* attr.vertexSize, +//* attr.dataType, +//* GL_TRUE, // TODO: Support normalization property on QAttribute +//* attr.byteStride, +//* reinterpret_cast(qintptr(attr.byteOffset))); +//* +//* +//* // Done by the helper if it supports it +//* if (attr.divisor != 0) +//* { +//* m_glHelper->vertexAttribDivisor(attr.location, attr.divisor); +//* } } void SubmissionContext::disableAttribute(const SubmissionContext::VAOVertexAttribute &attr) @@ -1404,32 +1450,19 @@ RHIBuffer *SubmissionContext::glBufferForRenderBuffer(Buffer *buf) HRHIBuffer SubmissionContext::createGLBufferFor(Buffer *buffer) { - RHIBuffer *b = m_renderer->rhiResourceManagers()->rhiBufferManager()->getOrCreateResource(buffer->peerId()); - // b.setUsagePattern(static_cast(buffer->usage())); - Q_ASSERT(b); - if (!b->create(this)) - qCWarning(Io) << Q_FUNC_INFO << "buffer creation failed"; - + m_renderer->rhiResourceManagers()->rhiBufferManager()->getOrCreateResource(buffer->peerId()); return m_renderer->rhiResourceManagers()->rhiBufferManager()->lookupHandle(buffer->peerId()); } bool SubmissionContext::bindGLBuffer(RHIBuffer *buffer, RHIBuffer::Type type) { - if (type == RHIBuffer::ArrayBuffer && buffer == m_boundArrayBuffer) - return true; - - if (buffer->bind(this, type)) { - if (type == RHIBuffer::ArrayBuffer) - m_boundArrayBuffer = buffer; - return true; - } - return false; + return buffer->bind(this, type); } void SubmissionContext::uploadDataToGLBuffer(Buffer *buffer, RHIBuffer *b, bool releaseBuffer) { - if (!bindGLBuffer(b, RHIBuffer::ArrayBuffer)) // We're uploading, the type doesn't matter here - qCWarning(Io) << Q_FUNC_INFO << "buffer bind failed"; + // if (!bindGLBuffer(b, RHIBuffer::ArrayBuffer)) // We're uploading, the type doesn't matter here + // qCWarning(Io) << Q_FUNC_INFO << "buffer bind failed"; // If the buffer is dirty (hence being called here) // there are two possible cases // * setData was called changing the whole data or functor (or the usage pattern) @@ -1457,20 +1490,18 @@ void SubmissionContext::uploadDataToGLBuffer(Buffer *buffer, RHIBuffer *b, bool } // TO DO: based on the number of updates .., it might make sense to // sometime use glMapBuffer rather than glBufferSubData - b->update(this, update->data.constData(), update->data.size(), update->offset); + b->update(this, update->data, update->offset); } else { // We have an update that was done by calling QBuffer::setData // which is used to resize or entirely clear the buffer // Note: we use the buffer data directly in that case - const int bufferSize = buffer->data().size(); - b->allocate(this, bufferSize, false); // orphan the buffer - b->allocate(this, buffer->data().constData(), bufferSize, false); + b->orphan(this); // orphan the buffer + b->allocate(this, buffer->data(), false); } } if (releaseBuffer) { b->release(this); - m_boundArrayBuffer = nullptr; } qCDebug(Io) << "uploaded buffer size=" << buffer->data().size(); } @@ -1492,81 +1523,82 @@ void SubmissionContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, QBlitFramebuffer::InterpolationMethod interpolationMethod) { - GLuint inputFboId = defaultFboId; - bool inputBufferIsDefault = true; - if (!inputRenderTargetId.isNull()) { - RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(inputRenderTargetId); - if (renderTarget) { - AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); - if (m_renderTargets.contains(inputRenderTargetId)) - inputFboId = updateRenderTarget(inputRenderTargetId, attachments, false); - else - inputFboId = createRenderTarget(inputRenderTargetId, attachments); - } - inputBufferIsDefault = false; - } - - GLuint outputFboId = defaultFboId; - bool outputBufferIsDefault = true; - if (!outputRenderTargetId.isNull()) { - RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(outputRenderTargetId); - if (renderTarget) { - AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); - if (m_renderTargets.contains(outputRenderTargetId)) - outputFboId = updateRenderTarget(outputRenderTargetId, attachments, false); - else - outputFboId = createRenderTarget(outputRenderTargetId, attachments); - } - outputBufferIsDefault = false; - } - - // Up until this point the input and output rects are normal Qt rectangles. - // Convert them to GL rectangles (Y at bottom). - const int inputFboHeight = inputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[inputFboId].height(); - const GLint srcX0 = inputRect.left(); - const GLint srcY0 = inputFboHeight - (inputRect.top() + inputRect.height()); - const GLint srcX1 = srcX0 + inputRect.width(); - const GLint srcY1 = srcY0 + inputRect.height(); - - const int outputFboHeight = outputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[outputFboId].height(); - const GLint dstX0 = outputRect.left(); - const GLint dstY0 = outputFboHeight - (outputRect.top() + outputRect.height()); - const GLint dstX1 = dstX0 + outputRect.width(); - const GLint dstY1 = dstY0 + outputRect.height(); - - //Get the last bounded framebuffers - const GLuint lastDrawFboId = boundFrameBufferObject(); - - // Activate input framebuffer for reading - bindFramebuffer(inputFboId, GraphicsHelperInterface::FBORead); - - // Activate output framebuffer for writing - bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw); - - //Bind texture - if (!inputBufferIsDefault) - readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); - - if (!outputBufferIsDefault) { - // Note that we use glDrawBuffers, not glDrawBuffer. The - // latter is not available with GLES. - const int buf = outputAttachmentPoint; - drawBuffers(1, &buf); - } - - // Blit framebuffer - const GLenum mode = interpolationMethod ? GL_NEAREST : GL_LINEAR; - m_glHelper->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, - mode); - - // Reset draw buffer - bindFramebuffer(lastDrawFboId, GraphicsHelperInterface::FBOReadAndDraw); - if (outputAttachmentPoint != QRenderTargetOutput::Color0) { - const int buf = QRenderTargetOutput::Color0; - drawBuffers(1, &buf); - } + RHI_UNIMPLEMENTED; +//* GLuint inputFboId = defaultFboId; +//* bool inputBufferIsDefault = true; +//* if (!inputRenderTargetId.isNull()) { +//* RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(inputRenderTargetId); +//* if (renderTarget) { +//* AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); +//* if (m_renderTargets.contains(inputRenderTargetId)) +//* inputFboId = updateRenderTarget(inputRenderTargetId, attachments, false); +//* else +//* inputFboId = createRenderTarget(inputRenderTargetId, attachments); +//* } +//* inputBufferIsDefault = false; +//* } +//* +//* GLuint outputFboId = defaultFboId; +//* bool outputBufferIsDefault = true; +//* if (!outputRenderTargetId.isNull()) { +//* RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(outputRenderTargetId); +//* if (renderTarget) { +//* AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); +//* if (m_renderTargets.contains(outputRenderTargetId)) +//* outputFboId = updateRenderTarget(outputRenderTargetId, attachments, false); +//* else +//* outputFboId = createRenderTarget(outputRenderTargetId, attachments); +//* } +//* outputBufferIsDefault = false; +//* } +//* +//* // Up until this point the input and output rects are normal Qt rectangles. +//* // Convert them to GL rectangles (Y at bottom). +//* const int inputFboHeight = inputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[inputFboId].height(); +//* const GLint srcX0 = inputRect.left(); +//* const GLint srcY0 = inputFboHeight - (inputRect.top() + inputRect.height()); +//* const GLint srcX1 = srcX0 + inputRect.width(); +//* const GLint srcY1 = srcY0 + inputRect.height(); +//* +//* const int outputFboHeight = outputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[outputFboId].height(); +//* const GLint dstX0 = outputRect.left(); +//* const GLint dstY0 = outputFboHeight - (outputRect.top() + outputRect.height()); +//* const GLint dstX1 = dstX0 + outputRect.width(); +//* const GLint dstY1 = dstY0 + outputRect.height(); +//* +//* //Get the last bounded framebuffers +//* const GLuint lastDrawFboId = boundFrameBufferObject(); +//* +//* // Activate input framebuffer for reading +//* bindFramebuffer(inputFboId, GraphicsHelperInterface::FBORead); +//* +//* // Activate output framebuffer for writing +//* bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw); +//* +//* //Bind texture +//* if (!inputBufferIsDefault) +//* readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); +//* +//* if (!outputBufferIsDefault) { +//* // Note that we use glDrawBuffers, not glDrawBuffer. The +//* // latter is not available with GLES. +//* const int buf = outputAttachmentPoint; +//* drawBuffers(1, &buf); +//* } +//* +//* // Blit framebuffer +//* const GLenum mode = interpolationMethod ? GL_NEAREST : GL_LINEAR; +//* m_glHelper->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, +//* dstX0, dstY0, dstX1, dstY1, +//* GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, +//* mode); +//* +//* // Reset draw buffer +//* bindFramebuffer(lastDrawFboId, GraphicsHelperInterface::FBOReadAndDraw); +//* if (outputAttachmentPoint != QRenderTargetOutput::Color0) { +//* const int buf = QRenderTargetOutput::Color0; +//* drawBuffers(1, &buf); +//* } } } // namespace Rhi diff --git a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h index 602dc7e35..de64aed74 100644 --- a/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h +++ b/src/plugins/renderers/rhi/graphicshelpers/submissioncontext_p.h @@ -200,7 +200,6 @@ private: QRectF m_viewport; GLuint m_activeFBO; - RHIBuffer *m_boundArrayBuffer; RenderStateSet* m_stateSet; Renderer *m_renderer; QByteArray m_uboTempArray; diff --git a/src/plugins/renderers/rhi/io/buffer.cpp b/src/plugins/renderers/rhi/io/buffer.cpp index d8ed97e30..697cf841a 100644 --- a/src/plugins/renderers/rhi/io/buffer.cpp +++ b/src/plugins/renderers/rhi/io/buffer.cpp @@ -62,6 +62,7 @@ #define GL_DRAW_INDIRECT_BUFFER 0x8F3F #endif +#include QT_BEGIN_NAMESPACE namespace Qt3DRender { @@ -89,57 +90,122 @@ GLenum glBufferTypes[] = { RHIBuffer::RHIBuffer() : m_bufferId(0) - , m_isCreated(false) - , m_bound(false) + , m_dynamic(true) , m_lastTarget(GL_ARRAY_BUFFER) { } bool RHIBuffer::bind(GraphicsContext *ctx, Type t) { - if (m_bufferId == 0) - return false; - m_lastTarget = glBufferTypes[t]; - ctx->openGLContext()->functions()->glBindBuffer(m_lastTarget, m_bufferId); - m_bound = true; + assert(ctx->m_currentUpdates); + if(this->m_datasToUpload.empty()) + return bool(m_rhiBuffer); + + if(!m_rhiBuffer) + { + const auto kind = m_dynamic ? QRhiBuffer::Dynamic : QRhiBuffer::Static; + const auto usage = [&] { + if(t == Type::ArrayBuffer) return QRhiBuffer::VertexBuffer; + if(t == Type::IndexBuffer) return QRhiBuffer::IndexBuffer; + if(t == Type::UniformBuffer) return QRhiBuffer::UniformBuffer; + RHI_UNIMPLEMENTED; + return QRhiBuffer::StorageBuffer; + }(); + + if(m_allocSize <= 0) + return false; + + if(m_rhiBuffer && m_rhiBuffer->type() != t) + { + m_rhiBuffer->release(); + delete m_rhiBuffer; + m_rhiBuffer = nullptr; + } + + if(!m_rhiBuffer) + { + m_rhiBuffer = ctx->m_rhi->newBuffer(kind, usage, m_allocSize); + } + assert(m_rhiBuffer); + + m_rhiBuffer->build(); + { + // debug: set to zero + char* ptr = (char*)alloca(m_allocSize); + std::fill_n(ptr, m_allocSize, 0); + if(m_dynamic) + { + ctx->m_currentUpdates->updateDynamicBuffer(m_rhiBuffer, 0, m_allocSize, ptr); + } + else + { + ctx->m_currentUpdates->uploadStaticBuffer(m_rhiBuffer, 0, m_allocSize, ptr); + } + } + } + + if(m_dynamic) + { + for(const auto& [data, offset] : this->m_datasToUpload) + { + ctx->m_currentUpdates->updateDynamicBuffer(m_rhiBuffer, offset, data.size(), data.constData()); + } + } + else + { + for(const auto& [data, offset] : this->m_datasToUpload) + { + ctx->m_currentUpdates->uploadStaticBuffer(m_rhiBuffer, offset, data.size(), data.constData()); + } + } + this->m_datasToUpload.clear(); return true; } bool RHIBuffer::release(GraphicsContext *ctx) { - m_bound = false; - ctx->openGLContext()->functions()->glBindBuffer(m_lastTarget, 0); + if(m_rhiBuffer) + m_rhiBuffer->release(); return true; } bool RHIBuffer::create(GraphicsContext *ctx) { - ctx->openGLContext()->functions()->glGenBuffers(1, &m_bufferId); - m_isCreated = true; - return m_bufferId != 0; + return true; } void RHIBuffer::destroy(GraphicsContext *ctx) { - ctx->openGLContext()->functions()->glDeleteBuffers(1, &m_bufferId); - m_isCreated = false; + if(m_rhiBuffer) + { + m_rhiBuffer->releaseAndDestroyLater(); + m_rhiBuffer = nullptr; + } + m_allocSize = 0; } -void RHIBuffer::allocate(GraphicsContext *ctx, uint size, bool dynamic) +void RHIBuffer::orphan(GraphicsContext *) { - // Either GL_STATIC_DRAW OR GL_DYNAMIC_DRAW depending on the use case - // TO DO: find a way to know how a buffer/QShaderData will be used to use the right usage - ctx->openGLContext()->functions()->glBufferData(m_lastTarget, size, NULL, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + m_datasToUpload.clear(); + if(m_rhiBuffer) + { + m_rhiBuffer->releaseAndDestroyLater(); + m_rhiBuffer = nullptr; + } + m_allocSize = 0; } -void RHIBuffer::allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic) +void RHIBuffer::allocate(GraphicsContext *ctx, const QByteArray& data, bool dynamic) { - ctx->openGLContext()->functions()->glBufferData(m_lastTarget, size, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + m_datasToUpload.clear(); + m_datasToUpload.push_back({data, 0}); + m_allocSize = data.size(); + m_dynamic = dynamic; } -void RHIBuffer::update(GraphicsContext *ctx, const void *data, uint size, int offset) +void RHIBuffer::update(GraphicsContext *ctx, const QByteArray& data, int offset) { - ctx->openGLContext()->functions()->glBufferSubData(m_lastTarget, offset, size, data); + m_datasToUpload.push_back({data, offset}); } QByteArray RHIBuffer::download(GraphicsContext *ctx, uint size) diff --git a/src/plugins/renderers/rhi/io/buffer_p.h b/src/plugins/renderers/rhi/io/buffer_p.h index 49c88a50e..43092d3e6 100644 --- a/src/plugins/renderers/rhi/io/buffer_p.h +++ b/src/plugins/renderers/rhi/io/buffer_p.h @@ -56,7 +56,7 @@ #include QT_BEGIN_NAMESPACE - +class QRhiBuffer; namespace Qt3DRender { namespace Render { @@ -85,22 +85,24 @@ public: bool release(GraphicsContext *ctx); bool create(GraphicsContext *ctx); void destroy(GraphicsContext *ctx); - void allocate(GraphicsContext *ctx, uint size, bool dynamic = true); - void allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic = true); - void update(GraphicsContext *ctx, const void *data, uint size, int offset = 0); + void orphan(GraphicsContext *ctx); + void allocate(GraphicsContext *ctx, const QByteArray& data, bool dynamic = true); + void update(GraphicsContext *ctx, const QByteArray& data, int offset = 0); QByteArray download(GraphicsContext *ctx, uint size); void bindBufferBase(GraphicsContext *ctx, int bindingPoint, Type t); void bindBufferBase(GraphicsContext *ctx, int bindingPoint); - inline GLuint bufferId() const { return m_bufferId; } - inline bool isCreated() const { return m_isCreated; } - inline bool isBound() const { return m_bound; } + QRhiBuffer* rhiBuffer() const noexcept { return m_rhiBuffer; } private: GLuint m_bufferId; - bool m_isCreated; - bool m_bound; + bool m_dynamic; + int m_allocSize{}; GLenum m_lastTarget; + + QRhiBuffer* m_rhiBuffer{}; + + std::vector> m_datasToUpload; }; } // namespace Rhi diff --git a/src/plugins/renderers/rhi/managers/handle_types_p.h b/src/plugins/renderers/rhi/managers/handle_types_p.h index 06ecab34d..6fdf21658 100644 --- a/src/plugins/renderers/rhi/managers/handle_types_p.h +++ b/src/plugins/renderers/rhi/managers/handle_types_p.h @@ -75,6 +75,7 @@ typedef Qt3DCore::QHandle HRHITexture; } // namespace Qt3DRender +#define RHI_UNIMPLEMENTED do { qDebug() << "Unimplemented: " << __PRETTY_FUNCTION__; } while(0) QT_END_NAMESPACE #endif // QT3DRENDER_RENDER_RHI_HANDLE_TYPES_P_H diff --git a/src/plugins/renderers/rhi/renderer/commandexecuter.cpp b/src/plugins/renderers/rhi/renderer/commandexecuter.cpp index 4cbd65dbf..b4794100c 100644 --- a/src/plugins/renderers/rhi/renderer/commandexecuter.cpp +++ b/src/plugins/renderers/rhi/renderer/commandexecuter.cpp @@ -304,83 +304,85 @@ CommandExecuter::CommandExecuter(Render::Rhi::Renderer *renderer) // Render thread void CommandExecuter::performAsynchronousCommandExecution(const QVector &views) { - QMutexLocker lock(&m_pendingCommandsMutex); - const QVector shellCommands = std::move(m_pendingCommands); - lock.unlock(); - - for (auto *reply : shellCommands) { - if (reply->commandName() == QLatin1String("glinfo")) { - QJsonObject replyObj; - const GraphicsApiFilterData *contextInfo = m_renderer->submissionContext()->contextInfo(); - if (contextInfo != nullptr) { - replyObj.insert(QLatin1String("api"), - contextInfo->m_api == QGraphicsApiFilter::OpenGL - ? QLatin1String("OpenGL") - : QLatin1String("OpenGLES")); - const QString versionString = - QString::number(contextInfo->m_major) - + QStringLiteral(".") - + QString::number(contextInfo->m_minor); - replyObj.insert(QLatin1String("version"), versionString); - replyObj.insert(QLatin1String("profile"), - contextInfo->m_profile == QGraphicsApiFilter::CoreProfile - ? QLatin1String("Core") - : contextInfo->m_profile == QGraphicsApiFilter::CompatibilityProfile - ? QLatin1String("Compatibility") - : QLatin1String("None")); - } - reply->setData(QJsonDocument(replyObj).toJson()); - } else if (reply->commandName() == QLatin1String("rendercommands")) { - QJsonObject replyObj; - - QJsonArray viewArray; - for (Render::Rhi::RenderView *v : views) { - QJsonObject viewObj; - viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport())); - viewObj.insert(QLatin1String("surfaceSize"), typeToJsonValue(v->surfaceSize())); - viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio()); - viewObj.insert(QLatin1String("noDraw"), v->noDraw()); - viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling()); - viewObj.insert(QLatin1String("compute"), v->isCompute()); - viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue()); - viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue()); - - QJsonArray renderCommandsArray; - for (Render::Rhi::RenderCommand &c : v->commands()) { - QJsonObject commandObj; - Render::NodeManagers *nodeManagers = m_renderer->nodeManagers(); - commandObj.insert(QLatin1String("shader"), typeToJsonValue(QVariant::fromValue(c.m_shaderId))); - commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle())); - commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount); - commandObj.insert(QLatin1String("geometry"), backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager())); - commandObj.insert(QLatin1String("geometryRenderer"), backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager())); - commandObj.insert(QLatin1String("shaderParameterPack"), parameterPackToJson(c.m_parameterPack)); - - renderCommandsArray.push_back(commandObj); - } - viewObj.insert(QLatin1String("commands"), renderCommandsArray); - viewArray.push_back(viewObj); - } - - replyObj.insert(QLatin1String("renderViews"), viewArray); - reply->setData(QJsonDocument(replyObj).toJson()); - } - reply->setFinished(true); - } + RHI_UNIMPLEMENTED; +//* QMutexLocker lock(&m_pendingCommandsMutex); +//* const QVector shellCommands = std::move(m_pendingCommands); +//* lock.unlock(); +//* +//* for (auto *reply : shellCommands) { +//* if (reply->commandName() == QLatin1String("glinfo")) { +//* QJsonObject replyObj; +//* const GraphicsApiFilterData *contextInfo = m_renderer->submissionContext()->contextInfo(); +//* if (contextInfo != nullptr) { +//* replyObj.insert(QLatin1String("api"), +//* contextInfo->m_api == QGraphicsApiFilter::OpenGL +//* ? QLatin1String("OpenGL") +//* : QLatin1String("OpenGLES")); +//* const QString versionString = +//* QString::number(contextInfo->m_major) +//* + QStringLiteral(".") +//* + QString::number(contextInfo->m_minor); +//* replyObj.insert(QLatin1String("version"), versionString); +//* replyObj.insert(QLatin1String("profile"), +//* contextInfo->m_profile == QGraphicsApiFilter::CoreProfile +//* ? QLatin1String("Core") +//* : contextInfo->m_profile == QGraphicsApiFilter::CompatibilityProfile +//* ? QLatin1String("Compatibility") +//* : QLatin1String("None")); +//* } +//* reply->setData(QJsonDocument(replyObj).toJson()); +//* } else if (reply->commandName() == QLatin1String("rendercommands")) { +//* QJsonObject replyObj; +//* +//* QJsonArray viewArray; +//* for (Render::Rhi::RenderView *v : views) { +//* QJsonObject viewObj; +//* viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport())); +//* viewObj.insert(QLatin1String("surfaceSize"), typeToJsonValue(v->surfaceSize())); +//* viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio()); +//* viewObj.insert(QLatin1String("noDraw"), v->noDraw()); +//* viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling()); +//* viewObj.insert(QLatin1String("compute"), v->isCompute()); +//* viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue()); +//* viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue()); +//* +//* QJsonArray renderCommandsArray; +//* for (Render::Rhi::RenderCommand &c : v->commands()) { +//* QJsonObject commandObj; +//* Render::NodeManagers *nodeManagers = m_renderer->nodeManagers(); +//* commandObj.insert(QLatin1String("shader"), typeToJsonValue(QVariant::fromValue(c.m_shaderId))); +//* commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle())); +//* commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount); +//* commandObj.insert(QLatin1String("geometry"), backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager())); +//* commandObj.insert(QLatin1String("geometryRenderer"), backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager())); +//* commandObj.insert(QLatin1String("shaderParameterPack"), parameterPackToJson(c.m_parameterPack)); +//* +//* renderCommandsArray.push_back(commandObj); +//* } +//* viewObj.insert(QLatin1String("commands"), renderCommandsArray); +//* viewArray.push_back(viewObj); +//* } +//* +//* replyObj.insert(QLatin1String("renderViews"), viewArray); +//* reply->setData(QJsonDocument(replyObj).toJson()); +//* } +//* reply->setFinished(true); +//* } } // Main thread QVariant CommandExecuter::executeCommand(const QStringList &args) { - // Note: The replies will be deleted by the AspectCommandDebugger - if (args.length() > 0 && - (args.first() == QLatin1String("glinfo") || - args.first() == QLatin1String("rendercommands"))) { - auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first()); - QMutexLocker lock(&m_pendingCommandsMutex); - m_pendingCommands.push_back(reply); - return QVariant::fromValue(reply); - } + RHI_UNIMPLEMENTED; +//* // Note: The replies will be deleted by the AspectCommandDebugger +//* if (args.length() > 0 && +//* (args.first() == QLatin1String("glinfo") || +//* args.first() == QLatin1String("rendercommands"))) { +//* auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first()); +//* QMutexLocker lock(&m_pendingCommandsMutex); +//* m_pendingCommands.push_back(reply); +//* return QVariant::fromValue(reply); +//* } return QVariant(); } diff --git a/src/plugins/renderers/rhi/renderer/rendercommand_p.h b/src/plugins/renderers/rhi/renderer/rendercommand_p.h index 19dfb89c3..25ffab3e6 100644 --- a/src/plugins/renderers/rhi/renderer/rendercommand_p.h +++ b/src/plugins/renderers/rhi/renderer/rendercommand_p.h @@ -61,8 +61,11 @@ #include #include #include +#include QT_BEGIN_NAMESPACE +class QRhiGraphicsPipeline; +class QRhiShaderResourceBindings; class QOpenGLVertexArrayObject; @@ -103,6 +106,8 @@ public: float m_depth; int m_changeCost; + QRhiShaderResourceBindings *srb = nullptr; + QRhiGraphicsPipeline *ps = nullptr; enum CommandType { Draw, Compute @@ -127,6 +132,11 @@ public: bool m_drawIndirect; bool m_primitiveRestartEnabled; bool m_isValid; + + QVarLengthArray vertex_input; + + const Attribute* indexAttribute{}; + QRhiBuffer* indexBuffer{}; }; Q_AUTOTEST_EXPORT bool operator==(const RenderCommand &a, const RenderCommand &b) noexcept; diff --git a/src/plugins/renderers/rhi/renderer/renderer.cpp b/src/plugins/renderers/rhi/renderer/renderer.cpp index ffc304bb4..0d588ef41 100644 --- a/src/plugins/renderers/rhi/renderer/renderer.cpp +++ b/src/plugins/renderers/rhi/renderer/renderer.cpp @@ -95,6 +95,11 @@ #include #include +#include +#include +#include +#include + #include #include #include @@ -121,12 +126,13 @@ #include #include +#include +#include QT_BEGIN_NAMESPACE // Crashes on AMD Radeon drivers on Windows. Disable for now. //#define SHADER_LOADING_IN_COMMAND_THREAD - using namespace Qt3DCore; namespace Qt3DRender { @@ -242,7 +248,6 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_exposed(0) , m_lastFrameCorrect(0) , m_glContext(nullptr) - , m_shareContext(nullptr) , m_pickBoundingVolumeJob(PickBoundingVolumeJobPtr::create()) , m_rayCastingJob(RayCastingJobPtr::create()) , m_time(0) @@ -408,11 +413,7 @@ NodeManagers *Renderer::nodeManagers() const */ QOpenGLContext *Renderer::shareContext() const { - QMutexLocker lock(&m_shareContextMutex); - return m_shareContext ? m_shareContext - : (m_submissionContext->openGLContext() - ? m_submissionContext->openGLContext()->shareContext() - : nullptr); + return nullptr; } // Executed in the reloadDirtyShader job @@ -480,10 +481,83 @@ void Renderer::initialize() m_submissionContext.reset(new SubmissionContext); m_submissionContext->setRenderer(this); + + // RHI initialization + { + qCDebug(Backend) << Q_FUNC_INFO << "Requesting renderer initialize"; + + { + auto windows = qApp->allWindows(); + Q_ASSERT(!windows.empty()); + auto window = windows.front(); +// m_r = QRhi::create(QRhi::Null, nullptr); + + switch(window->surfaceType()) + { + case QSurface::VulkanSurface: + { + QRhiVulkanInitParams params; + params.window = window; + params.inst = window->vulkanInstance(); + m_r = QRhi::create(QRhi::Vulkan, ¶ms, QRhi::EnableDebugMarkers); + break; + } + case QSurface::OpenGLSurface: + { + m_fallbackSurface = QRhiGles2InitParams::newFallbackSurface(); + QRhiGles2InitParams params; + params.window = window; + params.format = this->m_format; + params.fallbackSurface = m_fallbackSurface; + m_r = QRhi::create(QRhi::OpenGLES2, ¶ms, QRhi::EnableDebugMarkers); + break; + } + case QSurface::MetalSurface: + { + QRhiMetalInitParams params; + m_r = QRhi::create(QRhi::Metal, ¶ms, QRhi::EnableDebugMarkers); + break; + } + } + Q_ASSERT(m_r); + + const int samples = this->format().samples(); + m_sc = m_r->newSwapChain(); + // allow depth-stencil, although we do not actually enable depth test/write for the triangle + m_ds = m_r->newRenderBuffer(QRhiRenderBuffer::DepthStencil, + QSize(), // no need to set the size yet + samples, + QRhiRenderBuffer::UsedWithSwapChainOnly); + m_sc->setWindow(window); + m_sc->setDepthStencil(m_ds); + m_sc->setSampleCount(samples); + m_sc->setFlags(QRhiSwapChain::Flags {}); + m_rp = m_sc->newCompatibleRenderPassDescriptor(); + m_sc->setRenderPassDescriptor(m_rp); + } +/* + // Awake setScenegraphRoot in case it was waiting + m_waitForInitializationToBeCompleted.release(1); + + // Allow the aspect manager to proceed + m_vsyncFrameAdvanceService->proceedToNextFrame(); + + // Force initial refresh + markDirty(AllDirty, nullptr);*/ + } + + + + + + + + + + /* QOpenGLContext* ctx = m_glContext; { - QMutexLocker lock(&m_shareContextMutex); // If we are using our own context (not provided by QtQuick), // we need to create it if (!m_glContext) { @@ -518,15 +592,6 @@ void Renderer::initialize() qCDebug(Backend) << "Qt3D shared context:" << ctx->shareContext(); qCDebug(Backend) << "Qt global shared context:" << qt_gl_global_share_context(); - if (!ctx->shareContext()) { - m_shareContext = new QOpenGLContext; - if (ctx->screen()) - m_shareContext->setScreen(ctx->screen()); - m_shareContext->setFormat(ctx->format()); - m_shareContext->setShareContext(ctx); - m_shareContext->create(); - } - // Note: we don't have a surface at this point // The context will be made current later on (at render time) m_submissionContext->setOpenGLContext(ctx); @@ -539,6 +604,7 @@ void Renderer::initialize() m_format = ctx->format(); QMetaObject::invokeMethod(m_offscreenHelper, "createOffscreenSurface"); } + */ // Awake setScenegraphRoot in case it was waiting m_waitForInitializationToBeCompleted.release(1); @@ -619,47 +685,65 @@ void Renderer::releaseGraphicsResources() return; } - QOpenGLContext *context = m_submissionContext->openGLContext(); - Q_ASSERT(context); + //* QOpenGLContext *context = m_submissionContext->openGLContext(); + //* Q_ASSERT(context); + //* + //* if (context->thread() == QThread::currentThread() && context->makeCurrent(offscreenSurface)) { + //* + //* // Clean up the graphics context and any resources + //* const QVector activeTexturesHandles = m_RHIResourceManagers->rhiTextureManager()->activeHandles(); + //* for (const HRHITexture &textureHandle : activeTexturesHandles) { + //* RHITexture *tex = m_RHIResourceManagers->rhiTextureManager()->data(textureHandle); + //* tex->destroy(); + //* } + //* + //* // Do the same thing with buffers + //* const QVector activeBuffers = m_RHIResourceManagers->rhiBufferManager()->activeHandles(); + //* for (const HRHIBuffer &bufferHandle : activeBuffers) { + //* RHIBuffer *buffer = m_RHIResourceManagers->rhiBufferManager()->data(bufferHandle); + //* buffer->destroy(m_submissionContext.data()); + //* } + //* + //* // Do the same thing with shaders + //* const QVector shaders = m_RHIResourceManagers->rhiShaderManager()->takeActiveResources(); + //* qDeleteAll(shaders); + //* + //* // Do the same thing with VAOs + //* const QVector activeVaos = m_RHIResourceManagers->vaoManager()->activeHandles(); + //* for (const HVao &vaoHandle : activeVaos) { + //* RHIVertexArrayObject *vao = m_RHIResourceManagers->vaoManager()->data(vaoHandle); + //* vao->destroy(); + //* } + //* + //* context->doneCurrent(); + //* } else { + //* qWarning() << "Failed to make context current: OpenGL resources will not be destroyed"; + //* } + //* + //* if (m_ownedContext) + //* delete context; - if (context->thread() == QThread::currentThread() && context->makeCurrent(offscreenSurface)) { + m_submissionContext.reset(nullptr); - // Clean up the graphics context and any resources - const QVector activeTexturesHandles = m_RHIResourceManagers->rhiTextureManager()->activeHandles(); - for (const HRHITexture &textureHandle : activeTexturesHandles) { - RHITexture *tex = m_RHIResourceManagers->rhiTextureManager()->data(textureHandle); - tex->destroy(); - } + // Free RHI resources + { + qCDebug(Backend) << Q_FUNC_INFO; + delete m_rp; + m_rp = nullptr; - // Do the same thing with buffers - const QVector activeBuffers = m_RHIResourceManagers->rhiBufferManager()->activeHandles(); - for (const HRHIBuffer &bufferHandle : activeBuffers) { - RHIBuffer *buffer = m_RHIResourceManagers->rhiBufferManager()->data(bufferHandle); - buffer->destroy(m_submissionContext.data()); - } + delete m_ds; + m_ds = nullptr; - // Do the same thing with shaders - const QVector shaders = m_RHIResourceManagers->rhiShaderManager()->takeActiveResources(); - qDeleteAll(shaders); + delete m_sc; + m_sc = nullptr; - // Do the same thing with VAOs - const QVector activeVaos = m_RHIResourceManagers->vaoManager()->activeHandles(); - for (const HVao &vaoHandle : activeVaos) { - RHIVertexArrayObject *vao = m_RHIResourceManagers->vaoManager()->data(vaoHandle); - vao->destroy(); - } + delete m_r; + m_r = nullptr; - context->doneCurrent(); - } else { - qWarning() << "Failed to make context current: OpenGL resources will not be destroyed"; + // delete m_fallbackSurface; + // m_fallbackSurface = nullptr; } - if (m_ownedContext) - delete context; - if (m_shareContext) - delete m_shareContext; - - m_submissionContext.reset(nullptr); qCDebug(Backend) << Q_FUNC_INFO << "Renderer properly shutdown"; } @@ -750,6 +834,15 @@ void Renderer::render() } } +QShader getShader(const QString &name) +{ + QFile f(name); + if (f.open(QIODevice::ReadOnly)) + return QShader::fromSerialized(f.readAll()); + + return QShader(); +} + // Either called by render if Qt3D is in charge of the RenderThread // or by QRenderAspectPrivate::renderSynchronous (for Scene3D) void Renderer::doRender(bool swapBuffers) @@ -799,6 +892,16 @@ void Renderer::doRender(bool swapBuffers) // Reset state for each draw if we don't have complete control of the context if (!m_ownedContext) m_submissionContext->setCurrentStateSet(nullptr); + + const QSize outputSize = m_sc->surfacePixelSize(); + + m_ds->setPixelSize(outputSize); + m_ds->build(); // == m_ds->release(); m_ds->build(); + + m_hasSwapChain = m_sc->buildOrResize(); + m_submissionContext->m_rhi = this->m_r; + m_submissionContext->m_sc = this->m_sc; + m_submissionContext->m_currentUpdates = this->m_r->nextResourceUpdateBatch(); beganDrawing = m_submissionContext->beginDrawing(surface); if (beganDrawing) { // 1) Execute commands for buffer uploads, texture updates, shader loading first @@ -953,6 +1056,84 @@ QSurfaceFormat Renderer::format() { return m_format; } +void Renderer::setupRHICommand(RenderCommand& cmd) +{ + auto shaders = cmd.m_glShader->shaderCode(); + if(shaders.empty()) + return; + + // Create UBOs + auto standard_ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, sizeof(float) * 16); + standard_ubuf->build(); + QMatrix4x4 ident; + this->m_submissionContext->m_currentUpdates->updateDynamicBuffer(standard_ubuf, 0, sizeof(float) * 16, ident.data()); + + auto custom_ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, sizeof(float) * 1); + custom_ubuf->build(); + static float f{0.5}; + this->m_submissionContext->m_currentUpdates->updateDynamicBuffer(custom_ubuf, 0, sizeof(float), &f); + + + cmd.srb = m_r->newShaderResourceBindings(); + cmd.srb->setBindings({ + QRhiShaderResourceBinding::uniformBuffer( + 0, + QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, + standard_ubuf), + QRhiShaderResourceBinding::uniformBuffer( + 1, + QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, + custom_ubuf), + }); + cmd.srb->build(); + + + // Create pipeline + cmd.ps = m_r->newGraphicsPipeline(); + auto vert = shaders[0]; + auto frag = shaders[1]; + QShaderBaker b; + b.setGeneratedShaders({ + {QShader::SpirvShader, 100}, + {QShader::GlslShader, 120}, // Only GLSL version supported by RHI right now. + {QShader::HlslShader, 100}, + {QShader::MslShader, 100}, + }); + b.setGeneratedShaderVariants({QShader::Variant{}, + QShader::Variant{}, + QShader::Variant{}, + QShader::Variant{}}); + + b.setSourceString(vert, QShader::VertexStage); + auto vs = b.bake(); + if(b.errorMessage() != QString{}) + qDebug() << "Vertex Shader Error: " << b.errorMessage(); + + b.setSourceString(frag, QShader::FragmentStage); + auto fs = b.bake(); + if(b.errorMessage() != QString{}) + qDebug() << "Fragment Shader Error: " << b.errorMessage(); + + cmd.ps->setShaderStages({ + { QRhiShaderStage::Vertex, vs }, + { QRhiShaderStage::Fragment, fs } + }); + + QRhiVertexInputLayout inputLayout; + inputLayout.setBindings({ + { 3 * sizeof(float) } + }); + inputLayout.setAttributes({ + { 0, 0, QRhiVertexInputAttribute::Float3, 0 }, + //{ 0, 1, QRhiVertexInputAttribute::Float4, 3 * sizeof(float) } + }); + + cmd.ps->setVertexInputLayout(inputLayout); + cmd.ps->setShaderResourceBindings(cmd.srb); + cmd.ps->setRenderPassDescriptor(m_rp); + + cmd.ps->build(); +} // When this function is called, we must not be processing the commands for frame n+1 void Renderer::prepareCommandsSubmission(const QVector &renderViews) @@ -968,6 +1149,7 @@ void Renderer::prepareCommandsSubmission(const QVector &renderView Geometry *rGeometry = m_nodesManager->data(command.m_geometry); GeometryRenderer *rGeometryRenderer = m_nodesManager->data(command.m_geometryRenderer); RHIShader *shader = command.m_glShader; + Q_ASSERT(shader); // We should never have inserted a command for which these are null // in the first place @@ -1002,7 +1184,7 @@ void Renderer::prepareCommandsSubmission(const QVector &renderView if (!command.m_activeAttributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) { Profiling::GLTimeRecorder recorder(Profiling::VAOUpload); // Activate shader - m_submissionContext->activateShader(shader); + // m_submissionContext->activateShader(shader); // Bind VAO vao->bind(); // Update or set Attributes and Buffers for the given rGeometry and Command @@ -1021,7 +1203,10 @@ void Renderer::prepareCommandsSubmission(const QVector &renderView // Prepare the ShaderParameterPack based on the active uniforms of the shader shader->prepareUniforms(command.m_parameterPack); + setupRHICommand(command); + } else if (command.m_type == RenderCommand::Compute) { + RHI_UNIMPLEMENTED; RHIShader *shader = command.m_glShader; Q_ASSERT(shader); @@ -1353,6 +1538,7 @@ void Renderer::updateGLResources() Profiling::GLTimeRecorder recorder(Profiling::TextureUpload); const QVector activeTextureHandles = std::move(m_dirtyTextures); for (const HTexture &handle: activeTextureHandles) { + RHI_UNIMPLEMENTED; Texture *texture = m_nodesManager->textureManager()->data(handle); // Can be null when using Scene3D rendering @@ -1371,6 +1557,7 @@ void Renderer::updateGLResources() const QVector glTextureHandles = rhiTextureManager->activeHandles(); // Upload texture data for (const HRHITexture &glTextureHandle : glTextureHandles) { + RHI_UNIMPLEMENTED; RHITexture *glTexture = rhiTextureManager->data(glTextureHandle); // We create/update the actual GL texture using the GL context at this point @@ -1402,6 +1589,7 @@ void Renderer::updateGLResources() // Render Thread void Renderer::updateTexture(Texture *texture) { + RHI_UNIMPLEMENTED; // Check that the current texture images are still in place, if not, do not update const bool isValid = texture->isValid(m_nodesManager->textureImageManager()); if (!isValid) { @@ -1584,6 +1772,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVectorinsertFenceIds(); RHIFenceManager *fenceManager = m_RHIResourceManagers->rhiFenceManager(); for (const Qt3DCore::QNodeId insertFenceId : insertFenceIds) { + RHI_UNIMPLEMENTED; // If the fence is not in the manager, then it hasn't been inserted // into the command stream yet. if (fenceManager->find(insertFenceId) == fenceManager->end()) { @@ -1601,6 +1790,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector waitFences = renderView->waitFences(); for (const QWaitFenceData &waitFence : waitFences) { + RHI_UNIMPLEMENTED; // TO DO if (waitFence.handleType != QWaitFence::OpenGLFenceId) { qWarning() << "WaitFence handleType should be OpenGLFenceId when using the Qt 3D OpenGL renderer"; @@ -1640,6 +1830,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVectorcurrentContext() at the moment it was called (either // renderViewStateSet or m_defaultRenderStateSet) if (!renderView->renderCaptureNodeId().isNull()) { - const QRenderCaptureRequest request = renderView->renderCaptureRequest(); - const QSize size = m_submissionContext->renderTargetSize(renderView->surfaceSize()); - QRect rect(QPoint(0, 0), size); - if (!request.rect.isEmpty()) - rect = rect.intersected(request.rect); - QImage image; - if (!rect.isEmpty()) { - // Bind fbo as read framebuffer - m_submissionContext->bindFramebuffer(m_submissionContext->activeFBO(), GraphicsHelperInterface::FBORead); - image = m_submissionContext->readFramebuffer(rect); - } else { - qWarning() << "Requested capture rectangle is outside framebuffer"; - } - Render::RenderCapture *renderCapture = - static_cast(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId())); - renderCapture->addRenderCapture(request.captureId, image); - if (!m_pendingRenderCaptureSendRequests.contains(renderView->renderCaptureNodeId())) - m_pendingRenderCaptureSendRequests.push_back(renderView->renderCaptureNodeId()); + RHI_UNIMPLEMENTED; +//* const QRenderCaptureRequest request = renderView->renderCaptureRequest(); +//* const QSize size = m_submissionContext->renderTargetSize(renderView->surfaceSize()); +//* QRect rect(QPoint(0, 0), size); +//* if (!request.rect.isEmpty()) +//* rect = rect.intersected(request.rect); +//* QImage image; +//* if (!rect.isEmpty()) { +//* // Bind fbo as read framebuffer +//* m_submissionContext->bindFramebuffer(m_submissionContext->activeFBO(), GraphicsHelperInterface::FBORead); +//* image = m_submissionContext->readFramebuffer(rect); +//* } else { +//* qWarning() << "Requested capture rectangle is outside framebuffer"; +//* } +//* Render::RenderCapture *renderCapture = +//* static_cast(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId())); +//* renderCapture->addRenderCapture(request.captureId, image); +//* if (!m_pendingRenderCaptureSendRequests.contains(renderView->renderCaptureNodeId())) +//* m_pendingRenderCaptureSendRequests.push_back(renderView->renderCaptureNodeId()); } if (renderView->isDownloadBuffersEnable()) - downloadGLBuffers(); + { + RHI_UNIMPLEMENTED; +//* downloadGLBuffers(); + } // Perform BlitFramebuffer operations if (renderView->hasBlitFramebufferInfo()) { - const auto &blitFramebufferInfo = renderView->blitFrameBufferInfo(); - const QNodeId inputTargetId = blitFramebufferInfo.sourceRenderTargetId; - const QNodeId outputTargetId = blitFramebufferInfo.destinationRenderTargetId; - const QRect inputRect = blitFramebufferInfo.sourceRect; - const QRect outputRect = blitFramebufferInfo.destinationRect; - const QRenderTargetOutput::AttachmentPoint inputAttachmentPoint = blitFramebufferInfo.sourceAttachmentPoint; - const QRenderTargetOutput::AttachmentPoint outputAttachmentPoint = blitFramebufferInfo.destinationAttachmentPoint; - const QBlitFramebuffer::InterpolationMethod interpolationMethod = blitFramebufferInfo.interpolationMethod; - m_submissionContext->blitFramebuffer(inputTargetId, outputTargetId, inputRect, outputRect, lastBoundFBOId, - inputAttachmentPoint, outputAttachmentPoint, - interpolationMethod); + RHI_UNIMPLEMENTED; +//* const auto &blitFramebufferInfo = renderView->blitFrameBufferInfo(); +//* const QNodeId inputTargetId = blitFramebufferInfo.sourceRenderTargetId; +//* const QNodeId outputTargetId = blitFramebufferInfo.destinationRenderTargetId; +//* const QRect inputRect = blitFramebufferInfo.sourceRect; +//* const QRect outputRect = blitFramebufferInfo.destinationRect; +//* const QRenderTargetOutput::AttachmentPoint inputAttachmentPoint = blitFramebufferInfo.sourceAttachmentPoint; +//* const QRenderTargetOutput::AttachmentPoint outputAttachmentPoint = blitFramebufferInfo.destinationAttachmentPoint; +//* const QBlitFramebuffer::InterpolationMethod interpolationMethod = blitFramebufferInfo.interpolationMethod; +//* m_submissionContext->blitFramebuffer(inputTargetId, outputTargetId, inputRect, outputRect, lastBoundFBOId, +//* inputAttachmentPoint, outputAttachmentPoint, +//* interpolationMethod); } @@ -2027,66 +2223,70 @@ QAbstractFrameAdvanceService *Renderer::frameAdvanceService() const // Called by executeCommands void Renderer::performDraw(RenderCommand *command) { + QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); // Indirect Draw Calls if (command->m_drawIndirect) { - - // Bind the indirect draw buffer - Buffer *indirectDrawBuffer = m_nodesManager->bufferManager()->data(command->m_indirectDrawBuffer); - if (Q_UNLIKELY(indirectDrawBuffer == nullptr)) { - qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve Buffer"; - return; - } - - // Get RHIBuffer from Buffer; - RHIBuffer *indirectDrawGLBuffer = m_submissionContext->glBufferForRenderBuffer(indirectDrawBuffer); - if (Q_UNLIKELY(indirectDrawGLBuffer == nullptr)) { - qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve RHIBuffer"; - return; - } - - // Bind RHIBuffer - const bool successfullyBound = indirectDrawGLBuffer->bind(m_submissionContext.data(), RHIBuffer::DrawIndirectBuffer); - - if (Q_LIKELY(successfullyBound)) { - // TO DO: Handle multi draw variants if attribute count > 1 - if (command->m_drawIndexed) { - m_submissionContext->drawElementsIndirect(command->m_primitiveType, - command->m_indexAttributeDataType, - reinterpret_cast(quintptr(command->m_indirectAttributeByteOffset))); - } else { - m_submissionContext->drawArraysIndirect(command->m_primitiveType, - reinterpret_cast(quintptr(command->m_indirectAttributeByteOffset))); - } - } else { - qWarning() << "Failed to bind IndirectDrawBuffer"; - } + RHI_UNIMPLEMENTED; + //* // Bind the indirect draw buffer + //* Buffer *indirectDrawBuffer = m_nodesManager->bufferManager()->data(command->m_indirectDrawBuffer); + //* if (Q_UNLIKELY(indirectDrawBuffer == nullptr)) { + //* qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve Buffer"; + //* return; + //* } + //* + //* // Get RHIBuffer from Buffer; + //* RHIBuffer *indirectDrawGLBuffer = m_submissionContext->glBufferForRenderBuffer(indirectDrawBuffer); + //* if (Q_UNLIKELY(indirectDrawGLBuffer == nullptr)) { + //* qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve RHIBuffer"; + //* return; + //* } + //* + //* // Bind RHIBuffer + //* const bool successfullyBound = indirectDrawGLBuffer->bind(m_submissionContext.data(), RHIBuffer::DrawIndirectBuffer); + //* + //* if (Q_LIKELY(successfullyBound)) { + //* // TO DO: Handle multi draw variants if attribute count > 1 + //* if (command->m_drawIndexed) { + //* m_submissionContext->drawElementsIndirect(command->m_primitiveType, + //* command->m_indexAttributeDataType, + //* reinterpret_cast(quintptr(command->m_indirectAttributeByteOffset))); + //* } else { + //* m_submissionContext->drawArraysIndirect(command->m_primitiveType, + //* reinterpret_cast(quintptr(command->m_indirectAttributeByteOffset))); + //* } + //* } else { + //* qWarning() << "Failed to bind IndirectDrawBuffer"; + //* } } else { // Direct Draw Calls // TO DO: Add glMulti Draw variants if (command->m_primitiveType == QGeometryRenderer::Patches) - m_submissionContext->setVerticesPerPatch(command->m_verticesPerPatch); + { + RHI_UNIMPLEMENTED; + //* m_submissionContext->setVerticesPerPatch(command->m_verticesPerPatch); + } if (command->m_primitiveRestartEnabled) - m_submissionContext->enablePrimitiveRestart(command->m_restartIndexValue); + { + RHI_UNIMPLEMENTED; + //* m_submissionContext->enablePrimitiveRestart(command->m_restartIndexValue); + } // TO DO: Add glMulti Draw variants if (command->m_drawIndexed) { Profiling::GLTimeRecorder recorder(Profiling::DrawElement); - m_submissionContext->drawElementsInstancedBaseVertexBaseInstance(command->m_primitiveType, - command->m_primitiveCount, - command->m_indexAttributeDataType, - reinterpret_cast(quintptr(command->m_indexAttributeByteOffset)), - command->m_instanceCount, - command->m_indexOffset, - command->m_firstInstance); + cb->drawIndexed(command->m_primitiveCount, + command->m_instanceCount, + command->m_indexOffset, + command->m_indexAttributeByteOffset, + command->m_firstInstance); } else { Profiling::GLTimeRecorder recorder(Profiling::DrawArray); - m_submissionContext->drawArraysInstancedBaseInstance(command->m_primitiveType, - command->m_firstVertex, - command->m_primitiveCount, - command->m_instanceCount, - command->m_firstInstance); + cb->draw(command->m_primitiveCount, + command->m_instanceCount, + command->m_firstVertex, + command->m_firstInstance); } } @@ -2102,29 +2302,30 @@ void Renderer::performDraw(RenderCommand *command) void Renderer::performCompute(const RenderView *, RenderCommand *command) { - { - Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate); - RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource(command->m_shaderId); - m_submissionContext->activateShader(shader); - } - { - Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate); - m_submissionContext->setParameters(command->m_parameterPack); - } - { - Profiling::GLTimeRecorder recorder(Profiling::DispatchCompute); - m_submissionContext->dispatchCompute(command->m_workGroups[0], - command->m_workGroups[1], - command->m_workGroups[2]); - } - // HACK: Reset the compute flag to dirty - m_dirtyBits.marked |= AbstractRenderer::ComputeDirty; - -#if defined(QT3D_RENDER_ASPECT_RHI_DEBUG) - int err = m_submissionContext->openGLContext()->functions()->glGetError(); - if (err) - qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); -#endif + RHI_UNIMPLEMENTED; +//* { +//* Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate); +//* RHIShader *shader = m_RHIResourceManagers->rhiShaderManager()->lookupResource(command->m_shaderId); +//* m_submissionContext->activateShader(shader); +//* } +//* { +//* Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate); +//* m_submissionContext->setParameters(command->m_parameterPack); +//* } +//* { +//* Profiling::GLTimeRecorder recorder(Profiling::DispatchCompute); +//* m_submissionContext->dispatchCompute(command->m_workGroups[0], +//* command->m_workGroups[1], +//* command->m_workGroups[2]); +//* } +//* // HACK: Reset the compute flag to dirty +//* m_dirtyBits.marked |= AbstractRenderer::ComputeDirty; + +//* #if defined(QT3D_RENDER_ASPECT_RHI_DEBUG) +//* int err = m_submissionContext->openGLContext()->functions()->glGetError(); +//* if (err) +//* qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); +//* #endif } void Renderer::createOrUpdateVAO(RenderCommand *command, @@ -2149,6 +2350,81 @@ void Renderer::createOrUpdateVAO(RenderCommand *command, Q_ASSERT(*vao); } +static auto rhiIndexFormat(QAttribute::VertexBaseType type) +{ + switch(type) { + case QAttribute::VertexBaseType ::UnsignedShort: return QRhiCommandBuffer::IndexUInt16; + case QAttribute::VertexBaseType ::UnsignedInt: return QRhiCommandBuffer::IndexUInt32; + default: std::abort(); + } +} + +bool Renderer::prepareDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand& command) +{ + // Create the vertex input description + const auto geom = command.m_geometry; + const auto& attributes = geom->attributes(); + for(Qt3DCore::QNodeId attribute_id : attributes) + { + // TODO isn't there a more efficient way than doing three hash lookups ? + Attribute* attrib = m_nodesManager->attributeManager()->lookupResource(attribute_id); + Buffer *buffer = m_nodesManager->bufferManager()->lookupResource(attrib->bufferId()); + RHIBuffer* hbuf = m_RHIResourceManagers->rhiBufferManager()->lookupResource(buffer->peerId()); + switch(attrib->attributeType()) + { + case QAttribute::VertexAttribute: + hbuf->bind(&*m_submissionContext, RHIBuffer::Type::ArrayBuffer); + assert(hbuf->rhiBuffer()); + command.vertex_input.resize(std::max((std::size_t)command.vertex_input.size(), (std::size_t)attrib->location() + 1)); + command.vertex_input[attrib->location()] = {hbuf->rhiBuffer(), attrib->byteOffset()}; + break; + case QAttribute::IndexAttribute: + hbuf->bind(&*m_submissionContext, RHIBuffer::Type::IndexBuffer); + assert(hbuf->rhiBuffer()); + assert(command.indexBuffer == nullptr); + + command.indexBuffer = hbuf->rhiBuffer(); + command.indexAttribute = attrib; + break; + case QAttribute::DrawIndirectAttribute: + RHI_UNIMPLEMENTED; + break; + } + } + return true; +} + +bool Renderer::performDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand& command) +{ + // Setup the rendering pass + cb->setGraphicsPipeline(command.ps); + cb->setShaderResources(command.ps->shaderResourceBindings()); + + // Send the draw command + if (Q_UNLIKELY(!command.indexBuffer)) + { + Profiling::GLTimeRecorder recorder(Profiling::DrawArray); + cb->setVertexInput(0, command.vertex_input.size(), command.vertex_input.data()); + cb->draw(command.m_primitiveCount, + command.m_instanceCount, + command.m_firstVertex, + command.m_firstInstance); + } + else + { + Profiling::GLTimeRecorder recorder(Profiling::DrawElement); + auto indexFormat = rhiIndexFormat(command.indexAttribute->vertexBaseType()); + auto indexOffset = command.indexAttribute->byteOffset(); + cb->setVertexInput(0, command.vertex_input.size(), command.vertex_input.data(), command.indexBuffer, indexOffset, indexFormat); + cb->drawIndexed(command.m_primitiveCount, + command.m_instanceCount, + command.m_indexOffset, + command.m_indexAttributeByteOffset, + command.m_firstInstance); + } + + return true; +} // Called by RenderView->submit() in RenderThread context // Returns true, if all RenderCommands were sent to the GPU bool Renderer::executeCommandsSubmission(const RenderView *rv) @@ -2158,89 +2434,127 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv) // Render drawing commands QVector commands = rv->commands(); - // Use the graphicscontext to submit the commands to the underlying - // graphics API (OpenGL) + // Submit the commands to the underlying graphics API (RHI) // Save the RenderView base stateset RenderStateSet *globalState = m_submissionContext->currentStateSet(); - RHIVertexArrayObject *vao = nullptr; + QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); + + // Upload all the required data to rhi... for (RenderCommand &command : commands) { + if (command.m_type == RenderCommand::Draw) { + prepareDraw(cb, rv, command); + qDebug() << command.vertex_input.size() << command.vertex_input[0]; + } + } - if (command.m_type == RenderCommand::Compute) { // Compute Call + // Perform compute actions + cb->beginComputePass(m_submissionContext->m_currentUpdates); + for (RenderCommand &command : commands) { + if (command.m_type == RenderCommand::Compute) { performCompute(rv, &command); - } else { // Draw Command - // Check if we have a valid command that can be drawn - if (!command.m_isValid) { - allCommandsIssued = false; - continue; - } - - vao = m_RHIResourceManagers->vaoManager()->data(command.m_vao); - - // something may have went wrong when initializing the VAO - if (!vao->isSpecified()) { - allCommandsIssued = false; - continue; - } - - { - Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate); - //// We activate the shader here - RHIShader *shader = command.m_glShader; - if (!m_submissionContext->activateShader(shader)) { - allCommandsIssued = false; - continue; - } - } + } + } + cb->endComputePass(); + m_submissionContext->m_currentUpdates = m_r->nextResourceUpdateBatch(); - { - Profiling::GLTimeRecorder recorder(Profiling::VAOUpdate); - // Bind VAO - vao->bind(); - } + // Draw the commands + QRhiRenderTarget *rt = m_sc->currentFrameRenderTarget(); - { - Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate); - //// Update program uniforms - if (!m_submissionContext->setParameters(command.m_parameterPack)) { - allCommandsIssued = false; - // If we have failed to set uniform (e.g unable to bind a texture) - // we won't perform the draw call which could show invalid content - continue; - } - } + const QColor clearColor = [=] { + auto col = rv->globalClearColorBufferInfo().clearColor; + return QColor::fromRgbF(col.x(), col.y(), col.z(), col.w()); + }(); - //// OpenGL State - // TO DO: Make states not dependendent on their backend node for this step - // Set state - RenderStateSet *localState = command.m_stateSet.data(); + const QRhiDepthStencilClearValue clearDepthStencil{ rv->clearDepthValue(), (quint32)rv->clearStencilValue() }; + cb->beginPass(rt, clearColor, clearDepthStencil, m_submissionContext->m_currentUpdates); + { + const float x = rv->viewport().x() * rv->surfaceSize().width(); + const float y = (1. - rv->viewport().y() - rv->viewport().height()) * rv->surfaceSize().height(); + const float w = rv->viewport().width() * rv->surfaceSize().width(); + const float h = rv->viewport().height() * rv->surfaceSize().height(); - { - Profiling::GLTimeRecorder recorder(Profiling::StateUpdate); - // Merge the RenderCommand state with the globalState of the RenderView - // Or restore the globalState if no stateSet for the RenderCommand - if (localState != nullptr) { - command.m_stateSet->merge(globalState); - m_submissionContext->setCurrentStateSet(localState); - } else { - m_submissionContext->setCurrentStateSet(globalState); - } - } - // All Uniforms for a pass are stored in the QUniformPack of the command - // Uniforms for Effect, Material and Technique should already have been correctly resolved - // at that point + cb->setViewport(QRhiViewport{x, y, w, h}); + } - //// Draw Calls - performDraw(&command); + for (RenderCommand &command : commands) { + if (command.m_type == RenderCommand::Draw) { + performDraw(cb, rv, command); } - } // end of RenderCommands loop + } + cb->endPass(); + m_submissionContext->m_currentUpdates = m_r->nextResourceUpdateBatch(); +//* for (RenderCommand &command : commands) { +//* +//* // Check if we have a valid command that can be drawn +//* if (!command.m_isValid) { +//* allCommandsIssued = false; +//* continue; +//* } +//* +//* vao = m_RHIResourceManagers->vaoManager()->data(command.m_vao); +//* +//* // something may have went wrong when initializing the VAO +//* if (!vao->isSpecified()) { +//* allCommandsIssued = false; +//* continue; +//* } +//* +//* { +//* Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate); +//* //// We activate the shader here +//* //* RHIShader *shader = command.m_glShader; +//* //* if (!m_submissionContext->activateShader(shader)) { +//* //* allCommandsIssued = false; +//* //* continue; +//* //* } +//* } +//* +//* { +//* Profiling::GLTimeRecorder recorder(Profiling::VAOUpdate); +//* // Bind VAO +//* vao->bind(); +//* } +//* +//* { +//* Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate); +//* //// Update program uniforms +//* if (!m_submissionContext->setParameters(command.m_parameterPack)) { +//* allCommandsIssued = false; +//* // If we have failed to set uniform (e.g unable to bind a texture) +//* // we won't perform the draw call which could show invalid content +//* continue; +//* } +//* } +//* +//* //// OpenGL State +//* // TO DO: Make states not dependendent on their backend node for this step +//* // Set state +//* RenderStateSet *localState = command.m_stateSet.data(); +//* +//* +//* { +//* Profiling::GLTimeRecorder recorder(Profiling::StateUpdate); +//* // Merge the RenderCommand state with the globalState of the RenderView +//* // Or restore the globalState if no stateSet for the RenderCommand +//* if (localState != nullptr) { +//* command.m_stateSet->merge(globalState); +//* m_submissionContext->setCurrentStateSet(localState); +//* } else { +//* m_submissionContext->setCurrentStateSet(globalState); +//* } +//* } +//* // All Uniforms for a pass are stored in the QUniformPack of the command +//* // Uniforms for Effect, Material and Technique should already have been correctly resolved +//* // at that point +//* +//* //// Draw Calls +//* performDraw(&command); +//* } +//* } // end of RenderCommands loop - // We cache the VAO and release it only at the end of the exectute frame - // We try to minimize VAO binding between RenderCommands - if (vao) - vao->release(); // Reset to the state we were in before executing the render commands m_submissionContext->setCurrentStateSet(globalState); diff --git a/src/plugins/renderers/rhi/renderer/renderer_p.h b/src/plugins/renderers/rhi/renderer/renderer_p.h index f4afeceb8..e59ddad9d 100644 --- a/src/plugins/renderers/rhi/renderer/renderer_p.h +++ b/src/plugins/renderers/rhi/renderer/renderer_p.h @@ -375,8 +375,6 @@ private: QAtomicInt m_lastFrameCorrect; QOpenGLContext *m_glContext; - QOpenGLContext *m_shareContext; - mutable QMutex m_shareContextMutex; PickBoundingVolumeJobPtr m_pickBoundingVolumeJob; RayCastingJobPtr m_rayCastingJob; @@ -429,6 +427,8 @@ private: void sendSetFenceHandlesToFrontend(); void sendDisablesToFrontend(Qt3DCore::QAspectManager *manager); + void rhiRender(); + QMutex m_abandonedVaosMutex; QVector m_abandonedVaos; @@ -470,6 +470,9 @@ private: QOffscreenSurface *m_fallbackSurface{}; bool m_hasSwapChain = false; + void setupRHICommand(RenderCommand& command); + bool performDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand &command); + bool prepareDraw(QRhiCommandBuffer *cb, const RenderView *rv, RenderCommand &command); }; } // namespace Rhi diff --git a/src/plugins/renderers/rhi/renderer/renderview.cpp b/src/plugins/renderers/rhi/renderer/renderview.cpp index 45a0edbd5..68c282433 100644 --- a/src/plugins/renderers/rhi/renderer/renderview.cpp +++ b/src/plugins/renderers/rhi/renderer/renderview.cpp @@ -651,7 +651,7 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVectorcomponentUuid(); const HMaterial materialHandle = entity->componentHandle(); - const QVector renderPassData = m_parameters.value(materialComponentId); + const QVector renderPassData = m_parameters.value(materialComponentId); HGeometry geometryHandle = m_manager->geometryManager()->lookupHandle(geometryRenderer->geometryId()); Geometry *geometry = m_manager->geometryManager()->data(geometryHandle); @@ -681,6 +681,7 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVectorcommandData().size(); commandData.reserve(totalCommandCount); + //assert(totalCommandCount != 0); for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) commandData += std::move(renderViewCommandBuilder->commandData()); } diff --git a/src/plugins/renderers/rhi/renderer/shader.cpp b/src/plugins/renderers/rhi/renderer/shader.cpp index 992412dde..114fe92cc 100644 --- a/src/plugins/renderers/rhi/renderer/shader.cpp +++ b/src/plugins/renderers/rhi/renderer/shader.cpp @@ -62,11 +62,11 @@ void RHIShader::setGraphicsContext(GraphicsContext *context) { QMutexLocker lock(&m_mutex); m_graphicsContext = context; - if (m_graphicsContext) { - m_contextConnection = QObject::connect(m_graphicsContext->openGLContext(), - &QOpenGLContext::aboutToBeDestroyed, - [this] { setGraphicsContext(nullptr); }); - } + // if (m_graphicsContext) { + // m_contextConnection = QObject::connect(m_graphicsContext->openGLContext(), + // &QOpenGLContext::aboutToBeDestroyed, + // [this] { setGraphicsContext(nullptr); }); + // } } GraphicsContext *RHIShader::graphicsContext() diff --git a/src/plugins/renderers/rhi/rhi.pro b/src/plugins/renderers/rhi/rhi.pro index e5b5b9d71..4a9ed1175 100644 --- a/src/plugins/renderers/rhi/rhi.pro +++ b/src/plugins/renderers/rhi/rhi.pro @@ -1,5 +1,5 @@ TARGET = rhirenderer -QT += core-private gui-private 3dcore 3dcore-private 3drender 3drender-private +QT += core-private gui-private 3dcore 3dcore-private 3drender 3drender-private shadertools shadertools-private QT_PRIVATE = openglextensions # Qt3D is free of Q_FOREACH - make sure it stays that way: diff --git a/src/render/geometry/attribute.cpp b/src/render/geometry/attribute.cpp index de44c5fe3..1915376b8 100644 --- a/src/render/geometry/attribute.cpp +++ b/src/render/geometry/attribute.cpp @@ -58,6 +58,7 @@ Attribute::Attribute() , m_byteStride(0) , m_byteOffset(0) , m_divisor(0) + , m_location(0) , m_attributeType(QAttribute::VertexAttribute) , m_attributeDirty(false) { @@ -75,6 +76,7 @@ void Attribute::cleanup() m_byteStride = 0; m_byteOffset = 0; m_divisor = 0; + m_location = 0; m_attributeType = QAttribute::VertexAttribute; m_bufferId = Qt3DCore::QNodeId(); m_name.clear(); @@ -119,6 +121,10 @@ void Attribute::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) m_divisor = node->divisor(); m_attributeDirty = true; } + if (m_location != node->location()) { + m_location = node->location(); + m_attributeDirty = true; + } if (m_attributeType != node->attributeType()) { m_attributeType = node->attributeType(); m_attributeDirty = true; diff --git a/src/render/geometry/attribute_p.h b/src/render/geometry/attribute_p.h index 87b3cbb4f..298fd2e71 100644 --- a/src/render/geometry/attribute_p.h +++ b/src/render/geometry/attribute_p.h @@ -79,6 +79,7 @@ public: inline uint byteStride() const { return m_byteStride; } inline uint byteOffset() const { return m_byteOffset; } inline uint divisor() const { return m_divisor; } + inline uint location() const { return m_location; } inline QAttribute::AttributeType attributeType() const { return m_attributeType; } inline bool isDirty() const { return m_attributeDirty; } void unsetDirty(); @@ -93,6 +94,7 @@ private: uint m_byteStride; uint m_byteOffset; uint m_divisor; + uint m_location; QAttribute::AttributeType m_attributeType; bool m_attributeDirty; }; diff --git a/src/render/geometry/qattribute.cpp b/src/render/geometry/qattribute.cpp index 84d14cfe1..a427f9a71 100644 --- a/src/render/geometry/qattribute.cpp +++ b/src/render/geometry/qattribute.cpp @@ -212,6 +212,17 @@ QString QAttribute::name() const return d->m_name; } +/*! + * \property QAttribute::location + * + * Holds the location. + */ +uint QAttribute::location() const +{ + Q_D(const QAttribute); + return d->m_location; +} + /*! * \property QAttribute::vertexSize * @@ -325,6 +336,16 @@ void QAttribute::setName(const QString &name) emit nameChanged(name); } +void QAttribute::setLocation(uint location) +{ + Q_D(QAttribute); + if (d->m_location == location) + return; + + d->m_location = location; + emit locationChanged(location); +} + void QAttribute::setVertexBaseType(VertexBaseType type) { Q_D(QAttribute); @@ -499,6 +520,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAttribute::createNodeCreationChange() const data.byteStride = d->m_byteStride; data.byteOffset = d->m_byteOffset; data.divisor = d->m_divisor; + data.location = d->m_location; data.attributeType = d->m_attributeType; return creationChange; } diff --git a/src/render/geometry/qattribute.h b/src/render/geometry/qattribute.h index 526a77a59..8cddfa131 100644 --- a/src/render/geometry/qattribute.h +++ b/src/render/geometry/qattribute.h @@ -58,6 +58,7 @@ class Q_3DRENDERSHARED_EXPORT QAttribute : public Qt3DCore::QNode Q_OBJECT Q_PROPERTY(Qt3DRender::QBuffer *buffer READ buffer WRITE setBuffer NOTIFY bufferChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(uint location READ location WRITE setLocation NOTIFY locationChanged) Q_PROPERTY(VertexBaseType vertexBaseType READ vertexBaseType WRITE setVertexBaseType NOTIFY vertexBaseTypeChanged) Q_PROPERTY(uint vertexSize READ vertexSize WRITE setVertexSize NOTIFY vertexSizeChanged) Q_PROPERTY(uint count READ count WRITE setCount NOTIFY countChanged) @@ -104,6 +105,7 @@ public: QBuffer *buffer() const; QString name() const; + uint location() const; VertexBaseType vertexBaseType() const; uint vertexSize() const; uint count() const; @@ -125,6 +127,7 @@ public: public Q_SLOTS: void setBuffer(QBuffer *buffer); void setName(const QString &name); + void setLocation(uint location); void setVertexBaseType(VertexBaseType type); void setVertexSize(uint size); QT_DEPRECATED void setDataType(VertexBaseType type); @@ -138,6 +141,7 @@ public Q_SLOTS: Q_SIGNALS: void bufferChanged(QBuffer *buffer); void nameChanged(const QString &name); + void locationChanged(uint location); void vertexBaseTypeChanged(VertexBaseType vertexBaseType); void vertexSizeChanged(uint vertexSize); void dataTypeChanged(VertexBaseType vertexBaseType); diff --git a/src/render/geometry/qattribute_p.h b/src/render/geometry/qattribute_p.h index 8355a042b..c1016073a 100644 --- a/src/render/geometry/qattribute_p.h +++ b/src/render/geometry/qattribute_p.h @@ -77,6 +77,7 @@ public: uint m_byteStride; uint m_byteOffset; uint m_divisor; + uint m_location; QAttribute::AttributeType m_attributeType; }; @@ -90,6 +91,7 @@ struct QAttributeData uint byteStride; uint byteOffset; uint divisor; + uint location; QAttribute::AttributeType attributeType; }; diff --git a/src/render/materialsystem/qgraphicsapifilter.h b/src/render/materialsystem/qgraphicsapifilter.h index 337193673..80cfe026e 100644 --- a/src/render/materialsystem/qgraphicsapifilter.h +++ b/src/render/materialsystem/qgraphicsapifilter.h @@ -67,7 +67,8 @@ public: OpenGLES = QSurfaceFormat::OpenGLES, // 2 OpenGL = QSurfaceFormat::OpenGL, // 1 Vulkan = 3, // 3 - DirectX // 4 + DirectX, // 4 + RHI, // 5 }; Q_ENUM(Api) // LCOV_EXCL_LINE diff --git a/src/src.pro b/src/src.pro index 047e67bf2..0a16af003 100644 --- a/src/src.pro +++ b/src/src.pro @@ -114,7 +114,7 @@ qtHaveModule(quick) { SUBDIRS += src_core -QT_FOR_CONFIG += 3dcore +QT_FOR_CONFIG += 3dcore shadertools include($$OUT_PWD/core/qt3dcore-config.pri) qtConfig(qt3d-input): SUBDIRS += src_input diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 2f630e0d9..4f7432e03 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -70,7 +70,8 @@ SUBDIRS += \ compressed_textures \ subtree-enabler-qml \ scene3d-visibility \ - manual-renderloop + manual-renderloop \ + rhi !macos:!uikit: SUBDIRS += compute-manual diff --git a/tests/manual/rhi/main.cpp b/tests/manual/rhi/main.cpp new file mode 100644 index 000000000..69361d10b --- /dev/null +++ b/tests/manual/rhi/main.cpp @@ -0,0 +1,410 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const constexpr auto vertex_shader = R"_(#version 450 + +layout(location = 0) in vec3 vertexPosition; + +layout(location = 0) out vec4 color; + +layout(std140, binding = 0) uniform qt3d_uniforms { + mat4 mvp; +}; +void main() +{ + gl_Position = mvp * vec4( vertexPosition, 1.0 ); +} +)_"; + +static const constexpr auto fragment_shader = R"_(#version 450 + +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 1) uniform custom_uniforms { + float example; +}; +void main() +{ + fragColor = vec4(example, example, example, example); +} + +)_"; + +class Material : public Qt3DRender::QMaterial +{ +public: + explicit Material(Qt3DCore::QNode *parent = nullptr) + : QMaterial(parent) + , m_effect(new Qt3DRender::QEffect(this)) +{ + setEffect(m_effect); + + m_testParam = new Qt3DRender::QParameter(QStringLiteral("example"), float(0.5)); + + m_effect->addParameter(m_testParam); + + m_filter = new Qt3DRender::QFilterKey(this); + m_filter->setName(QStringLiteral("renderingStyle")); + m_filter->setValue(QStringLiteral("forward")); + + m_technique = new Qt3DRender::QTechnique(m_effect); + m_technique->addFilterKey(m_filter); + + m_effect->addTechnique(m_technique); + + m_program = new Qt3DRender::QShaderProgram(m_effect); + m_program->setVertexShaderCode(vertex_shader); + m_program->setFragmentShaderCode(fragment_shader); + + m_renderPass = new Qt3DRender::QRenderPass(m_effect); + + m_renderPass->setShaderProgram(m_program); + + m_technique->addRenderPass(m_renderPass); + + m_technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::RHI); +} +private: + Qt3DRender::QEffect *m_effect{}; + Qt3DRender::QParameter *m_testParam{}; + Qt3DRender::QFilterKey *m_filter{}; + Qt3DRender::QTechnique *m_technique{}; + Qt3DRender::QShaderProgram *m_program{}; + Qt3DRender::QRenderPass *m_renderPass{}; +}; + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Qt3DWindow view; + view.defaultFrameGraph()->setClearColor(QColor::fromRgbF(0.1, 0.5, 0.0, 1.0)); + + // Root entity + Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); + + // Camera + Qt3DRender::QCamera *cameraEntity = view.camera(); + + cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f); + cameraEntity->setPosition(QVector3D(0, 0, 40.0f)); + cameraEntity->setUpVector(QVector3D(0, 1, 0)); + cameraEntity->setViewCenter(QVector3D(0, 0, 0)); + + // For camera controls + Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity); + camController->setCamera(cameraEntity); + + // Material + Qt3DRender::QMaterial *material = new Material(rootEntity); + + // Torus + Qt3DCore::QEntity *customMeshEntity = new Qt3DCore::QEntity(rootEntity); + + // Transform + Qt3DCore::QTransform *transform = new Qt3DCore::QTransform; + transform->setScale(8.0f); + + // Custom Mesh (TetraHedron) + Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer; + Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(customMeshRenderer); + + Qt3DRender::QBuffer *vertexDataBuffer = new Qt3DRender::QBuffer(customGeometry); + + + // 4 distinct vertices + QByteArray vertexBufferData; + vertexBufferData.resize(9 * sizeof(float)); + + // Vertices + QVector3D v0(-1.0f, 0.0f, -1.0f); + QVector3D v1(1.0f, 0.0f, -1.0f); + QVector3D v2(0.0f, 1.0f, 0.0f); + + + const QVector vertices = QVector() + << v0 + << v1 + << v2; + + float *rawVertexArray = reinterpret_cast(vertexBufferData.data()); + int idx = 0; + + for (const QVector3D &v : vertices) { + rawVertexArray[idx++] = v.x(); + rawVertexArray[idx++] = v.y(); + rawVertexArray[idx++] = v.z(); + } + + vertexDataBuffer->setData(vertexBufferData); + + // Attributes + Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute(); + positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + positionAttribute->setBuffer(vertexDataBuffer); + positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + positionAttribute->setVertexSize(3); + positionAttribute->setByteOffset(0); + positionAttribute->setByteStride(3 * sizeof(float)); + positionAttribute->setCount(3); + positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + + customGeometry->addAttribute(positionAttribute); + + customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); + customMeshRenderer->setGeometry(customGeometry); + customMeshRenderer->setVertexCount(3); + + customMeshEntity->addComponent(customMeshRenderer); + customMeshEntity->addComponent(transform); + customMeshEntity->addComponent(material); + + view.setRootEntity(rootEntity); + view.show(); + + return app.exec(); +} +/* +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Qt3DWindow view; + view.defaultFrameGraph()->setClearColor(QColor::fromRgbF(0.0, 0.5, 1.0, 1.0)); + + // Root entity + Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); + + // Camera + Qt3DRender::QCamera *cameraEntity = view.camera(); + + cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f); + cameraEntity->setPosition(QVector3D(0, 0, 40.0f)); + cameraEntity->setUpVector(QVector3D(0, 1, 0)); + cameraEntity->setViewCenter(QVector3D(0, 0, 0)); + + // For camera controls + Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity); + camController->setCamera(cameraEntity); + + // Material + Qt3DRender::QMaterial *material = new Material(rootEntity); + + // Torus + Qt3DCore::QEntity *customMeshEntity = new Qt3DCore::QEntity(rootEntity); + + // Transform + Qt3DCore::QTransform *transform = new Qt3DCore::QTransform; + transform->setScale(8.0f); + + // Custom Mesh (TetraHedron) + Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer; + Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(customMeshRenderer); + + Qt3DRender::QBuffer *vertexDataBuffer = new Qt3DRender::QBuffer(customGeometry); + Qt3DRender::QBuffer *indexDataBuffer = new Qt3DRender::QBuffer(customGeometry); + + // vec3 for position + // vec3 for colors + + // 2 + // /|\ + // / | \ + // / /3\ \ + // 0/___\ 1 + + + // 4 distinct vertices + QByteArray vertexBufferData; + vertexBufferData.resize(4 * (3 + 3 + 3) * sizeof(float)); + + // Vertices + QVector3D v0(-1.0f, 0.0f, -1.0f); + QVector3D v1(1.0f, 0.0f, -1.0f); + QVector3D v2(0.0f, 1.0f, 0.0f); + QVector3D v3(0.0f, 0.0f, 1.0f); + + // Colors + QVector3D red(1.0f, 0.0f, 0.0f); + QVector3D green(0.0f, 1.0f, 0.0f); + QVector3D blue(0.0f, 0.0f, 1.0f); + QVector3D white(1.0f, 1.0f, 1.0f); + + const QVector vertices = QVector() + << v0 << red + << v1 << blue + << v2 << green + << v3 << white; + + float *rawVertexArray = reinterpret_cast(vertexBufferData.data()); + int idx = 0; + + for (const QVector3D &v : vertices) { + rawVertexArray[idx++] = v.x(); + rawVertexArray[idx++] = v.y(); + rawVertexArray[idx++] = v.z(); + } + + // Indices (12) + QByteArray indexBufferData; + indexBufferData.resize(4 * 3 * sizeof(ushort)); + ushort *rawIndexArray = reinterpret_cast(indexBufferData.data()); + + // Front + rawIndexArray[0] = 0; + rawIndexArray[1] = 1; + rawIndexArray[2] = 2; + // Bottom + rawIndexArray[3] = 3; + rawIndexArray[4] = 1; + rawIndexArray[5] = 0; + // Left + rawIndexArray[6] = 0; + rawIndexArray[7] = 2; + rawIndexArray[8] = 3; + // Right + rawIndexArray[9] = 1; + rawIndexArray[10] = 3; + rawIndexArray[11] = 2; + + vertexDataBuffer->setData(vertexBufferData); + indexDataBuffer->setData(indexBufferData); + + // Attributes + Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute(); + positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + positionAttribute->setBuffer(vertexDataBuffer); + positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + positionAttribute->setVertexSize(3); + positionAttribute->setByteOffset(0); + positionAttribute->setByteStride(9 * sizeof(float)); + positionAttribute->setCount(4); + positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + + Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute(); + colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + colorAttribute->setBuffer(vertexDataBuffer); + colorAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + colorAttribute->setVertexSize(3); + colorAttribute->setByteOffset(3 * sizeof(float)); + colorAttribute->setByteStride(9 * sizeof(float)); + colorAttribute->setCount(4); + colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); + + Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute(); + indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); + indexAttribute->setBuffer(indexDataBuffer); + indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort); + indexAttribute->setVertexSize(1); + indexAttribute->setByteOffset(0); + indexAttribute->setByteStride(0); + indexAttribute->setCount(12); + + customGeometry->addAttribute(positionAttribute); + customGeometry->addAttribute(colorAttribute); + customGeometry->addAttribute(indexAttribute); + + customMeshRenderer->setInstanceCount(1); + customMeshRenderer->setIndexOffset(0); + customMeshRenderer->setFirstInstance(0); + customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); + customMeshRenderer->setGeometry(customGeometry); + // 4 faces of 3 points + customMeshRenderer->setVertexCount(12); + + customMeshEntity->addComponent(customMeshRenderer); + customMeshEntity->addComponent(transform); + customMeshEntity->addComponent(material); + + view.setRootEntity(rootEntity); + view.show(); + + return app.exec(); +} +*/ diff --git a/tests/manual/rhi/rhi.pro b/tests/manual/rhi/rhi.pro new file mode 100644 index 000000000..04b2627cf --- /dev/null +++ b/tests/manual/rhi/rhi.pro @@ -0,0 +1,8 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dextras + +SOURCES += \ + main.cpp -- cgit v1.2.3