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
ab819490
Commit
ab819490
authored
Jan 19, 2019
by
Laszlo Agocs
Browse files
Drop public data members and inner structs in Tex.UploadDesc.
parent
b04ccdb2
Changes
11
Hide whitespace changes
Inline
Side-by-side
examples/rhi/compressedtexture_bc1/compressedtexture_bc1.cpp
View file @
ab819490
...
...
@@ -177,13 +177,13 @@ void Window::customRender()
u
->
updateDynamicBuffer
(
d
.
ubuf
,
64
,
4
,
&
flip
);
}
if
(
!
d
.
compressedData
.
isEmpty
())
{
QRhiTextureUploadDescription
desc
;
QRhiTextureUploadDescription
::
Layer
layer
;
QVector
<
QRhiTextureMipLevel
>
mipImages
;
for
(
int
i
=
0
;
i
<
d
.
compressedData
.
count
();
++
i
)
{
QRhiTexture
UploadDescription
::
Layer
::
MipLevel
image
(
d
.
compressedData
[
i
]);
layer
.
mipImages
.
append
(
image
);
QRhiTextureMipLevel
image
(
d
.
compressedData
[
i
]);
mipImages
.
append
(
image
);
}
desc
.
layers
.
append
(
layer
);
QRhiTextureLayer
layer
(
mipImages
);
QRhiTextureUploadDescription
desc
({
layer
});
u
->
uploadTexture
(
d
.
tex
,
desc
);
d
.
compressedData
.
clear
();
}
...
...
examples/rhi/compressedtexture_bc1_subupload/compressedtexture_bc1_subupload.cpp
View file @
ab819490
...
...
@@ -182,27 +182,23 @@ void Window::customRender()
}
if
(
!
d
.
compressedData
.
isEmpty
())
{
{
QRhiTextureUploadDescription
desc
;
QRhiTextureUploadDescription
::
Layer
layer
;
QRhiTextureUploadDescription
::
Layer
::
MipLevel
image
(
d
.
compressedData
[
0
]);
layer
.
mipImages
.
append
(
image
);
desc
.
layers
.
append
(
layer
);
QRhiTextureMipLevel
image
(
d
.
compressedData
[
0
]);
QRhiTextureLayer
layer
({
image
});
QRhiTextureUploadDescription
desc
({
layer
});
u
->
uploadTexture
(
d
.
tex
,
desc
);
d
.
compressedData
.
clear
();
}
// now exercise uploading a smaller compressed image into the same texture
{
QRhiTextureUploadDescription
desc
;
QRhiTextureUploadDescription
::
Layer
layer
;
QRhiTextureUploadDescription
::
Layer
::
MipLevel
image
(
d
.
compressedData2
[
0
]);
QRhiTextureMipLevel
image
(
d
.
compressedData2
[
0
]);
// positions and sizes must be multiples of 4 here (for BC1)
image
.
d
estinationTopLeft
=
QPoint
(
16
,
32
);
image
.
setD
estinationTopLeft
(
QPoint
(
16
,
32
)
)
;
// the image is smaller than the subresource size (224x64 vs
// 256x256) so the size must be specified manually
image
.
sourceSize
=
QSize
(
224
,
64
);
layer
.
mipImages
.
append
(
image
);
desc
.
layers
.
append
(
layer
);
image
.
s
etS
ourceSize
(
QSize
(
224
,
64
)
)
;
QRhiTextureLayer
layer
({
image
}
);
QRhiTextureUploadDescription
desc
({
layer
}
);
u
->
uploadTexture
(
d
.
tex
,
desc
);
d
.
compressedData2
.
clear
();
}
...
...
examples/rhi/cubemap/cubemap.cpp
View file @
ab819490
...
...
@@ -82,14 +82,15 @@ void Window::customInit()
QRhiTextureUploadDescription
desc
;
QImage
img
=
QImage
(
":/c.png"
).
mirrored
().
convertToFormat
(
QImage
::
Format_RGBA8888
);
// just use the same image for all faces for now
auto
texLayer
=
QRhiTextureUploadDescription
::
Layer
({
QRhiTextureUploadDescription
::
Layer
::
MipLevel
(
img
)
});
desc
.
layers
<<
texLayer
// +X
<<
texLayer
// -X
<<
texLayer
// +Y
<<
texLayer
// -Y
<<
texLayer
// +Z
<<
texLayer
;
// -Z
QRhiTextureLayer
texLayer
({
{
img
}
});
desc
.
setLayers
({
texLayer
,
// +X
texLayer
,
// -X
texLayer
,
// +Y
texLayer
,
// -Y
texLayer
,
// +Z
texLayer
// -Z
});
d
.
initialUpdates
->
uploadTexture
(
d
.
tex
,
desc
);
d
.
sampler
=
m_r
->
newSampler
(
QRhiSampler
::
Linear
,
QRhiSampler
::
Linear
,
QRhiSampler
::
None
,
...
...
examples/rhi/texuploads/texuploads.cpp
View file @
ab819490
...
...
@@ -184,17 +184,12 @@ void Window::customRender()
// Partially change the texture.
if
(
d
.
testStage
==
1
)
{
QRhiTextureUploadDescription
desc
;
QRhiTextureUploadDescription
::
Layer
layer
;
QRhiTextureUploadDescription
::
Layer
::
MipLevel
mipDesc
;
mipDesc
.
image
=
d
.
customImage
;
QRhiTextureMipLevel
mipDesc
(
d
.
customImage
);
// The image here is smaller than the original. Use a non-zero position
// to make it more interesting.
mipDesc
.
destinationTopLeft
=
QPoint
(
100
,
20
);
layer
.
mipImages
.
append
(
mipDesc
);
desc
.
layers
.
append
(
layer
);
mipDesc
.
setDestinationTopLeft
(
QPoint
(
100
,
20
));
QRhiTextureLayer
layer
({
mipDesc
});
QRhiTextureUploadDescription
desc
({
layer
});
u
->
uploadTexture
(
d
.
tex
,
desc
);
}
...
...
@@ -235,17 +230,12 @@ void Window::customRender()
// Now again upload customImage but this time only a part of it.
if
(
d
.
testStage
==
5
)
{
QRhiTextureUploadDescription
desc
;
QRhiTextureUploadDescription
::
Layer
layer
;
QRhiTextureUploadDescription
::
Layer
::
MipLevel
mipDesc
;
mipDesc
.
image
=
d
.
customImage
;
mipDesc
.
destinationTopLeft
=
QPoint
(
10
,
120
);
mipDesc
.
sourceSize
=
QSize
(
50
,
40
);
mipDesc
.
sourceTopLeft
=
QPoint
(
20
,
10
);
layer
.
mipImages
.
append
(
mipDesc
);
desc
.
layers
.
append
(
layer
);
QRhiTextureMipLevel
mipDesc
(
d
.
customImage
);
mipDesc
.
setDestinationTopLeft
(
QPoint
(
10
,
120
));
mipDesc
.
setSourceSize
(
QSize
(
50
,
40
));
mipDesc
.
setSourceTopLeft
(
QPoint
(
20
,
10
));
QRhiTextureLayer
layer
({
mipDesc
});
QRhiTextureUploadDescription
desc
({
layer
});
u
->
uploadTexture
(
d
.
newTex
,
desc
);
}
...
...
examples/rhi/triquadcube/texturedcuberenderer.cpp
View file @
ab819490
...
...
@@ -193,17 +193,19 @@ void TexturedCubeRenderer::queueResourceUpdates(QRhiResourceUpdateBatch *resourc
if
(
!
m_image
.
isNull
())
{
if
(
MIPMAP
)
{
QRhiTextureUploadDescription
desc
;
desc
.
layers
.
append
(
QRhiTextureUploadDescription
::
Layer
());
QRhiTextureLayer
layer
;
if
(
!
AUTOGENMIPMAP
)
{
// the ghetto mipmap generator...
QVector
<
QRhiTextureMipLevel
>
mipImages
;
for
(
int
i
=
0
,
ie
=
m_r
->
mipLevelsForSize
(
m_image
.
size
());
i
!=
ie
;
++
i
)
{
QImage
image
=
m_image
.
scaled
(
m_r
->
sizeForMipLevel
(
i
,
m_image
.
size
()));
desc
.
layers
[
0
].
mipImages
.
push_back
({
image
});
mipImages
.
append
({
image
});
}
layer
.
setMipImages
(
mipImages
);
}
else
{
desc
.
layers
[
0
].
mipImages
.
push_back
(
{
m_image
});
layer
.
setMipImages
({
{
m_image
}
});
}
QRhiTextureUploadDescription
desc
({
layer
});
resourceUpdates
->
uploadTexture
(
m_tex
,
desc
);
if
(
AUTOGENMIPMAP
)
resourceUpdates
->
generateMips
(
m_tex
);
...
...
src/rhi/qrhi.cpp
View file @
ab819490
...
...
@@ -634,13 +634,13 @@ QT_BEGIN_NAMESPACE
*/
/*!
\class QRhiTexture
UploadDescription::
Layer
\class QRhiTextureLayer
\inmodule QtRhi
\brief Describes one layer (face for cubemaps) in a texture upload operation.
*/
/*!
\class QRhiTexture
UploadDescription::Layer::
MipLevel
\class QRhiTextureMipLevel
\inmodule QtRhi
\brief Describes one mip level in a layer in a texture upload operation.
...
...
@@ -648,23 +648,23 @@ QT_BEGIN_NAMESPACE
former is only allowed for uncompressed textures, while the latter is only
supported for compressed ones.
\note
\l
image and
\l
compressedData cannot be both set.
\note image
()
and compressedData
()
cannot be both set
at the same time
.
\l
destinationTopLeft specifies the top-left corner of the target
destinationTopLeft
()
specifies the top-left corner of the target
rectangle. Defaults to (0, 0).
An empty
\l
sourceSize (the default) indicates that size is assumed to be
An empty sourceSize
()
(the default) indicates that size is assumed to be
the size of the subresource. For uncompressed textures this implies that
the size of the source
\l
image must match the subresource. For compressed
textures sufficient amount of data must be provided in
\l
compressedData.
the size of the source image
()
must match the subresource. For compressed
textures sufficient amount of data must be provided in compressedData
()
.
\note With compressed textures the first upload must always match the
subresource size due to graphics API limitations with some backends.
\l
sourceTopLeft is is only supported for uncompressed textures, and
sourceTopLeft
()
is is only supported for uncompressed textures, and
specifies the top-left corner of the source rectangle.
\note Setting
\l
sourceSize or
\l
sourceTopLeft may trigger a QImage copy
\note Setting sourceSize
()
or sourceTopLeft
()
may trigger a QImage copy
internally, depending on the format and the backend.
*/
...
...
src/rhi/qrhi.h
View file @
ab819490
...
...
@@ -365,34 +365,66 @@ private:
Q_DECLARE_TYPEINFO
(
QRhiTextureRenderTargetDescription
,
Q_MOVABLE_TYPE
);
struct
Q_RHI_EXPORT
QRhiTexture
UploadDescription
class
Q_RHI_EXPORT
QRhiTexture
MipLevel
{
struct
Q_RHI_EXPORT
Layer
{
struct
Q_RHI_EXPORT
MipLevel
{
MipLevel
()
{
}
MipLevel
(
const
QImage
&
image_
)
:
image
(
image_
)
{
}
MipLevel
(
const
QByteArray
&
compressedData_
)
:
compressedData
(
compressedData_
)
{
}
QImage
image
;
QByteArray
compressedData
;
QPoint
destinationTopLeft
;
QSize
sourceSize
;
QPoint
sourceTopLeft
;
};
Layer
()
{
}
Layer
(
const
QVector
<
MipLevel
>
&
mipImages_
)
:
mipImages
(
mipImages_
)
{
}
QVector
<
MipLevel
>
mipImages
;
};
public:
QRhiTextureMipLevel
()
{
}
QRhiTextureMipLevel
(
const
QImage
&
image
)
:
m_image
(
image
)
{
}
QRhiTextureMipLevel
(
const
QByteArray
&
compressedData
)
:
m_compressedData
(
compressedData
)
{
}
QImage
image
()
const
{
return
m_image
;
}
void
setImage
(
const
QImage
&
image
)
{
m_image
=
image
;
}
QByteArray
compressedData
()
const
{
return
m_compressedData
;
}
void
setCompressedData
(
const
QByteArray
&
data
)
{
m_compressedData
=
data
;
}
QPoint
destinationTopLeft
()
const
{
return
m_destinationTopLeft
;
}
void
setDestinationTopLeft
(
const
QPoint
&
p
)
{
m_destinationTopLeft
=
p
;
}
QSize
sourceSize
()
const
{
return
m_sourceSize
;
}
void
setSourceSize
(
const
QSize
&
size
)
{
m_sourceSize
=
size
;
}
QPoint
sourceTopLeft
()
const
{
return
m_sourceTopLeft
;
}
void
setSourceTopLeft
(
const
QPoint
&
p
)
{
m_sourceTopLeft
=
p
;
}
private:
QImage
m_image
;
QByteArray
m_compressedData
;
QPoint
m_destinationTopLeft
;
QSize
m_sourceSize
;
QPoint
m_sourceTopLeft
;
};
Q_DECLARE_TYPEINFO
(
QRhiTextureMipLevel
,
Q_MOVABLE_TYPE
);
class
Q_RHI_EXPORT
QRhiTextureLayer
{
public:
QRhiTextureLayer
()
{
}
QRhiTextureLayer
(
const
QVector
<
QRhiTextureMipLevel
>
&
mipImages
)
:
m_mipImages
(
mipImages
)
{
}
QVector
<
QRhiTextureMipLevel
>
mipImages
()
const
{
return
m_mipImages
;
}
void
setMipImages
(
const
QVector
<
QRhiTextureMipLevel
>
&
images
)
{
m_mipImages
=
images
;
}
private:
QVector
<
QRhiTextureMipLevel
>
m_mipImages
;
};
Q_DECLARE_TYPEINFO
(
QRhiTextureLayer
,
Q_MOVABLE_TYPE
);
class
Q_RHI_EXPORT
QRhiTextureUploadDescription
{
public:
QRhiTextureUploadDescription
()
{
}
QRhiTextureUploadDescription
(
const
QVector
<
Layer
>
&
layers_
)
:
layers
(
layers_
)
{
}
QVector
<
Layer
>
layers
;
QRhiTextureUploadDescription
(
const
QVector
<
QRhiTextureLayer
>
&
layers
)
:
m_layers
(
layers
)
{
}
QVector
<
QRhiTextureLayer
>
layers
()
const
{
return
m_layers
;
}
void
setLayers
(
const
QVector
<
QRhiTextureLayer
>
&
layers
)
{
m_layers
=
layers
;
}
private:
QVector
<
QRhiTextureLayer
>
m_layers
;
};
Q_DECLARE_TYPEINFO
(
QRhiTextureUploadDescription
::
Layer
::
MipLevel
,
Q_MOVABLE_TYPE
);
Q_DECLARE_TYPEINFO
(
QRhiTextureUploadDescription
::
Layer
,
Q_MOVABLE_TYPE
);
Q_DECLARE_TYPEINFO
(
QRhiTextureUploadDescription
,
Q_MOVABLE_TYPE
);
struct
Q_RHI_EXPORT
QRhiTextureCopyDescription
...
...
src/rhi/qrhid3d11.cpp
View file @
ab819490
...
...
@@ -932,13 +932,14 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
for
(
const
QRhiResourceUpdateBatchPrivate
::
TextureUpload
&
u
:
ud
->
textureUploads
)
{
QD3D11Texture
*
texD
=
QRHI_RES
(
QD3D11Texture
,
u
.
tex
);
for
(
int
layer
=
0
,
layerCount
=
u
.
desc
.
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureUploadDescription
::
Layer
&
layerDesc
(
u
.
desc
.
layers
[
layer
]);
for
(
int
level
=
0
,
levelCount
=
layerDesc
.
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureUploadDescription
::
Layer
::
MipLevel
mipDesc
(
layerDesc
.
mipImages
[
level
]);
const
QVector
<
QRhiTextureLayer
>
layers
=
u
.
desc
.
layers
();
for
(
int
layer
=
0
,
layerCount
=
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureLayer
&
layerDesc
(
layers
[
layer
]);
const
QVector
<
QRhiTextureMipLevel
>
mipImages
=
layerDesc
.
mipImages
();
for
(
int
level
=
0
,
levelCount
=
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureMipLevel
&
mipDesc
(
mipImages
[
level
]);
UINT
subres
=
D3D11CalcSubresource
(
level
,
layer
,
texD
->
mipLevelCount
);
const
int
dx
=
mipDesc
.
destinationTopLeft
.
x
();
const
int
dy
=
mipDesc
.
destinationTopLeft
.
y
();
const
QPoint
dp
=
mipDesc
.
destinationTopLeft
();
D3D11_BOX
box
;
box
.
front
=
0
;
// back, right, bottom are exclusive
...
...
@@ -948,58 +949,53 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd
.
args
.
updateSubRes
.
dst
=
texD
->
tex
;
cmd
.
args
.
updateSubRes
.
dstSubRes
=
subres
;
if
(
!
mipDesc
.
image
.
isNull
())
{
QImage
img
=
mipDesc
.
image
;
int
w
=
img
.
width
();
int
h
=
img
.
height
();
if
(
!
mipDesc
.
image
().
isNull
())
{
QImage
img
=
mipDesc
.
image
();
QSize
size
=
img
.
size
();
int
bpl
=
img
.
bytesPerLine
();
if
(
!
mipDesc
.
sourceSize
.
isEmpty
()
||
!
mipDesc
.
sourceTopLeft
.
isNull
())
{
const
int
sx
=
mipDesc
.
sourceTopLeft
.
x
();
const
int
sy
=
mipDesc
.
sourceTopLeft
.
y
();
if
(
!
mipDesc
.
sourceSize
.
isEmpty
())
{
w
=
mipDesc
.
sourceSize
.
width
();
h
=
mipDesc
.
sourceSize
.
height
();
}
if
(
!
mipDesc
.
sourceSize
().
isEmpty
()
||
!
mipDesc
.
sourceTopLeft
().
isNull
())
{
const
QPoint
sp
=
mipDesc
.
sourceTopLeft
();
if
(
!
mipDesc
.
sourceSize
().
isEmpty
())
size
=
mipDesc
.
sourceSize
();
if
(
img
.
depth
()
==
32
)
{
const
int
offset
=
s
y
*
img
.
bytesPerLine
()
+
s
x
*
4
;
const
int
offset
=
s
p
.
y
()
*
img
.
bytesPerLine
()
+
s
p
.
x
()
*
4
;
cmd
.
args
.
updateSubRes
.
src
=
cbD
->
retainImage
(
img
)
+
offset
;
}
else
{
img
=
img
.
copy
(
s
x
,
sy
,
w
,
h
);
img
=
img
.
copy
(
s
p
.
x
(),
sp
.
y
(),
size
.
width
(),
size
.
height
()
);
bpl
=
img
.
bytesPerLine
();
cmd
.
args
.
updateSubRes
.
src
=
cbD
->
retainImage
(
img
);
}
}
else
{
cmd
.
args
.
updateSubRes
.
src
=
cbD
->
retainImage
(
img
);
}
box
.
left
=
d
x
;
box
.
top
=
d
y
;
box
.
right
=
d
x
+
w
;
box
.
bottom
=
d
y
+
h
;
box
.
left
=
d
p
.
x
()
;
box
.
top
=
d
p
.
y
()
;
box
.
right
=
d
p
.
x
()
+
size
.
width
()
;
box
.
bottom
=
d
p
.
y
()
+
size
.
height
()
;
cmd
.
args
.
updateSubRes
.
hasDstBox
=
true
;
cmd
.
args
.
updateSubRes
.
dstBox
=
box
;
cmd
.
args
.
updateSubRes
.
srcRowPitch
=
bpl
;
}
else
if
(
!
mipDesc
.
compressedData
.
isEmpty
()
&&
isCompressedFormat
(
texD
->
m_format
))
{
int
w
,
h
;
if
(
mipDesc
.
sourceSize
.
isEmpty
())
{
w
=
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
width
()
>>
level
)));
h
=
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
height
()
>>
level
)));
}
else
if
(
!
mipDesc
.
compressedData
()
.
isEmpty
()
&&
isCompressedFormat
(
texD
->
m_format
))
{
QSize
size
;
if
(
mipDesc
.
sourceSize
()
.
isEmpty
())
{
size
.
setWidth
(
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
width
()
>>
level
)))
)
;
size
.
setHeight
(
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
height
()
>>
level
)))
)
;
}
else
{
w
=
mipDesc
.
sourceSize
.
width
();
h
=
mipDesc
.
sourceSize
.
height
();
size
=
mipDesc
.
sourceSize
();
}
quint32
bpl
=
0
;
QSize
blockDim
;
compressedFormatInfo
(
texD
->
m_format
,
QS
ize
(
w
,
h
)
,
&
bpl
,
nullptr
,
&
blockDim
);
compressedFormatInfo
(
texD
->
m_format
,
s
ize
,
&
bpl
,
nullptr
,
&
blockDim
);
// Everything must be a multiple of the block width and
// height, so e.g. a mip level of size 2x2 will be 4x4 when it
// comes to the actual data.
box
.
left
=
aligned
(
d
x
,
blockDim
.
width
());
box
.
top
=
aligned
(
d
y
,
blockDim
.
height
());
box
.
right
=
aligned
(
d
x
+
w
,
blockDim
.
width
());
box
.
bottom
=
aligned
(
d
y
+
h
,
blockDim
.
height
());
box
.
left
=
aligned
(
d
p
.
x
()
,
blockDim
.
width
());
box
.
top
=
aligned
(
d
p
.
y
()
,
blockDim
.
height
());
box
.
right
=
aligned
(
d
p
.
x
()
+
size
.
width
()
,
blockDim
.
width
());
box
.
bottom
=
aligned
(
d
p
.
y
()
+
size
.
height
()
,
blockDim
.
height
());
cmd
.
args
.
updateSubRes
.
hasDstBox
=
true
;
cmd
.
args
.
updateSubRes
.
dstBox
=
box
;
cmd
.
args
.
updateSubRes
.
src
=
cbD
->
retainData
(
mipDesc
.
compressedData
);
cmd
.
args
.
updateSubRes
.
src
=
cbD
->
retainData
(
mipDesc
.
compressedData
()
);
cmd
.
args
.
updateSubRes
.
srcRowPitch
=
bpl
;
}
cbD
->
commands
.
append
(
cmd
);
...
...
src/rhi/qrhigles2.cpp
View file @
ab819490
...
...
@@ -708,20 +708,21 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
const
bool
isCompressed
=
isCompressedFormat
(
texD
->
m_format
);
const
bool
isCubeMap
=
texD
->
m_flags
.
testFlag
(
QRhiTexture
::
CubeMap
);
const
GLenum
faceTargetBase
=
isCubeMap
?
GL_TEXTURE_CUBE_MAP_POSITIVE_X
:
texD
->
target
;
for
(
int
layer
=
0
,
layerCount
=
u
.
desc
.
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureUploadDescription
::
Layer
&
layerDesc
(
u
.
desc
.
layers
[
layer
]);
for
(
int
level
=
0
,
levelCount
=
layerDesc
.
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureUploadDescription
::
Layer
::
MipLevel
mipDesc
(
layerDesc
.
mipImages
[
level
]);
const
int
dx
=
mipDesc
.
destinationTopLeft
.
x
();
const
int
dy
=
mipDesc
.
destinationTopLeft
.
y
();
if
(
isCompressed
&&
!
mipDesc
.
compressedData
.
isEmpty
())
{
int
w
,
h
;
if
(
mipDesc
.
sourceSize
.
isEmpty
())
{
w
=
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
width
()
>>
level
)));
h
=
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
height
()
>>
level
)));
const
QVector
<
QRhiTextureLayer
>
layers
=
u
.
desc
.
layers
();
for
(
int
layer
=
0
,
layerCount
=
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureLayer
&
layerDesc
(
layers
[
layer
]);
const
QVector
<
QRhiTextureMipLevel
>
mipImages
=
layerDesc
.
mipImages
();
for
(
int
level
=
0
,
levelCount
=
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureMipLevel
&
mipDesc
(
mipImages
[
level
]);
const
QPoint
dp
=
mipDesc
.
destinationTopLeft
();
const
QByteArray
compressedData
=
mipDesc
.
compressedData
();
if
(
isCompressed
&&
!
compressedData
.
isEmpty
())
{
QSize
size
;
if
(
mipDesc
.
sourceSize
().
isEmpty
())
{
size
.
setWidth
(
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
width
()
>>
level
))));
size
.
setHeight
(
qFloor
(
float
(
qMax
(
1
,
texD
->
m_pixelSize
.
height
()
>>
level
))));
}
else
{
w
=
mipDesc
.
sourceSize
.
width
();
h
=
mipDesc
.
sourceSize
.
height
();
size
=
mipDesc
.
sourceSize
();
}
if
(
texD
->
specified
)
{
QGles2CommandBuffer
::
Command
cmd
;
...
...
@@ -729,13 +730,13 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd
.
args
.
compressedSubImage
.
dst
=
texD
;
cmd
.
args
.
compressedSubImage
.
faceTarget
=
faceTargetBase
+
layer
;
cmd
.
args
.
compressedSubImage
.
level
=
level
;
cmd
.
args
.
compressedSubImage
.
dx
=
d
x
;
cmd
.
args
.
compressedSubImage
.
dy
=
d
y
;
cmd
.
args
.
compressedSubImage
.
w
=
w
;
cmd
.
args
.
compressedSubImage
.
h
=
h
;
cmd
.
args
.
compressedSubImage
.
dx
=
d
p
.
x
()
;
cmd
.
args
.
compressedSubImage
.
dy
=
d
p
.
y
()
;
cmd
.
args
.
compressedSubImage
.
w
=
size
.
width
()
;
cmd
.
args
.
compressedSubImage
.
h
=
size
.
height
()
;
cmd
.
args
.
compressedSubImage
.
glintformat
=
texD
->
glintformat
;
cmd
.
args
.
compressedSubImage
.
size
=
mipDesc
.
compressedData
.
size
();
cmd
.
args
.
compressedSubImage
.
data
=
cbD
->
retainData
(
mipDesc
.
compressedData
);
cmd
.
args
.
compressedSubImage
.
size
=
compressedData
.
size
();
cmd
.
args
.
compressedSubImage
.
data
=
cbD
->
retainData
(
compressedData
);
cbD
->
commands
.
append
(
cmd
);
}
else
{
QGles2CommandBuffer
::
Command
cmd
;
...
...
@@ -744,34 +745,30 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd
.
args
.
compressedImage
.
faceTarget
=
faceTargetBase
+
layer
;
cmd
.
args
.
compressedImage
.
level
=
level
;
cmd
.
args
.
compressedImage
.
glintformat
=
texD
->
glintformat
;
cmd
.
args
.
compressedImage
.
w
=
w
;
cmd
.
args
.
compressedImage
.
h
=
h
;
cmd
.
args
.
compressedImage
.
size
=
mipDesc
.
compressedData
.
size
();
cmd
.
args
.
compressedImage
.
data
=
cbD
->
retainData
(
mipDesc
.
compressedData
);
cmd
.
args
.
compressedImage
.
w
=
size
.
width
()
;
cmd
.
args
.
compressedImage
.
h
=
size
.
height
()
;
cmd
.
args
.
compressedImage
.
size
=
compressedData
.
size
();
cmd
.
args
.
compressedImage
.
data
=
cbD
->
retainData
(
compressedData
);
cbD
->
commands
.
append
(
cmd
);
}
}
else
{
QImage
img
=
mipDesc
.
image
;
int
w
=
img
.
width
();
int
h
=
img
.
height
();
QImage
img
=
mipDesc
.
image
();
QSize
size
=
img
.
size
();
QGles2CommandBuffer
::
Command
cmd
;
cmd
.
cmd
=
QGles2CommandBuffer
::
Command
::
SubImage
;
if
(
!
mipDesc
.
sourceSize
.
isEmpty
()
||
!
mipDesc
.
sourceTopLeft
.
isNull
())
{
const
int
sx
=
mipDesc
.
sourceTopLeft
.
x
();
const
int
sy
=
mipDesc
.
sourceTopLeft
.
y
();
if
(
!
mipDesc
.
sourceSize
.
isEmpty
())
{
w
=
mipDesc
.
sourceSize
.
width
();
h
=
mipDesc
.
sourceSize
.
height
();
}
img
=
img
.
copy
(
sx
,
sy
,
w
,
h
);
if
(
!
mipDesc
.
sourceSize
().
isEmpty
()
||
!
mipDesc
.
sourceTopLeft
().
isNull
())
{
const
QPoint
sp
=
mipDesc
.
sourceTopLeft
();
if
(
!
mipDesc
.
sourceSize
().
isEmpty
())
size
=
mipDesc
.
sourceSize
();
img
=
img
.
copy
(
sp
.
x
(),
sp
.
y
(),
size
.
width
(),
size
.
height
());
}
cmd
.
args
.
subImage
.
dst
=
texD
;
cmd
.
args
.
subImage
.
faceTarget
=
faceTargetBase
+
layer
;
cmd
.
args
.
subImage
.
level
=
level
;
cmd
.
args
.
subImage
.
dx
=
d
x
;
cmd
.
args
.
subImage
.
dy
=
d
y
;
cmd
.
args
.
subImage
.
w
=
w
;
cmd
.
args
.
subImage
.
h
=
h
;
cmd
.
args
.
subImage
.
dx
=
d
p
.
x
()
;
cmd
.
args
.
subImage
.
dy
=
d
p
.
y
()
;
cmd
.
args
.
subImage
.
w
=
size
.
width
()
;
cmd
.
args
.
subImage
.
h
=
size
.
height
()
;
cmd
.
args
.
subImage
.
glformat
=
texD
->
glformat
;
cmd
.
args
.
subImage
.
gltype
=
texD
->
gltype
;
cmd
.
args
.
subImage
.
data
=
cbD
->
retainImage
(
img
);
...
...
src/rhi/qrhimetal.mm
View file @
ab819490
...
...
@@ -1098,18 +1098,20 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
};
for
(
const
QRhiResourceUpdateBatchPrivate
::
TextureUpload
&
u
:
ud
->
textureUploads
)
{
if
(
u
.
desc
.
layers
.
isEmpty
()
||
u
.
desc
.
layers
[
0
].
mipImages
.
isEmpty
())
const
QVector
<
QRhiTextureLayer
>
layers
=
u
.
desc
.
layers
();
if
(
layers
.
isEmpty
()
||
layers
[
0
].
mipImages
.
isEmpty
())
continue
;
QMetalTexture
*
utexD
=
QRHI_RES
(
QMetalTexture
,
u
.
tex
);
qsizetype
stagingSize
=
0
;
const
int
texbufAlign
=
256
;
// probably not needed
for
(
int
layer
=
0
,
layerCount
=
u
.
desc
.
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureUploadDescription
::
Layer
&
layerDesc
(
u
.
desc
.
layers
[
layer
]);
Q_ASSERT
(
layerDesc
.
mipImages
.
count
()
==
1
||
utexD
->
m_flags
.
testFlag
(
QRhiTexture
::
MipMapped
));
for
(
int
level
=
0
,
levelCount
=
layerDesc
.
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureUploadDescription
::
Layer
::
MipLevel
mipDesc
(
layerDesc
.
mipImages
[
level
]);
for
(
int
layer
=
0
,
layerCount
=
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureLayer
&
layerDesc
(
layers
[
layer
]);
const
QVector
<
QRhiTextureMipLevel
>
mipImages
=
layerDesc
.
mipImages
();
Q_ASSERT
(
mipImages
.
count
()
==
1
||
utexD
->
m_flags
.
testFlag
(
QRhiTexture
::
MipMapped
));
for
(
int
level
=
0
,
levelCount
=
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureMipLevel
&
mipDesc
(
mipImages
[
level
]);
const
qsizetype
imageSizeBytes
=
mipDesc
.
image
.
isNull
()
?
mipDesc
.
compressedData
.
size
()
:
mipDesc
.
image
.
sizeInBytes
();
if
(
imageSizeBytes
>
0
)
...
...
@@ -1125,27 +1127,28 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
void
*
mp
=
[
utexD
->
d
->
stagingBuf
[
currentFrameSlot
]
contents
];
qsizetype
curOfs
=
0
;
for
(
int
layer
=
0
,
layerCount
=
u
.
desc
.
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureUploadDescription
::
Layer
&
layerDesc
(
u
.
desc
.
layers
[
layer
]);
for
(
int
level
=
0
,
levelCount
=
layerDesc
.
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureUploadDescription
::
Layer
::
MipLevel
mipDesc
(
layerDesc
.
mipImages
[
level
]);
int
dx
=
mipDesc
.
destinationTopLeft
.
x
();
int
dy
=
mipDesc
.
destinationTopLeft
.
y
();
if
(
!
mipDesc
.
image
.
isNull
())
{
const
qsizetype
fullImageSizeBytes
=
mipDesc
.
image
.
sizeInBytes
();
QImage
img
=
mipDesc
.
image
;
for
(
int
layer
=
0
,
layerCount
=
layers
.
count
();
layer
!=
layerCount
;
++
layer
)
{
const
QRhiTextureLayer
&
layerDesc
(
layers
[
layer
]);
const
QVector
<
QRhiTextureMipLevel
>
mipImages
=
layerDesc
.
mipImages
();
for
(
int
level
=
0
,
levelCount
=
mipImages
.
count
();
level
!=
levelCount
;
++
level
)
{
const
QRhiTextureMipLevel
&
mipDesc
(
mipImages
[
level
]);
const
QPoint
dp
=
mipDesc
.
destinationTopLeft
();
const
QByteArray
compressedData
=
mipDesc
.
compressedData
();
QImage
img
=
mipDesc
.
image
();
if
(
!
img
.
isNull
())
{
const
qsizetype
fullImageSizeBytes
=
img
.
sizeInBytes
();
int
w
=
img
.
width
();
int
h
=
img
.
height
();
int
bpl
=
img
.
bytesPerLine
();
int
srcOffset
=
0
;
if
(
!
mipDesc
.
sourceSize
.
isEmpty
()
||
!
mipDesc
.
sourceTopLeft
.
isNull
())
{
const
int
sx
=
mipDesc
.
sourceTopLeft
.
x
();
const
int
sy
=
mipDesc
.
sourceTopLeft
.
y
();
if
(
!
mipDesc
.
sourceSize
.
isEmpty
())
{
w
=
mipDesc
.
sourceSize
.
width
();
h
=
mipDesc
.
sourceSize
.
height
();
if
(
!
mipDesc
.
sourceSize
()
.
isEmpty
()
||
!
mipDesc
.
sourceTopLeft
()
.
isNull
())
{
const
int
sx
=
mipDesc
.
sourceTopLeft
()
.
x
();
const
int
sy
=
mipDesc
.
sourceTopLeft
()
.
y
();
if
(
!
mipDesc
.
sourceSize
()
.
isEmpty
())
{
w
=
mipDesc
.
sourceSize
()
.
width
();
h
=
mipDesc
.
sourceSize
()
.
height
();
}
if
(
img
.
depth
()
==
32
)
{
memcpy
(
reinterpret_cast
<
char
*>
(
mp
)
+
curOfs
,
img
.
constBits
(),
fullImageSizeBytes
);