Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"

This commit is contained in:
Qt Forward Merge Bot 2019-09-28 01:00:51 +02:00
commit fbda189e08
36 changed files with 515 additions and 69 deletions

View File

@ -71,7 +71,8 @@ qt {
# Add the same default rpaths as Xcode does for new projects. # Add the same default rpaths as Xcode does for new projects.
# This is especially important for iOS/tvOS/watchOS where no other option is possible. # This is especially important for iOS/tvOS/watchOS where no other option is possible.
!no_default_rpath { !no_default_rpath {
QMAKE_RPATHDIR += @executable_path/../Frameworks uikit: QMAKE_RPATHDIR += @executable_path/Frameworks
else: QMAKE_RPATHDIR += @executable_path/../Frameworks
equals(TEMPLATE, lib):!plugin:lib_bundle: QMAKE_RPATHDIR += @loader_path/Frameworks equals(TEMPLATE, lib):!plugin:lib_bundle: QMAKE_RPATHDIR += @loader_path/Frameworks
} }

View File

@ -0,0 +1,7 @@
# Prevent warnings about object files without any symbols. This is a common
# thing in Qt as we tend to build files unconditionally, and then use ifdefs
# to compile out parts that are not relevant.
QMAKE_RANLIB += -no_warning_for_no_symbols
# We have to tell 'ar' to not run ranlib by itself
QMAKE_AR += -S

View File

@ -88,6 +88,9 @@ cross_compile: \
android|uikit|winrt: \ android|uikit|winrt: \
CONFIG += builtin_testdata CONFIG += builtin_testdata
# Prevent warnings about object files without any symbols
macos: CONFIG += no_warn_empty_obj_files
CONFIG += \ CONFIG += \
utf8_source \ utf8_source \
create_prl link_prl \ create_prl link_prl \

View File

@ -107,10 +107,51 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\internal \internal
Implements qFpClassify() for qfloat16. \since 5.14
*/ bool qfloat16::isInf() const noexcept
Tests whether this \c qfloat16 value is an infinity.
\sa qIsInf()
*/
/*!
\internal
\since 5.14
bool qfloat16::isNaN() const noexcept
Tests whether this \c qfloat16 value is "not a number".
\sa qIsNaN()
*/
/*!
\since 5.14
bool qfloat16::isNormal() const noexcept
Tests whether this \c qfloat16 value is finite and in normal form.
\sa qFpClassify()
*/
/*!
\internal
\since 5.14
bool qfloat16::isFinite() const noexcept
Tests whether this \c qfloat16 value is finite.
\sa qIsFinite()
*/
/*!
\internal
\since 5.14
Implements qFpClassify() for qfloat16.
\sa qFpClassify()
*/
int qfloat16::fpClassify() const noexcept int qfloat16::fpClassify() const noexcept
{ {
return isInf() ? FP_INFINITE : isNaN() ? FP_NAN return isInf() ? FP_INFINITE : isNaN() ? FP_NAN

View File

@ -48,6 +48,10 @@
#include "qoperatingsystemversion_p.h" #include "qoperatingsystemversion_p.h"
#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINRT) #if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINRT)
#include "qoperatingsystemversion_win_p.h" #include "qoperatingsystemversion_win_p.h"
# if QT_CONFIG(settings)
# include "qsettings.h"
# include "qvariant.h"
# endif
#endif #endif
#include <private/qlocale_tools_p.h> #include <private/qlocale_tools_p.h>
@ -2186,12 +2190,36 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
QT_WARNING_POP QT_WARNING_POP
#endif #endif
static QString readRegistryString(const QString &key, const QString &subKey)
{
#if QT_CONFIG(settings)
QSettings settings(key, QSettings::NativeFormat);
return settings.value(subKey).toString();
#else
Q_UNUSED(key);
Q_UNUSED(subKey);
return QString();
#endif
}
static inline QString windowsVersionKey() { return QStringLiteral(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"); }
static inline QString windows10ReleaseId()
{
return readRegistryString(windowsVersionKey(), QStringLiteral("ReleaseId"));
}
static inline QString windows7Build()
{
return readRegistryString(windowsVersionKey(), QStringLiteral("CurrentBuild"));
}
static QString winSp_helper() static QString winSp_helper()
{ {
const auto osv = qWindowsVersionInfo(); const auto osv = qWindowsVersionInfo();
const qint16 major = osv.wServicePackMajor; const qint16 major = osv.wServicePackMajor;
if (major) { if (major) {
QString sp = QStringLiteral(" SP ") + QString::number(major); QString sp = QStringLiteral("SP ") + QString::number(major);
const qint16 minor = osv.wServicePackMinor; const qint16 minor = osv.wServicePackMinor;
if (minor) if (minor)
sp += QLatin1Char('.') + QString::number(minor); sp += QLatin1Char('.') + QString::number(minor);
@ -2904,19 +2932,35 @@ QString QSysInfo::prettyProductName()
{ {
#if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN) #if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
const auto version = QOperatingSystemVersion::current(); const auto version = QOperatingSystemVersion::current();
const int majorVersion = version.majorVersion();
const QString versionString = QString::number(majorVersion) + QLatin1Char('.')
+ QString::number(version.minorVersion());
QString result = version.name() + QLatin1Char(' ');
const char *name = osVer_helper(version); const char *name = osVer_helper(version);
if (name) if (!name)
return version.name() + QLatin1Char(' ') + QLatin1String(name) return result + versionString;
# if defined(Q_OS_WIN) result += QLatin1String(name);
+ winSp_helper() # if !defined(Q_OS_WIN)
# endif return result + QLatin1String(" (") + versionString + QLatin1Char(')');
+ QLatin1String(" (") + QString::number(version.majorVersion()) # else
+ QLatin1Char('.') + QString::number(version.minorVersion()) // (resembling winver.exe): Windows 10 "Windows 10 Version 1809"
+ QLatin1Char(')'); result += QLatin1String(" Version ");
else if (majorVersion >= 10) {
return version.name() + QLatin1Char(' ') const auto releaseId = windows10ReleaseId();
+ QString::number(version.majorVersion()) + QLatin1Char('.') if (!releaseId.isEmpty())
+ QString::number(version.minorVersion()); result += QLatin1String(" Version ") + releaseId;
return result;
}
// Windows 7: "Windows 7 Version 6.1 (Build 7601: Service Pack 1)"
result += versionString + QLatin1String(" (");
const auto build = windows7Build();
if (!build.isEmpty())
result += QLatin1String("Build ") + build;
const auto servicePack = winSp_helper();
if (!servicePack.isEmpty())
result += QLatin1String(": ") + servicePack;
return result + QLatin1Char(')');
# endif // Windows
#elif defined(Q_OS_HAIKU) #elif defined(Q_OS_HAIKU)
return QLatin1String("Haiku ") + productVersion(); return QLatin1String("Haiku ") + productVersion();
#elif defined(Q_OS_UNIX) #elif defined(Q_OS_UNIX)

View File

@ -701,7 +701,7 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
calendar being constructed by other means first. With no argument, the calendar being constructed by other means first. With no argument, the
default constructor returns the Gregorian calendar. default constructor returns the Gregorian calendar.
\sa QCalendar, System \sa QCalendar, System, isValid()
*/ */
QCalendar::QCalendar() QCalendar::QCalendar()
@ -723,6 +723,15 @@ QCalendar::QCalendar(QLatin1String name)
QCalendar::QCalendar(QStringView name) QCalendar::QCalendar(QStringView name)
: d(QCalendarBackend::fromName(name)) {} : d(QCalendarBackend::fromName(name)) {}
/*
\fn bool QCalendar::isValid() const
Returns true if this is a valid calendar object.
Constructing a calendar with an unrecognised calendar name may result in an
invalid object. Use this method to check after creating a calendar by name.
*/
// Date queries: // Date queries:
/*! /*!

View File

@ -137,7 +137,7 @@ public:
explicit QCalendar(QStringView name); explicit QCalendar(QStringView name);
// QCalendar is a trivially copyable value type. // QCalendar is a trivially copyable value type.
bool isValid() { return d != nullptr; } bool isValid() const { return d != nullptr; }
// Date queries: // Date queries:
int daysInMonth(int month, int year = Unspecified) const; int daysInMonth(int month, int year = Unspecified) const;

View File

@ -3548,6 +3548,7 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
*/ */
/*! /*!
\since 5.14
\enum QDateTime::YearRange \enum QDateTime::YearRange
This enumerated type describes the range of years (in the Gregorian This enumerated type describes the range of years (in the Gregorian

View File

@ -186,7 +186,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, MyDictionary &myd
argument.beginMap(); argument.beginMap();
mydict.clear(); mydict.clear();
while ( !argMap.atEnd() ) { while ( !argument.atEnd() ) {
int key; int key;
MyValue value; MyValue value;
argument.beginMapEntry(); argument.beginMapEntry();

View File

@ -45,6 +45,7 @@
#include <QDir> #include <QDir>
#include <QSaveFile> #include <QSaveFile>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QCryptographicHash>
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
#include <sys/mman.h> #include <sys/mman.h>
@ -94,6 +95,15 @@ GLEnvInfo::GLEnvInfo()
glversion = QByteArray(version); glversion = QByteArray(version);
} }
QByteArray QOpenGLProgramBinaryCache::ProgramDesc::cacheKey() const
{
QCryptographicHash keyBuilder(QCryptographicHash::Sha1);
for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : shaders)
keyBuilder.addData(shader.source);
return keyBuilder.result().toHex();
}
static inline bool qt_ensureWritableDir(const QString &name) static inline bool qt_ensureWritableDir(const QString &name)
{ {
QDir::root().mkpath(name); QDir::root().mkpath(name);

View File

@ -71,6 +71,7 @@ public:
}; };
struct ProgramDesc { struct ProgramDesc {
QVector<ShaderDesc> shaders; QVector<ShaderDesc> shaders;
QByteArray cacheKey() const;
}; };
QOpenGLProgramBinaryCache(); QOpenGLProgramBinaryCache();

View File

@ -47,7 +47,6 @@
#include <QtCore/qvarlengtharray.h> #include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h> #include <QtCore/qvector.h>
#include <QtCore/qloggingcategory.h> #include <QtCore/qloggingcategory.h>
#include <QtCore/qcryptographichash.h>
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
#include <QtGui/qtransform.h> #include <QtGui/qtransform.h>
#include <QtGui/QColor> #include <QtGui/QColor>
@ -3819,11 +3818,7 @@ bool QOpenGLShaderProgramPrivate::linkBinary()
Q_Q(QOpenGLShaderProgram); Q_Q(QOpenGLShaderProgram);
QCryptographicHash keyBuilder(QCryptographicHash::Sha1); const QByteArray cacheKey = binaryProgram.cacheKey();
for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : qAsConst(binaryProgram.shaders))
keyBuilder.addData(shader.source);
const QByteArray cacheKey = keyBuilder.result().toHex();
if (DBG_SHADER_CACHE().isEnabled(QtDebugMsg)) if (DBG_SHADER_CACHE().isEnabled(QtDebugMsg))
qCDebug(DBG_SHADER_CACHE, "program with %d shaders, cache key %s", qCDebug(DBG_SHADER_CACHE, "program with %d shaders, cache key %s",
binaryProgram.shaders.count(), cacheKey.constData()); binaryProgram.shaders.count(), cacheKey.constData());

View File

@ -707,8 +707,8 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v)
Used with QRhiCommandBuffer::setViewport(). Used with QRhiCommandBuffer::setViewport().
\note QRhi assumes OpenGL-style viewport coordinates, meaning x and y are QRhi assumes OpenGL-style viewport coordinates, meaning x and y are
bottom-left. bottom-left. Negative width or height are not allowed.
Typical usage is like the following: Typical usage is like the following:
@ -737,7 +737,9 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v)
Constructs a viewport description with the rectangle specified by \a x, \a Constructs a viewport description with the rectangle specified by \a x, \a
y, \a w, \a h and the depth range \a minDepth and \a maxDepth. y, \a w, \a h and the depth range \a minDepth and \a maxDepth.
\note x and y are assumed to be the bottom-left position. \note \a x and \a y are assumed to be the bottom-left position. \a w and \a
h should not be negative, the viewport will be ignored by
QRhiCommandBuffer::setViewport() otherwise.
\sa QRhi::clipSpaceCorrMatrix() \sa QRhi::clipSpaceCorrMatrix()
*/ */
@ -810,8 +812,12 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v)
only possible with a QRhiGraphicsPipeline that has only possible with a QRhiGraphicsPipeline that has
QRhiGraphicsPipeline::UsesScissor set. QRhiGraphicsPipeline::UsesScissor set.
\note QRhi assumes OpenGL-style scissor coordinates, meaning x and y are QRhi assumes OpenGL-style scissor coordinates, meaning x and y are
bottom-left. bottom-left. Negative width or height are not allowed. However, apart from
that, the flexible OpenGL semantics apply: negative x and y, partially out
of bounds rectangles, etc. will be handled gracefully, clamping as
appropriate. Therefore, any rendering logic targeting OpenGL can feed
scissor rectangles into QRhiScissor as-is, without any adaptation.
\sa QRhiCommandBuffer::setScissor(), QRhiViewport \sa QRhiCommandBuffer::setScissor(), QRhiViewport
*/ */
@ -826,7 +832,11 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v)
Constructs a scissor with the rectangle specified by \a x, \a y, \a w, and Constructs a scissor with the rectangle specified by \a x, \a y, \a w, and
\a h. \a h.
\note x and y are assumed to be the bottom-left position. \note \a x and \a y are assumed to be the bottom-left position. Negative \a w
or \a h are not allowed, such scissor rectangles will be ignored by
QRhiCommandBuffer. Other than that, the flexible OpenGL semantics apply:
negative x and y, partially out of bounds rectangles, etc. will be handled
gracefully, clamping as appropriate.
*/ */
QRhiScissor::QRhiScissor(int x, int y, int w, int h) QRhiScissor::QRhiScissor(int x, int y, int w, int h)
: m_rect { { x, y, w, h } } : m_rect { { x, y, w, h } }

View File

@ -233,27 +233,37 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T,
T *x, T *y, T *w, T *h) T *x, T *y, T *w, T *h)
{ {
// x,y are bottom-left in QRhiScissor and QRhiViewport but top-left in // x,y are bottom-left in QRhiScissor and QRhiViewport but top-left in
// Vulkan/Metal/D3D. We also need proper clamping since some // Vulkan/Metal/D3D. Our input is an OpenGL-style scissor rect where both
// validation/debug layers are allergic to out of bounds scissor or // negative x or y, and partly or completely out of bounds rects are
// viewport rects. // allowed. The only thing the input here cannot have is a negative width
// or height. We must handle all other input gracefully, clamping to a zero
// width or height rect in the worst case, and ensuring the resulting rect
// is inside the rendertarget's bounds because some APIs' validation/debug
// layers are allergic to out of bounds scissor or viewport rects.
const T outputWidth = outputSize.width(); const T outputWidth = outputSize.width();
const T outputHeight = outputSize.height(); const T outputHeight = outputSize.height();
const T inputWidth = r[2]; const T inputWidth = r[2];
const T inputHeight = r[3]; const T inputHeight = r[3];
*x = qMax<T>(0, r[0]); if (inputWidth < 0 || inputHeight < 0)
*y = qMax<T>(0, outputHeight - (r[1] + inputHeight));
*w = inputWidth;
*h = inputHeight;
if (*x >= outputWidth || *y >= outputHeight)
return false; return false;
*x = r[0];
*y = outputHeight - (r[1] + inputHeight);
const T widthOffset = *x < 0 ? -*x : 0;
const T heightOffset = *y < 0 ? -*y : 0;
*x = qBound<T>(0, *x, outputWidth - 1);
*y = qBound<T>(0, *y, outputHeight - 1);
*w = qMax<T>(0, inputWidth - widthOffset);
*h = qMax<T>(0, inputHeight - heightOffset);
if (*x + *w > outputWidth) if (*x + *w > outputWidth)
*w = outputWidth - *x; *w = qMax<T>(0, outputWidth - *x - 1);
if (*y + *h > outputHeight) if (*y + *h > outputHeight)
*h = outputHeight - *y; *h = qMax<T>(0, outputHeight - *y - 1);
return true; return true;
} }

View File

@ -1004,8 +1004,12 @@ void QRhiGles2::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
QGles2CommandBuffer::Command cmd; QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::Viewport; cmd.cmd = QGles2CommandBuffer::Command::Viewport;
const std::array<float, 4> r = viewport.viewport(); const std::array<float, 4> r = viewport.viewport();
cmd.args.viewport.x = qMax(0.0f, r[0]); // A negative width or height is an error. A negative x or y is not.
cmd.args.viewport.y = qMax(0.0f, r[1]); if (r[2] < 0.0f || r[3] < 0.0f)
return;
cmd.args.viewport.x = r[0];
cmd.args.viewport.y = r[1];
cmd.args.viewport.w = r[2]; cmd.args.viewport.w = r[2];
cmd.args.viewport.h = r[3]; cmd.args.viewport.h = r[3];
cmd.args.viewport.d0 = viewport.minDepth(); cmd.args.viewport.d0 = viewport.minDepth();
@ -1021,8 +1025,12 @@ void QRhiGles2::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
QGles2CommandBuffer::Command cmd; QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::Scissor; cmd.cmd = QGles2CommandBuffer::Command::Scissor;
const std::array<int, 4> r = scissor.scissor(); const std::array<int, 4> r = scissor.scissor();
cmd.args.scissor.x = qMax(0, r[0]); // A negative width or height is an error. A negative x or y is not.
cmd.args.scissor.y = qMax(0, r[1]); if (r[2] < 0 || r[3] < 0)
return;
cmd.args.scissor.x = r[0];
cmd.args.scissor.y = r[1];
cmd.args.scissor.w = r[2]; cmd.args.scissor.w = r[2];
cmd.args.scissor.h = r[3]; cmd.args.scissor.h = r[3];
cbD->commands.append(cmd); cbD->commands.append(cmd);
@ -2250,6 +2258,7 @@ void QRhiGles2::executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps)
} }
} else { } else {
f->glDisable(GL_BLEND); f->glDisable(GL_BLEND);
f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
} }
if (psD->m_depthTest) if (psD->m_depthTest)
f->glEnable(GL_DEPTH_TEST); f->glEnable(GL_DEPTH_TEST);

View File

@ -838,8 +838,15 @@ void QRhiMetal::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
[cbD->d->currentRenderPassEncoder setRenderPipelineState: psD->d->ps]; [cbD->d->currentRenderPassEncoder setRenderPipelineState: psD->d->ps];
[cbD->d->currentRenderPassEncoder setDepthStencilState: psD->d->ds]; [cbD->d->currentRenderPassEncoder setDepthStencilState: psD->d->ds];
[cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode];
[cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding]; if (cbD->currentCullMode == -1 || psD->d->cullMode != uint(cbD->currentCullMode)) {
[cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode];
cbD->currentCullMode = int(psD->d->cullMode);
}
if (cbD->currentFrontFaceWinding == -1 || psD->d->winding != uint(cbD->currentFrontFaceWinding)) {
[cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding];
cbD->currentFrontFaceWinding = int(psD->d->winding);
}
} }
psD->lastActiveFrameSlot = currentFrameSlot; psD->lastActiveFrameSlot = currentFrameSlot;
@ -3450,6 +3457,10 @@ void QMetalCommandBuffer::resetPerPassCachedState()
currentSrbGeneration = 0; currentSrbGeneration = 0;
currentResSlot = -1; currentResSlot = -1;
currentIndexBuffer = nullptr; currentIndexBuffer = nullptr;
currentIndexOffset = 0;
currentIndexFormat = QRhiCommandBuffer::IndexUInt16;
currentCullMode = -1;
currentFrontFaceWinding = -1;
d->currentFirstVertexBinding = -1; d->currentFirstVertexBinding = -1;
d->currentVertexInputsBuffers.clear(); d->currentVertexInputsBuffers.clear();

View File

@ -271,8 +271,11 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
ComputePass ComputePass
}; };
// per-pass (render or compute command encoder) persistent state
PassType recordingPass; PassType recordingPass;
QRhiRenderTarget *currentTarget; QRhiRenderTarget *currentTarget;
// per-pass (render or compute command encoder) volatile (cached) state
QRhiGraphicsPipeline *currentGraphicsPipeline; QRhiGraphicsPipeline *currentGraphicsPipeline;
QRhiComputePipeline *currentComputePipeline; QRhiComputePipeline *currentComputePipeline;
uint currentPipelineGeneration; uint currentPipelineGeneration;
@ -283,6 +286,8 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
QRhiBuffer *currentIndexBuffer; QRhiBuffer *currentIndexBuffer;
quint32 currentIndexOffset; quint32 currentIndexOffset;
QRhiCommandBuffer::IndexFormat currentIndexFormat; QRhiCommandBuffer::IndexFormat currentIndexFormat;
int currentCullMode;
int currentFrontFaceWinding;
const QRhiNativeHandles *nativeHandles(); const QRhiNativeHandles *nativeHandles();
void resetState(); void resetState();

View File

@ -1110,16 +1110,32 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
glyph_buffer.reset(new uchar[glyph_buffer_size]); glyph_buffer.reset(new uchar[glyph_buffer_size]);
if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
Q_ASSERT(format == Format_Mono);
uchar *src = slot->bitmap.buffer; uchar *src = slot->bitmap.buffer;
uchar *dst = glyph_buffer.data(); uchar *dst = glyph_buffer.data();
int h = slot->bitmap.rows; int h = slot->bitmap.rows;
// Some fonts return bitmaps even when we requested something else:
int bytes = ((info.width + 7) & ~7) >> 3; if (format == Format_Mono) {
while (h--) { int bytes = ((info.width + 7) & ~7) >> 3;
memcpy (dst, src, bytes); while (h--) {
dst += pitch; memcpy (dst, src, bytes);
src += slot->bitmap.pitch; dst += pitch;
src += slot->bitmap.pitch;
}
} else if (format == Format_A8) {
while (h--) {
for (int x = 0; x < int{info.width}; x++)
dst[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
dst += pitch;
src += slot->bitmap.pitch;
}
} else {
while (h--) {
uint *dd = reinterpret_cast<uint *>(dst);
for (int x = 0; x < int{info.width}; x++)
dd[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffffff : 0x00000000);
dst += pitch;
src += slot->bitmap.pitch;
}
} }
} else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) { } else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) {
Q_ASSERT(format == Format_ARGB); Q_ASSERT(format == Format_ARGB);

View File

@ -182,7 +182,7 @@ void Window::customRender()
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
const QSize outputSizeInPixels = m_sc->currentPixelSize(); const QSize outputSizeInPixels = m_sc->currentPixelSize();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });

View File

@ -197,7 +197,7 @@ void Window::customRender()
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
const QSize outputSizeInPixels = m_sc->currentPixelSize(); const QSize outputSizeInPixels = m_sc->currentPixelSize();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });

View File

@ -195,7 +195,7 @@ void Window::customRender()
cb->endComputePass(); cb->endComputePass();
// graphics pass // graphics pass
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
cb->setGraphicsPipeline(d.graphicsPipeline); cb->setGraphicsPipeline(d.graphicsPipeline);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
QRhiCommandBuffer::VertexInput vbufBinding(d.sbuf, 0); QRhiCommandBuffer::VertexInput vbufBinding(d.sbuf, 0);

View File

@ -217,7 +217,7 @@ void Window::customRender()
cb->dispatch(d.imageSize.width() / 16, d.imageSize.height() / 16, 1); cb->dispatch(d.imageSize.width() / 16, d.imageSize.height() / 16, 1);
cb->endComputePass(); cb->endComputePass();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources(); cb->setShaderResources();

View File

@ -168,7 +168,7 @@ void Window::customRender()
// no translation // no translation
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData()); u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height())); cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources(); cb->setShaderResources();

View File

@ -0,0 +1,241 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples 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$
**
****************************************************************************/
// This is a test for scissoring. Based on the cubemap test (because there the
// rendering covers the entire viewport which is what we need here). The
// scissor rectangle moves first up, then down, then from the center to the
// left and then to right. The important part is to ensure that the behavior
// identical between all backends, especially when the rectangle is partly or
// fully off window.
#include "../shared/examplefw.h"
#include "../shared/cube.h"
struct {
QVector<QRhiResource *> releasePool;
QRhiBuffer *vbuf = nullptr;
QRhiBuffer *ubuf = nullptr;
QRhiTexture *tex = nullptr;
QRhiSampler *sampler = nullptr;
QRhiShaderResourceBindings *srb = nullptr;
QRhiGraphicsPipeline *ps = nullptr;
QRhiResourceUpdateBatch *initialUpdates = nullptr;
QPoint scissorBottomLeft;
QSize scissorSize;
int scissorAnimState = 0;
QSize outputSize;
} d;
void Window::customInit()
{
d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(cube));
d.vbuf->build();
d.releasePool << d.vbuf;
d.ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64);
d.ubuf->build();
d.releasePool << d.ubuf;
const QSize cubeMapSize(512, 512);
d.tex = m_r->newTexture(QRhiTexture::RGBA8, cubeMapSize, 1, QRhiTexture::CubeMap);
d.releasePool << d.tex;
d.tex->build();
d.initialUpdates = m_r->nextResourceUpdateBatch();
d.initialUpdates->uploadStaticBuffer(d.vbuf, cube);
QImage img = QImage(":/c.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
// just use the same image for all faces for now
QRhiTextureSubresourceUploadDescription subresDesc(img);
QRhiTextureUploadDescription desc({
{ 0, 0, subresDesc }, // +X
{ 1, 0, subresDesc }, // -X
{ 2, 0, subresDesc }, // +Y
{ 3, 0, subresDesc }, // -Y
{ 4, 0, subresDesc }, // +Z
{ 5, 0, subresDesc } // -Z
});
d.initialUpdates->uploadTexture(d.tex, desc);
d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
QRhiSampler::Repeat, QRhiSampler::Repeat);
d.releasePool << d.sampler;
d.sampler->build();
d.srb = m_r->newShaderResourceBindings();
d.releasePool << d.srb;
d.srb->setBindings({
QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, d.ubuf),
QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, d.tex, d.sampler)
});
d.srb->build();
d.ps = m_r->newGraphicsPipeline();
d.releasePool << d.ps;
d.ps->setFlags(QRhiGraphicsPipeline::UsesScissor);
d.ps->setDepthTest(true);
d.ps->setDepthWrite(true);
d.ps->setDepthOp(QRhiGraphicsPipeline::LessOrEqual);
d.ps->setCullMode(QRhiGraphicsPipeline::Front); // we are inside the cube so cull front, not back
d.ps->setFrontFace(QRhiGraphicsPipeline::CCW); // front is ccw in the cube data
QShader vs = getShader(QLatin1String(":/cubemap.vert.qsb"));
Q_ASSERT(vs.isValid());
QShader fs = getShader(QLatin1String(":/cubemap.frag.qsb"));
Q_ASSERT(fs.isValid());
d.ps->setShaderStages({
{ QRhiShaderStage::Vertex, vs },
{ QRhiShaderStage::Fragment, fs }
});
QRhiVertexInputLayout inputLayout;
inputLayout.setBindings({
{ 3 * sizeof(float) }
});
inputLayout.setAttributes({
{ 0, 0, QRhiVertexInputAttribute::Float3, 0 }
});
d.ps->setVertexInputLayout(inputLayout);
d.ps->setShaderResourceBindings(d.srb);
d.ps->setRenderPassDescriptor(m_rp);
d.ps->build();
d.scissorAnimState = 0;
}
void Window::customRelease()
{
qDeleteAll(d.releasePool);
d.releasePool.clear();
}
static void advanceScissor()
{
switch (d.scissorAnimState) {
case 1: // up
d.scissorBottomLeft.setX(d.outputSize.width() / 4);
d.scissorBottomLeft.ry() += 1;
if (d.scissorBottomLeft.y() > d.outputSize.height() + 100)
d.scissorAnimState = 2;
break;
case 2: // down
d.scissorBottomLeft.ry() -= 1;
if (d.scissorBottomLeft.y() < -d.scissorSize.height() - 100)
d.scissorAnimState = 3;
break;
case 3: // left
d.scissorBottomLeft.setY(d.outputSize.height() / 4);
d.scissorBottomLeft.rx() += 1;
if (d.scissorBottomLeft.x() > d.outputSize.width() + 100)
d.scissorAnimState = 4;
break;
case 4: // right
d.scissorBottomLeft.rx() -= 1;
if (d.scissorBottomLeft.x() < -d.scissorSize.width() - 100)
d.scissorAnimState = 1;
break;
}
qDebug() << "scissor bottom-left" << d.scissorBottomLeft << "size" << d.scissorSize;
}
void Window::customRender()
{
const QSize outputSizeInPixels = m_sc->currentPixelSize();
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
QRhiResourceUpdateBatch *u = m_r->nextResourceUpdateBatch();
if (d.initialUpdates) {
u->merge(d.initialUpdates);
d.initialUpdates->release();
d.initialUpdates = nullptr;
}
d.outputSize = outputSizeInPixels;
if (d.scissorAnimState == 0) {
d.scissorBottomLeft = QPoint(outputSizeInPixels.width() / 4, 0);
d.scissorSize = QSize(outputSizeInPixels.width() / 2, outputSizeInPixels.height() / 2);
d.scissorAnimState = 1;
}
QMatrix4x4 mvp = m_r->clipSpaceCorrMatrix();
mvp.perspective(90.0f, outputSizeInPixels.width() / (float) outputSizeInPixels.height(), 0.01f, 1000.0f);
// cube vertices go from -1..1
mvp.scale(10);
static float rx = 0;
mvp.rotate(rx, 1, 0, 0);
rx += 0.5f;
// no translation
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
// Apply a scissor rectangle that moves around on the screen, also
// exercising the out of screen (negative x or y) case.
cb->setScissor(QRhiScissor(d.scissorBottomLeft.x(), d.scissorBottomLeft.y(),
d.scissorSize.width(), d.scissorSize.height()));
cb->setShaderResources();
const QRhiCommandBuffer::VertexInput vbufBinding(d.vbuf, 0);
cb->setVertexInput(0, 1, &vbufBinding);
cb->draw(36);
cb->endPass();
advanceScissor();
}

View File

@ -0,0 +1,8 @@
TEMPLATE = app
QT += gui-private
SOURCES = \
cubemap_scissor.cpp
RESOURCES = cubemap_scissor.qrc

View File

@ -0,0 +1,7 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="cubemap.vert.qsb">../cubemap/cubemap.vert.qsb</file>
<file alias="cubemap.frag.qsb">../cubemap/cubemap.frag.qsb</file>
<file alias="c.png">../cubemap/c.png</file>
</qresource>
</RCC>

View File

@ -317,7 +317,7 @@ void Window::customRender()
} }
const QSize outputSizeInPixels = m_sc->currentPixelSize(); const QSize outputSizeInPixels = m_sc->currentPixelSize();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources(); cb->setShaderResources();

View File

@ -161,7 +161,7 @@ void Window::customRender()
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData()); u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
} }
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources(); cb->setShaderResources();

View File

@ -283,7 +283,7 @@ void Window::customRender()
} }
const QSize outputSizeInPixels = m_sc->currentPixelSize(); const QSize outputSizeInPixels = m_sc->currentPixelSize();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
vbufBinding.second = 0; vbufBinding.second = 0;

View File

@ -248,7 +248,7 @@ void Window::customRender()
// onscreen (quad) // onscreen (quad)
const QSize outputSizeInPixels = m_sc->currentPixelSize(); const QSize outputSizeInPixels = m_sc->currentPixelSize();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources(); cb->setShaderResources();

View File

@ -315,7 +315,7 @@ void Window::customRender()
// onscreen // onscreen
const QSize outputSizeInPixels = m_sc->currentPixelSize(); const QSize outputSizeInPixels = m_sc->currentPixelSize();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
cb->setGraphicsPipeline(d.psLeft); // showing the non-msaa version cb->setGraphicsPipeline(d.psLeft); // showing the non-msaa version
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources(); cb->setShaderResources();

View File

@ -8,6 +8,7 @@ SUBDIRS += \
msaatexture \ msaatexture \
msaarenderbuffer \ msaarenderbuffer \
cubemap \ cubemap \
cubemap_scissor \
multiwindow \ multiwindow \
multiwindow_threaded \ multiwindow_threaded \
triquadcube \ triquadcube \

View File

@ -296,7 +296,7 @@ void Window::customRender()
cb->endPass(); cb->endPass();
// main pass // main pass
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
enqueueScene(cb, d.srb, oneRoundedUniformBlockSize, 0); enqueueScene(cb, d.srb, oneRoundedUniformBlockSize, 0);

View File

@ -127,6 +127,7 @@ QRhiSwapChain::Flags scFlags = 0;
QRhi::BeginFrameFlags beginFrameFlags = 0; QRhi::BeginFrameFlags beginFrameFlags = 0;
QRhi::EndFrameFlags endFrameFlags = 0; QRhi::EndFrameFlags endFrameFlags = 0;
int framesUntilTdr = -1; int framesUntilTdr = -1;
bool transparentBackground = false;
class Window : public QWindow class Window : public QWindow
{ {
@ -167,6 +168,8 @@ protected:
QOffscreenSurface *m_fallbackSurface = nullptr; QOffscreenSurface *m_fallbackSurface = nullptr;
#endif #endif
QColor m_clearColor;
friend int main(int, char**); friend int main(int, char**);
}; };
@ -194,6 +197,8 @@ Window::Window()
default: default:
break; break;
} }
m_clearColor = transparentBackground ? Qt::transparent : QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f);
} }
Window::~Window() Window::~Window()
@ -477,6 +482,9 @@ int main(int argc, char **argv)
QCommandLineOption swOption(QLatin1String("software"), QLatin1String("Prefer a software renderer when choosing the adapter. " QCommandLineOption swOption(QLatin1String("software"), QLatin1String("Prefer a software renderer when choosing the adapter. "
"Only applicable with some APIs and platforms.")); "Only applicable with some APIs and platforms."));
cmdLineParser.addOption(swOption); cmdLineParser.addOption(swOption);
// Allow testing having a semi-transparent window.
QCommandLineOption transparentOption(QLatin1String("transparent"), QLatin1String("Make background transparent"));
cmdLineParser.addOption(transparentOption);
cmdLineParser.process(app); cmdLineParser.process(app);
if (cmdLineParser.isSet(nullOption)) if (cmdLineParser.isSet(nullOption))
@ -493,6 +501,11 @@ int main(int argc, char **argv)
qDebug("Selected graphics API is %s", qPrintable(graphicsApiName())); qDebug("Selected graphics API is %s", qPrintable(graphicsApiName()));
qDebug("This is a multi-api example, use command line arguments to override:\n%s", qPrintable(cmdLineParser.helpText())); qDebug("This is a multi-api example, use command line arguments to override:\n%s", qPrintable(cmdLineParser.helpText()));
if (cmdLineParser.isSet(transparentOption)) {
transparentBackground = true;
scFlags |= QRhiSwapChain::SurfaceHasPreMulAlpha;
}
#ifdef EXAMPLEFW_PREINIT #ifdef EXAMPLEFW_PREINIT
void preInit(); void preInit();
preInit(); preInit();
@ -508,6 +521,9 @@ int main(int argc, char **argv)
fmt.setSwapInterval(0); fmt.setSwapInterval(0);
if (scFlags.testFlag(QRhiSwapChain::sRGB)) if (scFlags.testFlag(QRhiSwapChain::sRGB))
fmt.setColorSpace(QSurfaceFormat::sRGBColorSpace); fmt.setColorSpace(QSurfaceFormat::sRGBColorSpace);
// Exception: The alpha size is not necessarily OpenGL specific.
if (transparentBackground)
fmt.setAlphaBufferSize(8);
QSurfaceFormat::setDefaultFormat(fmt); QSurfaceFormat::setDefaultFormat(fmt);
// Vulkan setup. // Vulkan setup.

View File

@ -296,7 +296,7 @@ void Window::customRender()
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer(); QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
const QSize outputSizeInPixels = m_sc->currentPixelSize(); const QSize outputSizeInPixels = m_sc->currentPixelSize();
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps); cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) }); cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });

View File

@ -230,7 +230,7 @@ void Window::customRender()
if (!d.onScreenOnly) if (!d.onScreenOnly)
d.liveTexCubeRenderer.queueResourceUpdates(u); d.liveTexCubeRenderer.queueResourceUpdates(u);
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u); cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
cb->debugMarkBegin(QByteArrayLiteral("Triangle")); cb->debugMarkBegin(QByteArrayLiteral("Triangle"));
d.triRenderer.queueDraw(cb, outputSize); d.triRenderer.queueDraw(cb, outputSize);
cb->debugMarkEnd(); cb->debugMarkEnd();