@@ -17,13 +17,21 @@ namespace ext
17
17
namespace TextRendering
18
18
{
19
19
20
- core::smart_refctd_ptr<ICPUBuffer> TextRenderer::generateShapeMSDF (msdfgen::Shape glyph, uint32_t msdfPixelRange, uint32_t2 msdfExtents, float32_t2 scale, float32_t2 translate)
20
+ uint32_t TextRenderer::generateShapeMSDF (
21
+ core::smart_refctd_ptr<ICPUBuffer>& buffer, uint32_t bufferOffset,
22
+ msdfgen::Shape glyph, uint32_t msdfPixelRange, uint32_t2 msdfExtents,
23
+ float32_t2 scale, float32_t2 translate)
21
24
{
22
25
uint32_t glyphW = msdfExtents.x ;
23
26
uint32_t glyphH = msdfExtents.y ;
24
27
25
- auto cpuBuf = core::make_smart_refctd_ptr<ICPUBuffer>(glyphW * glyphH * sizeof (int8_t ) * 4 );
26
- int8_t * data = reinterpret_cast <int8_t *>(cpuBuf->getPointer ());
28
+ uint32_t bufferSize = glyphW * glyphH * sizeof (int8_t ) * 4 ;
29
+ if (buffer->getSize () + bufferOffset < bufferSize)
30
+ {
31
+ return 0u ;
32
+ }
33
+
34
+ int8_t * data = reinterpret_cast <int8_t *>(buffer->getPointer ()) + bufferOffset;
27
35
28
36
auto floatToSNORM8 = [](const float fl) -> int8_t
29
37
{
@@ -51,7 +59,7 @@ core::smart_refctd_ptr<ICPUBuffer> TextRenderer::generateShapeMSDF(msdfgen::Shap
51
59
}
52
60
}
53
61
54
- return std::move (cpuBuf) ;
62
+ return bufferSize ;
55
63
}
56
64
57
65
constexpr double FreeTypeFontScaling = 1.0 / 64.0 ;
@@ -76,9 +84,24 @@ FontFace::GlyphMetrics FontFace::getGlyphMetrics(uint32_t glyphId)
76
84
};
77
85
}
78
86
79
- std::vector< core::smart_refctd_ptr<ICPUBuffer> > FontFace::generateGlyphMSDF (uint32_t msdfPixelRange, uint32_t glyphId, uint32_t2 textureExtents, uint32_t mipLevels)
87
+ core::smart_refctd_ptr<ICPUImage > FontFace::generateGlyphMSDF (uint32_t msdfPixelRange, uint32_t glyphId, uint32_t2 textureExtents, uint32_t mipLevels)
80
88
{
81
- std::vector<core::smart_refctd_ptr<ICPUBuffer>> buffers;
89
+ ICPUImage::SCreationParams imgParams;
90
+ {
91
+ imgParams.flags = static_cast <ICPUImage::E_CREATE_FLAGS>(0u ); // no flags
92
+ imgParams.type = ICPUImage::ET_2D;
93
+ imgParams.format = TextRenderer::MSDFTextureFormat;
94
+ imgParams.extent = { textureExtents.x , textureExtents.y , 1 };
95
+ imgParams.mipLevels = mipLevels;
96
+ imgParams.arrayLayers = 1u ;
97
+ imgParams.samples = ICPUImage::ESCF_1_BIT;
98
+ }
99
+
100
+ auto image = ICPUImage::create (std::move (imgParams));
101
+ auto buffer = core::make_smart_refctd_ptr<ICPUBuffer>(textureExtents.x * textureExtents.y * sizeof (uint8_t ) * 4 * 2 );
102
+ auto regions = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<IImage::SBufferCopy>>(mipLevels);
103
+
104
+ uint32_t bufferOffset = 0u ;
82
105
for (uint32_t i = 0 ; i < mipLevels; i++)
83
106
{
84
107
// we need to generate a msdfgen per mip map, because the msdf generate call consumes the shape
@@ -88,10 +111,22 @@ std::vector<core::smart_refctd_ptr<ICPUBuffer>> FontFace::generateGlyphMSDF(uint
88
111
// Empty shapes should've been filtered sooner
89
112
assert (!shape.contours .empty ());
90
113
91
- auto shapeBounds = shape.getBounds ();
92
-
93
114
uint32_t mipW = textureExtents.x / (1 << i);
94
115
uint32_t mipH = textureExtents.y / (1 << i);
116
+
117
+ auto & region = regions->begin ()[i];
118
+ region.bufferOffset = 0u ;
119
+ region.bufferRowLength = 0u ;
120
+ region.bufferImageHeight = 0u ;
121
+ // region.imageSubresource.aspectMask = wait for Vulkan;
122
+ region.imageSubresource .mipLevel = i;
123
+ region.imageSubresource .baseArrayLayer = 0u ;
124
+ region.imageSubresource .layerCount = 1u ;
125
+ region.imageOffset = { 0u ,0u ,0u };
126
+ region.imageExtent = { mipW, mipH };
127
+
128
+ auto shapeBounds = shape.getBounds ();
129
+
95
130
float32_t2 mipExtents = float32_t2 (float (mipW), float (mipH));
96
131
uint32_t mipPixelRange = msdfPixelRange / (1 << i);
97
132
@@ -112,9 +147,14 @@ std::vector<core::smart_refctd_ptr<ICPUBuffer>> FontFace::generateGlyphMSDF(uint
112
147
const float32_t2 shapeSpaceCenter = float32_t2 (shapeBounds.l + shapeBounds.r , shapeBounds.t + shapeBounds.b ) * float32_t2 (0.5 );
113
148
const float32_t2 translate = mipExtents / (float32_t2 (2.0 ) * uniformScale) - shapeSpaceCenter;
114
149
115
- buffers.push_back (m_textRenderer->generateShapeMSDF (shape, mipPixelRange, mipExtents, float32_t2 (uniformScale, uniformScale), translate));
150
+ uint32_t result = m_textRenderer->generateShapeMSDF (buffer, bufferOffset, shape, mipPixelRange, mipExtents, float32_t2 (uniformScale, uniformScale), translate);
151
+ // Failing here means the buffer didn't have enough space
152
+ assert (result);
153
+ bufferOffset += result;
116
154
}
117
- return buffers;
155
+ image->setBufferAndRegions (std::move (buffer), std::move (regions));
156
+
157
+ return image;
118
158
}
119
159
120
160
float32_t2 FontFace::getUV (float32_t2 uv, float32_t2 glyphSize, uint32_t2 textureExtents, uint32_t msdfPixelRange)
0 commit comments