Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Laszlo Agocs
qtrhi
Commits
cbb16855
Commit
cbb16855
authored
Jan 10, 2019
by
Laszlo Agocs
Browse files
Improve resource binding logic
Esp. for Metal where we now avoid superfluous set* for shader resources.
parent
211520f0
Changes
10
Hide whitespace changes
Inline
Side-by-side
examples/rhi/imguidemo/qrhiimgui.cpp
View file @
cbb16855
...
...
@@ -105,6 +105,7 @@ bool QRhiImgui::prepareFrame(QRhiRenderTarget *rt, QRhiRenderPassDescriptor *rp,
if
(
!
d
->
ubuf
)
{
d
->
ubuf
=
d
->
rhi
->
newBuffer
(
QRhiBuffer
::
Dynamic
,
QRhiBuffer
::
UniformBuffer
,
64
+
4
);
d
->
ubuf
->
setName
(
QByteArrayLiteral
(
"imgui uniform buffer"
));
d
->
releasePool
<<
d
->
ubuf
;
if
(
!
d
->
ubuf
->
build
())
return
false
;
...
...
@@ -124,14 +125,17 @@ bool QRhiImgui::prepareFrame(QRhiRenderTarget *rt, QRhiRenderPassDescriptor *rp,
if
(
!
d
->
sampler
)
{
d
->
sampler
=
d
->
rhi
->
newSampler
(
QRhiSampler
::
Linear
,
QRhiSampler
::
Linear
,
QRhiSampler
::
None
,
QRhiSampler
::
Repeat
,
QRhiSampler
::
Repeat
);
d
->
sampler
->
setName
(
QByteArrayLiteral
(
"imgui sampler"
));
d
->
releasePool
<<
d
->
sampler
;
if
(
!
d
->
sampler
->
build
())
return
false
;
}
for
(
QRhiImguiPrivate
::
Texture
&
t
:
d
->
textures
)
{
for
(
int
i
=
0
;
i
<
d
->
textures
.
count
();
++
i
)
{
QRhiImguiPrivate
::
Texture
&
t
(
d
->
textures
[
i
]);
if
(
!
t
.
tex
)
{
t
.
tex
=
d
->
rhi
->
newTexture
(
QRhiTexture
::
RGBA8
,
t
.
image
.
size
());
t
.
tex
->
setName
(
QByteArrayLiteral
(
"imgui texture "
)
+
QByteArray
::
number
(
i
));
if
(
!
t
.
tex
->
build
())
return
false
;
dstResourceUpdates
->
uploadTexture
(
t
.
tex
,
t
.
image
);
...
...
@@ -212,6 +216,7 @@ bool QRhiImgui::prepareFrame(QRhiRenderTarget *rt, QRhiRenderPassDescriptor *rp,
if
(
!
d
->
vbuf
)
{
d
->
vbuf
=
d
->
rhi
->
newBuffer
(
QRhiBuffer
::
Dynamic
,
QRhiBuffer
::
VertexBuffer
,
totalVbufSize
);
d
->
vbuf
->
setName
(
QByteArrayLiteral
(
"imgui vertex buffer"
));
d
->
releasePool
<<
d
->
vbuf
;
if
(
!
d
->
vbuf
->
build
())
return
false
;
...
...
@@ -224,6 +229,7 @@ bool QRhiImgui::prepareFrame(QRhiRenderTarget *rt, QRhiRenderPassDescriptor *rp,
}
if
(
!
d
->
ibuf
)
{
d
->
ibuf
=
d
->
rhi
->
newBuffer
(
QRhiBuffer
::
Dynamic
,
QRhiBuffer
::
IndexBuffer
,
totalIbufSize
);
d
->
ibuf
->
setName
(
QByteArrayLiteral
(
"imgui index buffer"
));
d
->
releasePool
<<
d
->
ibuf
;
if
(
!
d
->
ibuf
->
build
())
return
false
;
...
...
examples/rhi/shared/examplefw.h
View file @
cbb16855
...
...
@@ -116,7 +116,7 @@ QString graphicsApiName()
return
QString
();
}
QRhi
::
Flags
rhiFlags
=
0
;
QRhi
::
Flags
rhiFlags
=
QRhi
::
EnableDebugMarkers
;
int
sampleCount
=
1
;
QRhiSwapChain
::
Flags
scFlags
=
0
;
...
...
examples/rhi/triquadcube/triquadcube.cpp
View file @
cbb16855
...
...
@@ -84,8 +84,6 @@ struct {
void
preInit
()
{
rhiFlags
|=
QRhi
::
EnableDebugMarkers
;
#ifdef PROFILE_TO_FILE
rhiFlags
|=
QRhi
::
EnableProfiling
;
const
QString
profFn
=
QFileInfo
(
QLatin1String
(
"rhiprof.txt"
)).
absoluteFilePath
();
...
...
src/rhi/qrhi.h
View file @
cbb16855
...
...
@@ -367,9 +367,9 @@ public:
// This has two uses: to get names visible in graphics debugging tools and
// in the profiling output. Regarding the former, the name is ignored when
// DebugMarkers are not supported
or EnableDebugMarkers is not set. May
// also be ignored for objects other
than buffers, renderbuffers, and
// textures, depending on the backend.
// DebugMarkers are not supported
, and may be ignored when
//
EnableDebugMarkers is not set. May
also be ignored for objects other
//
than buffers, renderbuffers, and
textures, depending on the backend.
QByteArray
name
()
const
;
void
setName
(
const
QByteArray
&
name
);
...
...
src/rhi/qrhid3d11.cpp
View file @
cbb16855
...
...
@@ -372,6 +372,7 @@ void QRhiD3D11::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
break
;
}
}
if
(
srbUpdate
)
updateShaderResourceBindings
(
srbD
);
...
...
@@ -1258,18 +1259,22 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
}
break
;
case
QRhiShaderResourceBinding
::
SampledTexture
:
{
// A sampler with binding N is mapped to a HLSL sampler and texture
// with registers sN and tN by SPIRV-Cross.
bd
.
stex
.
texGeneration
=
QRHI_RES
(
QD3D11Texture
,
b
.
stex
.
tex
)
->
generation
;
bd
.
stex
.
samplerGeneration
=
QRHI_RES
(
QD3D11Sampler
,
b
.
stex
.
sampler
)
->
generation
;
QD3D11Texture
*
texD
=
QRHI_RES
(
QD3D11Texture
,
b
.
stex
.
tex
);
QD3D11Sampler
*
samplerD
=
QRHI_RES
(
QD3D11Sampler
,
b
.
stex
.
sampler
);
bd
.
stex
.
texGeneration
=
texD
->
generation
;
bd
.
stex
.
samplerGeneration
=
samplerD
->
generation
;
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
VertexStage
))
{
srbD
->
vssamplers
.
feed
(
b
.
binding
,
QRHI_RES
(
QD3D11Sampler
,
b
.
stex
.
sampler
)
->
samplerState
);
srbD
->
vsshaderresources
.
feed
(
b
.
binding
,
QRHI_RES
(
QD3D11Texture
,
b
.
stex
.
tex
)
->
srv
);
srbD
->
vssamplers
.
feed
(
b
.
binding
,
sampler
D
->
samplerState
);
srbD
->
vsshaderresources
.
feed
(
b
.
binding
,
texD
->
srv
);
}
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
FragmentStage
))
{
srbD
->
fssamplers
.
feed
(
b
.
binding
,
QRHI_RES
(
QD3D11Sampler
,
b
.
stex
.
sampler
)
->
samplerState
);
srbD
->
fsshaderresources
.
feed
(
b
.
binding
,
QRHI_RES
(
QD3D11Texture
,
b
.
stex
.
tex
)
->
srv
);
srbD
->
fssamplers
.
feed
(
b
.
binding
,
sampler
D
->
samplerState
);
srbD
->
fsshaderresources
.
feed
(
b
.
binding
,
texD
->
srv
);
}
}
break
;
default:
Q_UNREACHABLE
();
...
...
src/rhi/qrhimetal.mm
View file @
cbb16855
...
...
@@ -426,6 +426,41 @@ QRhiShaderResourceBindings *QRhiMetal::createShaderResourceBindings()
return
new
QMetalShaderResourceBindings
(
this
);
}
void
QRhiMetal
::
enqueueShaderResourceBindings
(
QMetalShaderResourceBindings
*
srbD
,
QMetalCommandBuffer
*
cbD
)
{
for
(
const
QRhiShaderResourceBinding
&
b
:
qAsConst
(
srbD
->
sortedBindings
))
{
switch
(
b
.
type
)
{
case
QRhiShaderResourceBinding
::
UniformBuffer
:
{
QMetalBuffer
*
bufD
=
QRHI_RES
(
QMetalBuffer
,
b
.
ubuf
.
buf
);
id
<
MTLBuffer
>
mtlbuf
=
bufD
->
d
->
buf
[
bufD
->
m_type
==
QRhiBuffer
:
:
Immutable
?
0
:
currentFrameSlot
];
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
VertexStage
))
[
cbD
->
d
->
currentPassEncoder
setVertexBuffer
:
mtlbuf
offset
:
b
.
ubuf
.
offset
atIndex
:
b
.
binding
];
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
FragmentStage
))
[
cbD
->
d
->
currentPassEncoder
setFragmentBuffer
:
mtlbuf
offset
:
b
.
ubuf
.
offset
atIndex
:
b
.
binding
];
}
break
;
case
QRhiShaderResourceBinding
::
SampledTexture
:
{
QMetalTexture
*
texD
=
QRHI_RES
(
QMetalTexture
,
b
.
stex
.
tex
);
QMetalSampler
*
samplerD
=
QRHI_RES
(
QMetalSampler
,
b
.
stex
.
sampler
);
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
VertexStage
))
{
[
cbD
->
d
->
currentPassEncoder
setVertexTexture
:
texD
->
d
->
tex
atIndex
:
b
.
binding
];
[
cbD
->
d
->
currentPassEncoder
setVertexSamplerState
:
samplerD
->
d
->
samplerState
atIndex
:
b
.
binding
];
}
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
FragmentStage
))
{
[
cbD
->
d
->
currentPassEncoder
setFragmentTexture
:
texD
->
d
->
tex
atIndex
:
b
.
binding
];
[
cbD
->
d
->
currentPassEncoder
setFragmentSamplerState
:
samplerD
->
d
->
samplerState
atIndex
:
b
.
binding
];
}
}
break
;
default:
Q_UNREACHABLE
();
break
;
}
}
}
void
QRhiMetal
::
setGraphicsPipeline
(
QRhiCommandBuffer
*
cb
,
QRhiGraphicsPipeline
*
ps
,
QRhiShaderResourceBindings
*
srb
)
{
Q_ASSERT
(
inPass
);
...
...
@@ -435,37 +470,43 @@ void QRhiMetal::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
srb
=
psD
->
m_shaderResourceBindings
;
QMetalShaderResourceBindings
*
srbD
=
QRHI_RES
(
QMetalShaderResourceBindings
,
srb
);
QMetalCommandBuffer
*
cbD
=
QRHI_RES
(
QMetalCommandBuffer
,
cb
);
for
(
const
QRhiShaderResourceBinding
&
b
:
qAsConst
(
srbD
->
sortedBindings
))
{
bool
hasSlottedResourceInSrb
=
false
;
const
int
resSlot
=
hasSlottedResourceInSrb
?
currentFrameSlot
:
0
;
bool
resNeedsRebind
=
false
;
// do host writes, figure out if we need to rebind, and mark as in-use
for
(
int
i
=
0
,
ie
=
srbD
->
sortedBindings
.
count
();
i
!=
ie
;
++
i
)
{
const
QRhiShaderResourceBinding
&
b
(
srbD
->
sortedBindings
[
i
]);
QMetalShaderResourceBindings
::
BoundResourceData
&
bd
(
srbD
->
boundResourceData
[
i
]);
switch
(
b
.
type
)
{
case
QRhiShaderResourceBinding
::
UniformBuffer
:
{
QMetalBuffer
*
bufD
=
QRHI_RES
(
QMetalBuffer
,
b
.
ubuf
.
buf
);
Q_ASSERT
(
bufD
->
m_usage
.
testFlag
(
QRhiBuffer
::
UniformBuffer
));
if
(
bufD
->
m_type
!=
QRhiBuffer
::
Immutable
)
{
// static and dynamic are both slotted
hasSlottedResourceInSrb
=
true
;
executeBufferHostWritesForCurrentFrame
(
bufD
);
}
if
(
bufD
->
generation
!=
bd
.
ubuf
.
generation
)
{
resNeedsRebind
=
true
;
bd
.
ubuf
.
generation
=
bufD
->
generation
;
}
bufD
->
lastActiveFrameSlot
=
currentFrameSlot
;
executeBufferHostWritesForCurrentFrame
(
bufD
);
id
<
MTLBuffer
>
mtlbuf
=
bufD
->
d
->
buf
[
bufD
->
m_type
==
QRhiBuffer
:
:
Immutable
?
0
:
currentFrameSlot
];
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
VertexStage
))
[
cbD
->
d
->
currentPassEncoder
setVertexBuffer
:
mtlbuf
offset
:
b
.
ubuf
.
offset
atIndex
:
b
.
binding
];
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
FragmentStage
))
[
cbD
->
d
->
currentPassEncoder
setFragmentBuffer
:
mtlbuf
offset
:
b
.
ubuf
.
offset
atIndex
:
b
.
binding
];
}
break
;
case
QRhiShaderResourceBinding
::
SampledTexture
:
{
QMetalTexture
*
tex
=
QRHI_RES
(
QMetalTexture
,
b
.
stex
.
tex
);
tex
->
lastActiveFrameSlot
=
currentFrameSlot
;
QMetalSampler
*
samp
=
QRHI_RES
(
QMetalSampler
,
b
.
stex
.
sampler
);
samp
->
lastActiveFrameSlot
=
currentFrameSlot
;
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
VertexStage
))
{
[
cbD
->
d
->
currentPassEncoder
setVertexTexture
:
tex
->
d
->
tex
atIndex
:
b
.
binding
];
[
cbD
->
d
->
currentPassEncoder
setVertexSamplerState
:
samp
->
d
->
samplerState
atIndex
:
b
.
binding
];
}
if
(
b
.
stage
.
testFlag
(
QRhiShaderResourceBinding
::
FragmentStage
))
{
[
cbD
->
d
->
currentPassEncoder
setFragmentTexture
:
tex
->
d
->
tex
atIndex
:
b
.
binding
];
[
cbD
->
d
->
currentPassEncoder
setFragmentSamplerState
:
samp
->
d
->
samplerState
atIndex
:
b
.
binding
];
QMetalTexture
*
texD
=
QRHI_RES
(
QMetalTexture
,
b
.
stex
.
tex
);
QMetalSampler
*
samplerD
=
QRHI_RES
(
QMetalSampler
,
b
.
stex
.
sampler
);
if
(
texD
->
generation
!=
bd
.
stex
.
texGeneration
||
samplerD
->
generation
!=
bd
.
stex
.
samplerGeneration
)
{
resNeedsRebind
=
true
;
bd
.
stex
.
texGeneration
=
texD
->
generation
;
bd
.
stex
.
samplerGeneration
=
samplerD
->
generation
;
}
texD
->
lastActiveFrameSlot
=
currentFrameSlot
;
samplerD
->
lastActiveFrameSlot
=
currentFrameSlot
;
}
break
;
default:
...
...
@@ -474,18 +515,27 @@ void QRhiMetal::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
}
}
if
(
cbD
->
currentPipeline
!=
ps
||
cbD
->
currentPipelineGeneration
!=
psD
->
generation
||
cbD
->
currentSrb
!=
srb
||
cbD
->
currentSrbGeneration
!=
srbD
->
generation
)
{
QMetalCommandBuffer
*
cbD
=
QRHI_RES
(
QMetalCommandBuffer
,
cb
);
// make sure the resources for the correct slot get bound
if
(
hasSlottedResourceInSrb
&&
cbD
->
currentResSlot
!=
resSlot
)
resNeedsRebind
=
true
;
if
(
cbD
->
currentPipeline
!=
ps
||
cbD
->
currentPipelineGeneration
!=
psD
->
generation
)
{
cbD
->
currentPipeline
=
ps
;
cbD
->
currentPipelineGeneration
=
psD
->
generation
;
cbD
->
currentSrb
=
srb
;
cbD
->
currentSrbGeneration
=
srbD
->
generation
;
[
cbD
->
d
->
currentPassEncoder
setRenderPipelineState
:
psD
->
d
->
ps
];
[
cbD
->
d
->
currentPassEncoder
setDepthStencilState
:
psD
->
d
->
ds
];
[
cbD
->
d
->
currentPassEncoder
setCullMode
:
psD
->
d
->
cullMode
];
[
cbD
->
d
->
currentPassEncoder
setFrontFacingWinding
:
psD
->
d
->
winding
];
}
if
(
resNeedsRebind
||
cbD
->
currentSrb
!=
srb
||
cbD
->
currentSrbGeneration
!=
srbD
->
generation
)
{
cbD
->
currentSrb
=
srb
;
cbD
->
currentSrbGeneration
=
srbD
->
generation
;
cbD
->
currentResSlot
=
resSlot
;
enqueueShaderResourceBindings
(
srbD
,
cbD
);
}
psD
->
lastActiveFrameSlot
=
currentFrameSlot
;
}
...
...
@@ -1341,8 +1391,14 @@ bool QMetalBuffer::build()
if
(
i
==
0
||
m_type
!=
Immutable
)
{
d
->
buf
[
i
]
=
[
rhiD
->
d
->
dev
newBufferWithLength
:
roundedSize
options
:
opts
];
d
->
pendingUpdates
[
i
].
reserve
(
16
);
if
(
!
objectName
.
isEmpty
())
d
->
buf
[
i
].
label
=
[
NSString
stringWithUTF8String
:
objectName
.
constData
()];
if
(
!
objectName
.
isEmpty
())
{
if
(
m_type
==
Immutable
)
{
d
->
buf
[
i
].
label
=
[
NSString
stringWithUTF8String
:
objectName
.
constData
()];
}
else
{
const
QByteArray
name
=
objectName
+
'/'
+
QByteArray
::
number
(
i
);
d
->
buf
[
i
].
label
=
[
NSString
stringWithUTF8String
:
name
.
constData
()];
}
}
}
}
...
...
@@ -1973,6 +2029,25 @@ bool QMetalShaderResourceBindings::build()
else
maxBinding
=
-
1
;
boundResourceData
.
resize
(
sortedBindings
.
count
());
for
(
int
i
=
0
,
ie
=
sortedBindings
.
count
();
i
!=
ie
;
++
i
)
{
const
QRhiShaderResourceBinding
&
b
(
sortedBindings
[
i
]);
QMetalShaderResourceBindings
::
BoundResourceData
&
bd
(
boundResourceData
[
i
]);
switch
(
b
.
type
)
{
case
QRhiShaderResourceBinding
::
UniformBuffer
:
bd
.
ubuf
.
generation
=
QRHI_RES
(
QMetalBuffer
,
b
.
ubuf
.
buf
)
->
generation
;
break
;
case
QRhiShaderResourceBinding
::
SampledTexture
:
bd
.
stex
.
texGeneration
=
QRHI_RES
(
QMetalTexture
,
b
.
stex
.
tex
)
->
generation
;
bd
.
stex
.
samplerGeneration
=
QRHI_RES
(
QMetalSampler
,
b
.
stex
.
sampler
)
->
generation
;
break
;
default:
Q_UNREACHABLE
();
break
;
}
}
generation
+=
1
;
return
true
;
}
...
...
@@ -2440,6 +2515,7 @@ void QMetalCommandBuffer::resetState()
currentPipelineGeneration
=
0
;
currentSrb
=
nullptr
;
currentSrbGeneration
=
0
;
currentResSlot
=
-
1
;
currentIndexBuffer
=
nullptr
;
d
->
currentPassEncoder
=
nil
;
d
->
currentPassRpDesc
=
nil
;
...
...
src/rhi/qrhimetal_p.h
View file @
cbb16855
...
...
@@ -178,6 +178,22 @@ struct QMetalShaderResourceBindings : public QRhiShaderResourceBindings
QVector
<
QRhiShaderResourceBinding
>
sortedBindings
;
int
maxBinding
=
-
1
;
struct
BoundUniformBufferData
{
uint
generation
;
};
struct
BoundSampledTextureData
{
uint
texGeneration
;
uint
samplerGeneration
;
};
struct
BoundResourceData
{
union
{
BoundUniformBufferData
ubuf
;
BoundSampledTextureData
stex
;
};
};
QVector
<
BoundResourceData
>
boundResourceData
;
uint
generation
=
0
;
friend
class
QRhiMetal
;
};
...
...
@@ -213,6 +229,7 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
uint
currentPipelineGeneration
;
QRhiShaderResourceBindings
*
currentSrb
;
uint
currentSrbGeneration
;
int
currentResSlot
;
QRhiBuffer
*
currentIndexBuffer
;
quint32
currentIndexOffset
;
QRhiCommandBuffer
::
IndexFormat
currentIndexFormat
;
...
...
@@ -334,6 +351,7 @@ public:
void
finishActiveReadbacks
(
bool
forced
=
false
);
void
enqueueResourceUpdates
(
QRhiCommandBuffer
*
cb
,
QRhiResourceUpdateBatch
*
resourceUpdates
);
void
executeBufferHostWritesForCurrentFrame
(
QMetalBuffer
*
bufD
);
void
enqueueShaderResourceBindings
(
QMetalShaderResourceBindings
*
srbD
,
QMetalCommandBuffer
*
cbD
);
int
effectiveSampleCount
(
int
sampleCount
)
const
;
bool
importedDevice
=
false
;
...
...
src/rhi/qrhivulkan.cpp
View file @
cbb16855
...
...
@@ -1903,12 +1903,14 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
break
;
case
QRhiShaderResourceBinding
::
SampledTexture
:
{
QVkTexture
*
texD
=
QRHI_RES
(
QVkTexture
,
b
.
stex
.
tex
);
QVkSampler
*
samplerD
=
QRHI_RES
(
QVkSampler
,
b
.
stex
.
sampler
);
writeInfo
.
descriptorType
=
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
;
bd
.
stex
.
texGeneration
=
QRHI_RES
(
QVkTexture
,
b
.
stex
.
tex
)
->
generation
;
bd
.
stex
.
samplerGeneration
=
QRHI_RES
(
QVkSampler
,
b
.
stex
.
sampler
)
->
generation
;
bd
.
stex
.
texGeneration
=
texD
->
generation
;
bd
.
stex
.
samplerGeneration
=
sampler
D
->
generation
;
VkDescriptorImageInfo
imageInfo
;
imageInfo
.
sampler
=
QRHI_RES
(
QVkSampler
,
b
.
stex
.
sampler
)
->
sampler
;
imageInfo
.
imageView
=
QRHI_RES
(
QVkTexture
,
b
.
stex
.
tex
)
->
imageView
;
imageInfo
.
sampler
=
sampler
D
->
sampler
;
imageInfo
.
imageView
=
texD
->
imageView
;
imageInfo
.
imageLayout
=
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
;
imageInfos
.
append
(
imageInfo
);
writeInfo
.
pImageInfo
=
&
imageInfos
.
last
();
...
...
@@ -2847,10 +2849,16 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
if
(
!
srb
)
srb
=
psD
->
m_shaderResourceBindings
;
// do host writes and mark referenced shader resources as in-use
QVkShaderResourceBindings
*
srbD
=
QRHI_RES
(
QVkShaderResourceBindings
,
srb
);
bool
hasSlottedResourceInSrb
=
false
;
for
(
const
QRhiShaderResourceBinding
&
b
:
qAsConst
(
srbD
->
m_bindings
))
{
const
int
descSetIdx
=
hasSlottedResourceInSrb
?
currentFrameSlot
:
0
;
bool
rewriteDescSet
=
false
;
// Do host writes and mark referenced shader resources as in-use.
// Also prepare to ensure the descriptor set we are going to bind refers to up-to-date Vk objects.
for
(
int
i
=
0
,
ie
=
srbD
->
m_bindings
.
count
();
i
!=
ie
;
++
i
)
{
const
QRhiShaderResourceBinding
&
b
(
srbD
->
m_bindings
[
i
]);
QVkShaderResourceBindings
::
BoundResourceData
&
bd
(
srbD
->
boundResourceData
[
descSetIdx
][
i
]);
switch
(
b
.
type
)
{
case
QRhiShaderResourceBinding
::
UniformBuffer
:
{
...
...
@@ -2861,46 +2869,35 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
hasSlottedResourceInSrb
=
true
;
executeBufferHostWritesForCurrentFrame
(
bufD
);
}
}
break
;
case
QRhiShaderResourceBinding
::
SampledTexture
:
QRHI_RES
(
QVkTexture
,
b
.
stex
.
tex
)
->
lastActiveFrameSlot
=
currentFrameSlot
;
QRHI_RES
(
QVkSampler
,
b
.
stex
.
sampler
)
->
lastActiveFrameSlot
=
currentFrameSlot
;
break
;
default:
Q_UNREACHABLE
();
break
;
}
}
// ensure the descriptor set we are going to bind refers to up-to-date Vk objects
const
int
descSetIdx
=
hasSlottedResourceInSrb
?
currentFrameSlot
:
0
;
bool
srbUpdate
=
false
;
for
(
int
i
=
0
,
ie
=
srbD
->
m_bindings
.
count
();
i
!=
ie
;
++
i
)
{
const
QRhiShaderResourceBinding
&
b
(
srbD
->
m_bindings
[
i
]);
QVkShaderResourceBindings
::
BoundResourceData
&
bd
(
srbD
->
boundResourceData
[
descSetIdx
][
i
]);
switch
(
b
.
type
)
{
case
QRhiShaderResourceBinding
::
UniformBuffer
:
if
(
QRHI_RES
(
QVkBuffer
,
b
.
ubuf
.
buf
)
->
generation
!=
bd
.
ubuf
.
generation
)
{
srbUpdate
=
true
;
bd
.
ubuf
.
generation
=
QRHI_RES
(
QVkBuffer
,
b
.
ubuf
.
buf
)
->
generation
;
if
(
bufD
->
generation
!=
bd
.
ubuf
.
generation
)
{
rewriteDescSet
=
true
;
bd
.
ubuf
.
generation
=
bufD
->
generation
;
}
}
break
;
case
QRhiShaderResourceBinding
::
SampledTexture
:
if
(
QRHI_RES
(
QVkTexture
,
b
.
stex
.
tex
)
->
generation
!=
bd
.
stex
.
texGeneration
||
QRHI_RES
(
QVkSampler
,
b
.
stex
.
sampler
)
->
generation
!=
bd
.
stex
.
samplerGeneration
)
{
QVkTexture
*
texD
=
QRHI_RES
(
QVkTexture
,
b
.
stex
.
tex
);
QVkSampler
*
samplerD
=
QRHI_RES
(
QVkSampler
,
b
.
stex
.
sampler
);
texD
->
lastActiveFrameSlot
=
currentFrameSlot
;
samplerD
->
lastActiveFrameSlot
=
currentFrameSlot
;
if
(
texD
->
generation
!=
bd
.
stex
.
texGeneration
||
samplerD
->
generation
!=
bd
.
stex
.
samplerGeneration
)
{
srbUpdate
=
true
;
bd
.
stex
.
texGeneration
=
QRHI_RES
(
QVkTexture
,
b
.
stex
.
tex
)
->
generation
;
bd
.
stex
.
samplerGeneration
=
QRHI_RES
(
QVkSampler
,
b
.
stex
.
sampler
)
->
generation
;
rewriteDescSet
=
true
;
bd
.
stex
.
texGeneration
=
texD
->
generation
;
bd
.
stex
.
samplerGeneration
=
sampler
D
->
generation
;
}
}
break
;
default:
Q_UNREACHABLE
();
break
;
}
}
if
(
srbUpdate
)
// write descriptor sets, if needed
if
(
rewriteDescSet
)
updateShaderResourceBindings
(
srb
,
descSetIdx
);
QVkCommandBuffer
*
cbD
=
QRHI_RES
(
QVkCommandBuffer
,
cb
);
...
...
@@ -2912,10 +2909,9 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
psD
->
lastActiveFrameSlot
=
currentFrameSlot
;
// make sure the descriptors for the correct slot will get bound
if
(
hasSlottedResourceInSrb
&&
cbD
->
currentDescSetSlot
!=
descSetIdx
)
srbUpdate
=
true
;
const
bool
forceRebind
=
hasSlottedResourceInSrb
&&
cbD
->
currentDescSetSlot
!=
descSetIdx
;
if
(
srbUpdate
||
cbD
->
currentSrb
!=
srb
||
cbD
->
currentSrbGeneration
!=
srbD
->
generation
)
{
if
(
forceRebind
||
rewriteDescSet
||
cbD
->
currentSrb
!=
srb
||
cbD
->
currentSrbGeneration
!=
srbD
->
generation
)
{
df
->
vkCmdBindDescriptorSets
(
cbD
->
cb
,
VK_PIPELINE_BIND_POINT_GRAPHICS
,
psD
->
layout
,
0
,
1
,
&
srbD
->
descSets
[
descSetIdx
],
0
,
nullptr
);
cbD
->
currentSrb
=
srb
;
...
...
@@ -3070,7 +3066,7 @@ void QRhiVulkan::debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg)
vkCmdDebugMarkerInsert
(
QRHI_RES
(
QVkCommandBuffer
,
cb
)
->
cb
,
&
marker
);
}
void
QRhiVulkan
::
setObjectName
(
uint64_t
object
,
VkDebugReportObjectTypeEXT
type
,
const
QByteArray
&
name
)
void
QRhiVulkan
::
setObjectName
(
uint64_t
object
,
VkDebugReportObjectTypeEXT
type
,
const
QByteArray
&
name
,
int
slot
)
{
if
(
!
debugMarkers
||
!
debugMarkersAvailable
||
name
.
isEmpty
())
return
;
...
...
@@ -3080,7 +3076,12 @@ void QRhiVulkan::setObjectName(uint64_t object, VkDebugReportObjectTypeEXT type,
nameInfo
.
sType
=
VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT
;
nameInfo
.
objectType
=
type
;
nameInfo
.
object
=
object
;
nameInfo
.
pObjectName
=
name
.
constData
();
QByteArray
decoratedName
=
name
;
if
(
slot
>=
0
)
{
decoratedName
+=
'/'
;
decoratedName
+=
QByteArray
::
number
(
slot
);
}
nameInfo
.
pObjectName
=
decoratedName
.
constData
();
vkDebugMarkerSetObjectName
(
dev
,
&
nameInfo
);
}
...
...
@@ -3476,7 +3477,8 @@ bool QVkBuffer::build()
if
(
m_type
==
Dynamic
)
pendingDynamicUpdates
[
i
].
reserve
(
16
);
rhiD
->
setObjectName
(
reinterpret_cast
<
uint64_t
>
(
buffers
[
i
]),
VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT
,
objectName
);
rhiD
->
setObjectName
(
reinterpret_cast
<
uint64_t
>
(
buffers
[
i
]),
VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT
,
objectName
,
m_type
==
Dynamic
?
i
:
-
1
);
}
}
...
...
src/rhi/qrhivulkan_p.h
View file @
cbb16855
...
...
@@ -453,7 +453,7 @@ public:
void
executeDeferredReleases
(
bool
forced
=
false
);
void
finishActiveReadbacks
(
bool
forced
=
false
);
void
setObjectName
(
uint64_t
object
,
VkDebugReportObjectTypeEXT
type
,
const
QByteArray
&
name
);
void
setObjectName
(
uint64_t
object
,
VkDebugReportObjectTypeEXT
type
,
const
QByteArray
&
name
,
int
slot
=
-
1
);
void
bufferBarrier
(
QRhiCommandBuffer
*
cb
,
QRhiBuffer
*
buf
);
void
imageSubResBarrier
(
QRhiCommandBuffer
*
cb
,
QRhiTexture
*
tex
,
VkImageLayout
oldLayout
,
VkImageLayout
newLayout
,
...
...
todo.txt
View file @
cbb16855
multiwindow_threaded should demo pulling out the device and importing to another rhi
mtl: reduce set*
advanced blend modes
gl: tex formats (texture, readback)
gl: srgb
...
...
@@ -47,6 +46,7 @@ dxc for d3d as an alternative to fxc?
hlsl -> dxc -> spirv -> spirv-cross hmmm...
+++ done
mtl: reduce set*
mtl: report readback temp buf
vk: support instanceStepRate via VK_EXT_vertex_attribute_divisor
resize to 0 width or height fails (vk, d3d)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment