rhi: metal: Remap resource bindings based on the QShader table
...when available. Fall back to the QRhi (i.e. SPIR-V) binding point otherwise (which becomes unsafe once shadertools bumps its SPIRV-Cross snapshot, but is fine for existing .qsb files) Task-number: QTBUG-79368 Change-Id: I2d452fdd4efb484867732c358171a800d3261dcd Reviewed-by: Christian Strømme <christian.stromme@qt.io>
This commit is contained in:
parent
6326d1df39
commit
cc631c15a0
@ -35,8 +35,6 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qrhimetal_p_p.h"
|
#include "qrhimetal_p_p.h"
|
||||||
#include "qshader_p.h"
|
|
||||||
#include "qshaderdescription_p.h"
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
@ -143,8 +141,10 @@ struct QMetalShader
|
|||||||
id<MTLLibrary> lib = nil;
|
id<MTLLibrary> lib = nil;
|
||||||
id<MTLFunction> func = nil;
|
id<MTLFunction> func = nil;
|
||||||
std::array<uint, 3> localSize;
|
std::array<uint, 3> localSize;
|
||||||
|
QShader::NativeResourceBindingMap nativeResourceBindingMap;
|
||||||
|
|
||||||
void release() {
|
void release() {
|
||||||
|
nativeResourceBindingMap.clear();
|
||||||
[lib release];
|
[lib release];
|
||||||
lib = nil;
|
lib = nil;
|
||||||
[func release];
|
[func release];
|
||||||
@ -164,7 +164,7 @@ struct QRhiMetalData
|
|||||||
const QRhiDepthStencilClearValue &depthStencilClearValue,
|
const QRhiDepthStencilClearValue &depthStencilClearValue,
|
||||||
int colorAttCount);
|
int colorAttCount);
|
||||||
id<MTLLibrary> createMetalLib(const QShader &shader, QShader::Variant shaderVariant,
|
id<MTLLibrary> createMetalLib(const QShader &shader, QShader::Variant shaderVariant,
|
||||||
QString *error, QByteArray *entryPoint);
|
QString *error, QByteArray *entryPoint, QShaderKey *activeKey);
|
||||||
id<MTLFunction> createMSLShaderFunction(id<MTLLibrary> lib, const QByteArray &entryPoint);
|
id<MTLFunction> createMSLShaderFunction(id<MTLLibrary> lib, const QByteArray &entryPoint);
|
||||||
|
|
||||||
struct DeferredReleaseEntry {
|
struct DeferredReleaseEntry {
|
||||||
@ -653,18 +653,39 @@ QRhiShaderResourceBindings *QRhiMetal::createShaderResourceBindings()
|
|||||||
return new QMetalShaderResourceBindings(this);
|
return new QMetalShaderResourceBindings(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD, QMetalCommandBuffer *cbD,
|
enum class BindingType {
|
||||||
|
Buffer,
|
||||||
|
Texture,
|
||||||
|
Sampler
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int mapBinding(int binding,
|
||||||
|
int stageIndex,
|
||||||
|
const QShader::NativeResourceBindingMap *nativeResourceBindingMaps[],
|
||||||
|
BindingType type)
|
||||||
|
{
|
||||||
|
const QShader::NativeResourceBindingMap *map = nativeResourceBindingMaps[stageIndex];
|
||||||
|
if (map) {
|
||||||
|
auto it = map->constFind(binding);
|
||||||
|
if (it != map->cend())
|
||||||
|
return type == BindingType::Sampler ? it->second : it->first;
|
||||||
|
}
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD,
|
||||||
|
QMetalCommandBuffer *cbD,
|
||||||
int dynamicOffsetCount,
|
int dynamicOffsetCount,
|
||||||
const QRhiCommandBuffer::DynamicOffset *dynamicOffsets,
|
const QRhiCommandBuffer::DynamicOffset *dynamicOffsets,
|
||||||
bool offsetOnlyChange)
|
bool offsetOnlyChange,
|
||||||
|
const QShader::NativeResourceBindingMap *nativeResourceBindingMaps[SUPPORTED_STAGES])
|
||||||
{
|
{
|
||||||
static const int KNOWN_STAGES = 3;
|
|
||||||
struct {
|
struct {
|
||||||
QRhiBatchedBindings<id<MTLBuffer> > buffers;
|
QRhiBatchedBindings<id<MTLBuffer> > buffers;
|
||||||
QRhiBatchedBindings<NSUInteger> bufferOffsets;
|
QRhiBatchedBindings<NSUInteger> bufferOffsets;
|
||||||
QRhiBatchedBindings<id<MTLTexture> > textures;
|
QRhiBatchedBindings<id<MTLTexture> > textures;
|
||||||
QRhiBatchedBindings<id<MTLSamplerState> > samplers;
|
QRhiBatchedBindings<id<MTLSamplerState> > samplers;
|
||||||
} res[KNOWN_STAGES];
|
} res[SUPPORTED_STAGES];
|
||||||
|
|
||||||
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
||||||
const QRhiShaderResourceBinding::Data *b = binding.data();
|
const QRhiShaderResourceBinding::Data *b = binding.data();
|
||||||
@ -682,15 +703,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
||||||
res[0].buffers.feed(b->binding, mtlbuf);
|
res[0].buffers.feed(mapBinding(b->binding, 0, nativeResourceBindingMaps, BindingType::Buffer), mtlbuf);
|
||||||
res[0].bufferOffsets.feed(b->binding, offset);
|
res[0].bufferOffsets.feed(b->binding, offset);
|
||||||
}
|
}
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
||||||
res[1].buffers.feed(b->binding, mtlbuf);
|
res[1].buffers.feed(mapBinding(b->binding, 1, nativeResourceBindingMaps, BindingType::Buffer), mtlbuf);
|
||||||
res[1].bufferOffsets.feed(b->binding, offset);
|
res[1].bufferOffsets.feed(b->binding, offset);
|
||||||
}
|
}
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
||||||
res[2].buffers.feed(b->binding, mtlbuf);
|
res[2].buffers.feed(mapBinding(b->binding, 2, nativeResourceBindingMaps, BindingType::Buffer), mtlbuf);
|
||||||
res[2].bufferOffsets.feed(b->binding, offset);
|
res[2].bufferOffsets.feed(b->binding, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -700,16 +721,16 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
QMetalTexture *texD = QRHI_RES(QMetalTexture, b->u.stex.tex);
|
QMetalTexture *texD = QRHI_RES(QMetalTexture, b->u.stex.tex);
|
||||||
QMetalSampler *samplerD = QRHI_RES(QMetalSampler, b->u.stex.sampler);
|
QMetalSampler *samplerD = QRHI_RES(QMetalSampler, b->u.stex.sampler);
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
||||||
res[0].textures.feed(b->binding, texD->d->tex);
|
res[0].textures.feed(mapBinding(b->binding, 0, nativeResourceBindingMaps, BindingType::Texture), texD->d->tex);
|
||||||
res[0].samplers.feed(b->binding, samplerD->d->samplerState);
|
res[0].samplers.feed(mapBinding(b->binding, 0, nativeResourceBindingMaps, BindingType::Sampler), samplerD->d->samplerState);
|
||||||
}
|
}
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
||||||
res[1].textures.feed(b->binding, texD->d->tex);
|
res[1].textures.feed(mapBinding(b->binding, 1, nativeResourceBindingMaps, BindingType::Texture), texD->d->tex);
|
||||||
res[1].samplers.feed(b->binding, samplerD->d->samplerState);
|
res[1].samplers.feed(mapBinding(b->binding, 1, nativeResourceBindingMaps, BindingType::Sampler), samplerD->d->samplerState);
|
||||||
}
|
}
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
||||||
res[2].textures.feed(b->binding, texD->d->tex);
|
res[2].textures.feed(mapBinding(b->binding, 2, nativeResourceBindingMaps, BindingType::Texture), texD->d->tex);
|
||||||
res[2].samplers.feed(b->binding, samplerD->d->samplerState);
|
res[2].samplers.feed(mapBinding(b->binding, 2, nativeResourceBindingMaps, BindingType::Sampler), samplerD->d->samplerState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -722,11 +743,11 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
QMetalTexture *texD = QRHI_RES(QMetalTexture, b->u.simage.tex);
|
QMetalTexture *texD = QRHI_RES(QMetalTexture, b->u.simage.tex);
|
||||||
id<MTLTexture> t = texD->d->viewForLevel(b->u.simage.level);
|
id<MTLTexture> t = texD->d->viewForLevel(b->u.simage.level);
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage))
|
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage))
|
||||||
res[0].textures.feed(b->binding, t);
|
res[0].textures.feed(mapBinding(b->binding, 0, nativeResourceBindingMaps, BindingType::Texture), t);
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage))
|
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage))
|
||||||
res[1].textures.feed(b->binding, t);
|
res[1].textures.feed(mapBinding(b->binding, 1, nativeResourceBindingMaps, BindingType::Texture), t);
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage))
|
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage))
|
||||||
res[2].textures.feed(b->binding, t);
|
res[2].textures.feed(mapBinding(b->binding, 2, nativeResourceBindingMaps, BindingType::Texture), t);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QRhiShaderResourceBinding::BufferLoad:
|
case QRhiShaderResourceBinding::BufferLoad:
|
||||||
@ -739,15 +760,15 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
id<MTLBuffer> mtlbuf = bufD->d->buf[0];
|
id<MTLBuffer> mtlbuf = bufD->d->buf[0];
|
||||||
uint offset = uint(b->u.sbuf.offset);
|
uint offset = uint(b->u.sbuf.offset);
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::VertexStage)) {
|
||||||
res[0].buffers.feed(b->binding, mtlbuf);
|
res[0].buffers.feed(mapBinding(b->binding, 0, nativeResourceBindingMaps, BindingType::Buffer), mtlbuf);
|
||||||
res[0].bufferOffsets.feed(b->binding, offset);
|
res[0].bufferOffsets.feed(b->binding, offset);
|
||||||
}
|
}
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::FragmentStage)) {
|
||||||
res[1].buffers.feed(b->binding, mtlbuf);
|
res[1].buffers.feed(mapBinding(b->binding, 1, nativeResourceBindingMaps, BindingType::Buffer), mtlbuf);
|
||||||
res[1].bufferOffsets.feed(b->binding, offset);
|
res[1].bufferOffsets.feed(b->binding, offset);
|
||||||
}
|
}
|
||||||
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
if (b->stage.testFlag(QRhiShaderResourceBinding::ComputeStage)) {
|
||||||
res[2].buffers.feed(b->binding, mtlbuf);
|
res[2].buffers.feed(mapBinding(b->binding, 2, nativeResourceBindingMaps, BindingType::Buffer), mtlbuf);
|
||||||
res[2].bufferOffsets.feed(b->binding, offset);
|
res[2].bufferOffsets.feed(b->binding, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -758,7 +779,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int idx = 0; idx < KNOWN_STAGES; ++idx) {
|
for (int idx = 0; idx < SUPPORTED_STAGES; ++idx) {
|
||||||
res[idx].buffers.finish();
|
res[idx].buffers.finish();
|
||||||
res[idx].bufferOffsets.finish();
|
res[idx].bufferOffsets.finish();
|
||||||
|
|
||||||
@ -973,18 +994,22 @@ void QRhiMetal::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
|
|
||||||
// dynamic uniform buffer offsets always trigger a rebind
|
// dynamic uniform buffer offsets always trigger a rebind
|
||||||
if (hasDynamicOffsetInSrb || resNeedsRebind || srbChanged || srbRebuilt) {
|
if (hasDynamicOffsetInSrb || resNeedsRebind || srbChanged || srbRebuilt) {
|
||||||
|
const QShader::NativeResourceBindingMap *resBindMaps[SUPPORTED_STAGES] = { nullptr, nullptr, nullptr };
|
||||||
if (gfxPsD) {
|
if (gfxPsD) {
|
||||||
cbD->currentGraphicsSrb = srb;
|
cbD->currentGraphicsSrb = srb;
|
||||||
cbD->currentComputeSrb = nullptr;
|
cbD->currentComputeSrb = nullptr;
|
||||||
|
resBindMaps[0] = &gfxPsD->d->vs.nativeResourceBindingMap;
|
||||||
|
resBindMaps[1] = &gfxPsD->d->fs.nativeResourceBindingMap;
|
||||||
} else {
|
} else {
|
||||||
cbD->currentGraphicsSrb = nullptr;
|
cbD->currentGraphicsSrb = nullptr;
|
||||||
cbD->currentComputeSrb = srb;
|
cbD->currentComputeSrb = srb;
|
||||||
|
resBindMaps[2] = &compPsD->d->cs.nativeResourceBindingMap;
|
||||||
}
|
}
|
||||||
cbD->currentSrbGeneration = srbD->generation;
|
cbD->currentSrbGeneration = srbD->generation;
|
||||||
cbD->currentResSlot = resSlot;
|
cbD->currentResSlot = resSlot;
|
||||||
|
|
||||||
const bool offsetOnlyChange = hasDynamicOffsetInSrb && !resNeedsRebind && !srbChanged && !srbRebuilt;
|
const bool offsetOnlyChange = hasDynamicOffsetInSrb && !resNeedsRebind && !srbChanged && !srbRebuilt;
|
||||||
enqueueShaderResourceBindings(srbD, cbD, dynamicOffsetCount, dynamicOffsets, offsetOnlyChange);
|
enqueueShaderResourceBindings(srbD, cbD, dynamicOffsetCount, dynamicOffsets, offsetOnlyChange, resBindMaps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3081,9 +3106,10 @@ static inline MTLCullMode toMetalCullMode(QRhiGraphicsPipeline::CullMode c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Variant shaderVariant,
|
id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Variant shaderVariant,
|
||||||
QString *error, QByteArray *entryPoint)
|
QString *error, QByteArray *entryPoint, QShaderKey *activeKey)
|
||||||
{
|
{
|
||||||
QShaderCode mtllib = shader.shader({ QShader::MetalLibShader, 12, shaderVariant });
|
QShaderKey key = { QShader::MetalLibShader, 12, shaderVariant };
|
||||||
|
QShaderCode mtllib = shader.shader(key);
|
||||||
if (!mtllib.shader().isEmpty()) {
|
if (!mtllib.shader().isEmpty()) {
|
||||||
dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(),
|
dispatch_data_t data = dispatch_data_create(mtllib.shader().constData(),
|
||||||
size_t(mtllib.shader().size()),
|
size_t(mtllib.shader().size()),
|
||||||
@ -3094,6 +3120,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
|
|||||||
dispatch_release(data);
|
dispatch_release(data);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
*entryPoint = mtllib.entryPoint();
|
*entryPoint = mtllib.entryPoint();
|
||||||
|
*activeKey = key;
|
||||||
return lib;
|
return lib;
|
||||||
} else {
|
} else {
|
||||||
const QString msg = QString::fromNSString(err.localizedDescription);
|
const QString msg = QString::fromNSString(err.localizedDescription);
|
||||||
@ -3101,7 +3128,8 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QShaderCode mslSource = shader.shader({ QShader::MslShader, 12, shaderVariant });
|
key = { QShader::MslShader, 12, shaderVariant };
|
||||||
|
QShaderCode mslSource = shader.shader(key);
|
||||||
if (mslSource.shader().isEmpty()) {
|
if (mslSource.shader().isEmpty()) {
|
||||||
qWarning() << "No MSL 1.2 code found in baked shader" << shader;
|
qWarning() << "No MSL 1.2 code found in baked shader" << shader;
|
||||||
return nil;
|
return nil;
|
||||||
@ -3122,6 +3150,7 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
|
|||||||
}
|
}
|
||||||
|
|
||||||
*entryPoint = mslSource.entryPoint();
|
*entryPoint = mslSource.entryPoint();
|
||||||
|
*activeKey = key;
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3195,9 +3224,12 @@ bool QMetalGraphicsPipeline::build()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const QShader shader = shaderStage.shader();
|
||||||
QString error;
|
QString error;
|
||||||
QByteArray entryPoint;
|
QByteArray entryPoint;
|
||||||
id<MTLLibrary> lib = rhiD->d->createMetalLib(shaderStage.shader(), shaderStage.shaderVariant(), &error, &entryPoint);
|
QShaderKey activeKey;
|
||||||
|
id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, shaderStage.shaderVariant(),
|
||||||
|
&error, &entryPoint, &activeKey);
|
||||||
if (!lib) {
|
if (!lib) {
|
||||||
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
||||||
return false;
|
return false;
|
||||||
@ -3218,6 +3250,8 @@ bool QMetalGraphicsPipeline::build()
|
|||||||
case QRhiShaderStage::Vertex:
|
case QRhiShaderStage::Vertex:
|
||||||
d->vs.lib = lib;
|
d->vs.lib = lib;
|
||||||
d->vs.func = func;
|
d->vs.func = func;
|
||||||
|
if (const QShader::NativeResourceBindingMap *map = shader.nativeResourceBindingMap(activeKey))
|
||||||
|
d->vs.nativeResourceBindingMap = *map;
|
||||||
rhiD->d->shaderCache.insert(shaderStage, d->vs);
|
rhiD->d->shaderCache.insert(shaderStage, d->vs);
|
||||||
[d->vs.lib retain];
|
[d->vs.lib retain];
|
||||||
[d->vs.func retain];
|
[d->vs.func retain];
|
||||||
@ -3226,6 +3260,8 @@ bool QMetalGraphicsPipeline::build()
|
|||||||
case QRhiShaderStage::Fragment:
|
case QRhiShaderStage::Fragment:
|
||||||
d->fs.lib = lib;
|
d->fs.lib = lib;
|
||||||
d->fs.func = func;
|
d->fs.func = func;
|
||||||
|
if (const QShader::NativeResourceBindingMap *map = shader.nativeResourceBindingMap(activeKey))
|
||||||
|
d->fs.nativeResourceBindingMap = *map;
|
||||||
rhiD->d->shaderCache.insert(shaderStage, d->fs);
|
rhiD->d->shaderCache.insert(shaderStage, d->fs);
|
||||||
[d->fs.lib retain];
|
[d->fs.lib retain];
|
||||||
[d->fs.func retain];
|
[d->fs.func retain];
|
||||||
@ -3360,8 +3396,9 @@ bool QMetalComputePipeline::build()
|
|||||||
const QShader shader = m_shaderStage.shader();
|
const QShader shader = m_shaderStage.shader();
|
||||||
QString error;
|
QString error;
|
||||||
QByteArray entryPoint;
|
QByteArray entryPoint;
|
||||||
|
QShaderKey activeKey;
|
||||||
id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
|
id<MTLLibrary> lib = rhiD->d->createMetalLib(shader, m_shaderStage.shaderVariant(),
|
||||||
&error, &entryPoint);
|
&error, &entryPoint, &activeKey);
|
||||||
if (!lib) {
|
if (!lib) {
|
||||||
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
qWarning("MSL shader compilation failed: %s", qPrintable(error));
|
||||||
return false;
|
return false;
|
||||||
@ -3375,6 +3412,8 @@ bool QMetalComputePipeline::build()
|
|||||||
d->cs.lib = lib;
|
d->cs.lib = lib;
|
||||||
d->cs.func = func;
|
d->cs.func = func;
|
||||||
d->cs.localSize = shader.description().computeShaderLocalSize();
|
d->cs.localSize = shader.description().computeShaderLocalSize();
|
||||||
|
if (const QShader::NativeResourceBindingMap *map = shader.nativeResourceBindingMap(activeKey))
|
||||||
|
d->cs.nativeResourceBindingMap = *map;
|
||||||
|
|
||||||
if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
|
if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
|
||||||
for (QMetalShader &s : rhiD->d->shaderCache)
|
for (QMetalShader &s : rhiD->d->shaderCache)
|
||||||
|
@ -433,10 +433,13 @@ public:
|
|||||||
qsizetype *curOfs);
|
qsizetype *curOfs);
|
||||||
void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
|
void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
|
||||||
void executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD);
|
void executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD);
|
||||||
void enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD, QMetalCommandBuffer *cbD,
|
static const int SUPPORTED_STAGES = 3;
|
||||||
|
void enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD,
|
||||||
|
QMetalCommandBuffer *cbD,
|
||||||
int dynamicOffsetCount,
|
int dynamicOffsetCount,
|
||||||
const QRhiCommandBuffer::DynamicOffset *dynamicOffsets,
|
const QRhiCommandBuffer::DynamicOffset *dynamicOffsets,
|
||||||
bool offsetOnlyChange);
|
bool offsetOnlyChange,
|
||||||
|
const QShader::NativeResourceBindingMap *nativeResourceBindingMaps[SUPPORTED_STAGES]);
|
||||||
int effectiveSampleCount(int sampleCount) const;
|
int effectiveSampleCount(int sampleCount) const;
|
||||||
|
|
||||||
bool importedDevice = false;
|
bool importedDevice = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user