font: glyph per-instance data, draw multiple individual glyphs
This commit is contained in:
parent
4042bbd623
commit
bb6f76cf72
@ -28,9 +28,26 @@ namespace font::outline {
|
|||||||
AllocatedImage allocatedImage;
|
AllocatedImage allocatedImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GlyphInstance {
|
||||||
|
uint16_t x;
|
||||||
|
uint16_t y;
|
||||||
|
uint32_t glyph;
|
||||||
|
uint32_t color;
|
||||||
|
};
|
||||||
|
static_assert((sizeof (GlyphInstance)) == 4 * 3);
|
||||||
|
|
||||||
|
struct Glyph {
|
||||||
|
uint32_t x;
|
||||||
|
uint32_t y;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
};
|
||||||
|
|
||||||
struct font {
|
struct font {
|
||||||
static constexpr int perVertexSize = (4) * 2;
|
static constexpr int perVertexSize = (4) * 2;
|
||||||
static constexpr int perInstanceSize = (0) * 2;
|
static constexpr int perInstanceSize = (sizeof (GlyphInstance));
|
||||||
|
|
||||||
|
static constexpr int maximumGlyphCount = 1024;
|
||||||
|
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
@ -49,6 +66,16 @@ namespace font::outline {
|
|||||||
VertexIndex vertexIndex;
|
VertexIndex vertexIndex;
|
||||||
LoadedFont loadedFont;
|
LoadedFont loadedFont;
|
||||||
|
|
||||||
|
VkDeviceSize instanceBufferOffset[2];
|
||||||
|
VkBuffer instanceBuffer;
|
||||||
|
VkDeviceMemory instanceMemory;
|
||||||
|
VkDeviceSize instanceMemorySize;
|
||||||
|
GlyphInstance * instanceMappedData;
|
||||||
|
|
||||||
|
VkBuffer glyphsBuffer;
|
||||||
|
VkDeviceMemory glyphsMemory;
|
||||||
|
VkDeviceSize glyphsBufferSize;
|
||||||
|
|
||||||
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
||||||
static constexpr int descriptorSetLayoutCount = 1;
|
static constexpr int descriptorSetLayoutCount = 1;
|
||||||
VkDescriptorSetLayout descriptorSetLayouts[descriptorSetLayoutCount]; // unrelated to maxFrames, unrelated to descriptorCount
|
VkDescriptorSetLayout descriptorSetLayouts[descriptorSetLayoutCount]; // unrelated to maxFrames, unrelated to descriptorCount
|
||||||
@ -70,7 +97,9 @@ namespace font::outline {
|
|||||||
void load_shader();
|
void load_shader();
|
||||||
void create_descriptor_sets();
|
void create_descriptor_sets();
|
||||||
void write_descriptor_sets(VkImageView fontImageView);
|
void write_descriptor_sets(VkImageView fontImageView);
|
||||||
|
void create_instance_buffers();
|
||||||
void create_pipeline();
|
void create_pipeline();
|
||||||
|
void create_glyphs_buffer(types::font const * const font, types::glyph const * const glyphs);
|
||||||
void draw(VkCommandBuffer commandBuffer,
|
void draw(VkCommandBuffer commandBuffer,
|
||||||
uint32_t frameIndex);
|
uint32_t frameIndex);
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,22 @@
|
|||||||
// set 1: constant
|
struct GlyphBitmap
|
||||||
|
{
|
||||||
|
uint2 Position; // x y, in texels
|
||||||
|
uint2 Size; // width height
|
||||||
|
};
|
||||||
|
|
||||||
|
// set 0: constant
|
||||||
[[vk::binding(0, 0)]] SamplerState ClosestSampler;
|
[[vk::binding(0, 0)]] SamplerState ClosestSampler;
|
||||||
[[vk::binding(1, 0)]] Texture2D FontTexture;
|
[[vk::binding(1, 0)]] Texture2D FontTexture;
|
||||||
|
[[vk::binding(2, 0)]] StructuredBuffer<GlyphBitmap> Glyphs;
|
||||||
|
|
||||||
struct VSInput
|
struct VSInput
|
||||||
{
|
{
|
||||||
float2 Position : POSITION0;
|
float2 Position : POSITION0;
|
||||||
float2 Texture : TEXCOORD0;
|
float2 Texture : TEXCOORD0;
|
||||||
|
// per-instance
|
||||||
|
uint2 InstancePosition : InstancePosition;
|
||||||
|
uint InstanceGlyph : InstanceGlyph;
|
||||||
|
float4 InstanceColor : InstanceColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VSOutput
|
struct VSOutput
|
||||||
@ -17,9 +28,14 @@ struct VSOutput
|
|||||||
[shader("vertex")]
|
[shader("vertex")]
|
||||||
VSOutput VSMain(VSInput input)
|
VSOutput VSMain(VSInput input)
|
||||||
{
|
{
|
||||||
|
float2 inverseTexel = float2(1.0 / 256.0, 1.0 / 256.0);
|
||||||
|
float2 inversePixel = float2(1.0 / 1024.0, 1.0 / 1024.0);
|
||||||
|
int index = input.InstanceGlyph;
|
||||||
|
|
||||||
VSOutput output = (VSOutput)0;
|
VSOutput output = (VSOutput)0;
|
||||||
output.Position = float4(input.Position, 0, 1);
|
float2 position = (input.Texture * Glyphs[index].Size + input.InstancePosition) * inversePixel;
|
||||||
output.Texture = input.Texture;
|
output.Position = float4(position * 2.0 - 1.0, 0, 1);
|
||||||
|
output.Texture = (input.Texture * Glyphs[index].Size + Glyphs[index].Position) * inverseTexel;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,9 @@ namespace font::outline {
|
|||||||
load_shader();
|
load_shader();
|
||||||
create_descriptor_sets();
|
create_descriptor_sets();
|
||||||
loadedFont = load_font(uncial_antiqua[0]);
|
loadedFont = load_font(uncial_antiqua[0]);
|
||||||
|
create_glyphs_buffer(loadedFont.font, loadedFont.glyphs);
|
||||||
write_descriptor_sets(loadedFont.allocatedImage.imageView);
|
write_descriptor_sets(loadedFont.allocatedImage.imageView);
|
||||||
|
create_instance_buffers();
|
||||||
create_pipeline();
|
create_pipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +203,8 @@ namespace font::outline {
|
|||||||
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
||||||
};
|
};
|
||||||
|
|
||||||
VkVertexInputBindingDescription vertexBindingDescriptions[2]{
|
constexpr int vertexBindingDescriptionsCount = 2;
|
||||||
|
VkVertexInputBindingDescription vertexBindingDescriptions[vertexBindingDescriptionsCount]{
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.stride = perVertexSize,
|
.stride = perVertexSize,
|
||||||
@ -214,7 +217,8 @@ namespace font::outline {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VkVertexInputAttributeDescription vertexAttributeDescriptions[2]{
|
constexpr int vertexAttributeDescriptionsCount = 5;
|
||||||
|
VkVertexInputAttributeDescription vertexAttributeDescriptions[vertexAttributeDescriptionsCount]{
|
||||||
// per-vertex
|
// per-vertex
|
||||||
{ // position
|
{ // position
|
||||||
.location = 0,
|
.location = 0,
|
||||||
@ -228,14 +232,32 @@ namespace font::outline {
|
|||||||
.format = VK_FORMAT_R16G16_SFLOAT,
|
.format = VK_FORMAT_R16G16_SFLOAT,
|
||||||
.offset = 4,
|
.offset = 4,
|
||||||
},
|
},
|
||||||
|
// per-instance
|
||||||
|
{
|
||||||
|
.location = 2,
|
||||||
|
.binding = 1,
|
||||||
|
.format = VK_FORMAT_R16G16_UINT,
|
||||||
|
.offset = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.location = 3,
|
||||||
|
.binding = 1,
|
||||||
|
.format = VK_FORMAT_R32_UINT,
|
||||||
|
.offset = 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.location = 4,
|
||||||
|
.binding = 1,
|
||||||
|
.format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
.offset = 8,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputState{
|
VkPipelineVertexInputStateCreateInfo vertexInputState{
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
//.vertexBindingDescriptionCount = 2,
|
.vertexBindingDescriptionCount = vertexBindingDescriptionsCount,
|
||||||
.vertexBindingDescriptionCount = 1,
|
|
||||||
.pVertexBindingDescriptions = vertexBindingDescriptions,
|
.pVertexBindingDescriptions = vertexBindingDescriptions,
|
||||||
.vertexAttributeDescriptionCount = 2,
|
.vertexAttributeDescriptionCount = vertexAttributeDescriptionsCount,
|
||||||
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -358,7 +380,7 @@ namespace font::outline {
|
|||||||
//
|
//
|
||||||
// pool
|
// pool
|
||||||
//
|
//
|
||||||
constexpr int descriptorPoolSizesCount = 2;
|
constexpr int descriptorPoolSizesCount = 3;
|
||||||
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
||||||
{ // linear sampler
|
{ // linear sampler
|
||||||
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
@ -367,7 +389,11 @@ namespace font::outline {
|
|||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
@ -381,7 +407,7 @@ namespace font::outline {
|
|||||||
// (set 0, constant)
|
// (set 0, constant)
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
constexpr int bindingCount = 2;
|
constexpr int bindingCount = 3;
|
||||||
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
@ -394,6 +420,12 @@ namespace font::outline {
|
|||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = 2,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -420,7 +452,7 @@ namespace font::outline {
|
|||||||
|
|
||||||
void font::write_descriptor_sets(VkImageView fontImageView)
|
void font::write_descriptor_sets(VkImageView fontImageView)
|
||||||
{
|
{
|
||||||
constexpr uint32_t writeCount = 2;
|
constexpr uint32_t writeCount = 3;
|
||||||
VkWriteDescriptorSet writeDescriptorSets[writeCount];
|
VkWriteDescriptorSet writeDescriptorSets[writeCount];
|
||||||
uint32_t writeIndex = 0;
|
uint32_t writeIndex = 0;
|
||||||
|
|
||||||
@ -448,11 +480,129 @@ namespace font::outline {
|
|||||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
.pImageInfo = &terrainDescriptorImageInfo
|
.pImageInfo = &terrainDescriptorImageInfo
|
||||||
};
|
};
|
||||||
|
VkDescriptorBufferInfo glyphsDescriptorBufferInfo{
|
||||||
|
.buffer = glyphsBuffer,
|
||||||
|
.offset = 0,
|
||||||
|
.range = glyphsBufferSize,
|
||||||
|
};
|
||||||
|
writeDescriptorSets[writeIndex++] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet0,
|
||||||
|
.dstBinding = 2,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.pBufferInfo = &glyphsDescriptorBufferInfo
|
||||||
|
};
|
||||||
assert(writeIndex == writeCount);
|
assert(writeIndex == writeCount);
|
||||||
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// create instance buffer
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::create_instance_buffers()
|
||||||
|
{
|
||||||
|
constexpr VkDeviceSize bufferSize{ maximumGlyphCount * (sizeof (GlyphInstance)) };
|
||||||
|
instanceMemorySize = bufferSize * 2;
|
||||||
|
instanceBufferOffset[0] = bufferSize * 0;
|
||||||
|
instanceBufferOffset[1] = bufferSize * 1;
|
||||||
|
|
||||||
|
// create buffer
|
||||||
|
VkBufferCreateInfo bufferCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.size = instanceMemorySize,
|
||||||
|
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||||
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &instanceBuffer));
|
||||||
|
|
||||||
|
// allocate memory
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device, instanceBuffer, &memoryRequirements);
|
||||||
|
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||||
|
VkMemoryAllocateFlags memoryAllocateFlags{};
|
||||||
|
VkDeviceSize stride;
|
||||||
|
allocateFromMemoryRequirements(device,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
memoryRequirements,
|
||||||
|
memoryPropertyFlags,
|
||||||
|
memoryAllocateFlags,
|
||||||
|
1,
|
||||||
|
&instanceMemory,
|
||||||
|
&stride);
|
||||||
|
|
||||||
|
VK_CHECK(vkBindBufferMemory(device, instanceBuffer, instanceMemory, 0));
|
||||||
|
|
||||||
|
// map memory
|
||||||
|
|
||||||
|
VK_CHECK(vkMapMemory(device, instanceMemory, 0, VK_WHOLE_SIZE, 0, (void **)&instanceMappedData));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// create instance buffer
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::create_glyphs_buffer(types::font const * const font, types::glyph const * const glyphs)
|
||||||
|
{
|
||||||
|
glyphsBufferSize = (sizeof (Glyph)) * font->glyph_count;
|
||||||
|
|
||||||
|
// create buffer
|
||||||
|
VkBufferCreateInfo bufferCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.size = glyphsBufferSize,
|
||||||
|
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &glyphsBuffer));
|
||||||
|
|
||||||
|
// allocate memory
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device, glyphsBuffer, &memoryRequirements);
|
||||||
|
VkMemoryPropertyFlags memoryPropertyFlags{ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT };
|
||||||
|
VkMemoryAllocateFlags memoryAllocateFlags{};
|
||||||
|
VkDeviceSize stride;
|
||||||
|
allocateFromMemoryRequirements(device,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
memoryRequirements,
|
||||||
|
memoryPropertyFlags,
|
||||||
|
memoryAllocateFlags,
|
||||||
|
1,
|
||||||
|
&glyphsMemory,
|
||||||
|
&stride);
|
||||||
|
|
||||||
|
VK_CHECK(vkBindBufferMemory(device, glyphsBuffer, glyphsMemory, 0));
|
||||||
|
|
||||||
|
// map memory
|
||||||
|
Glyph * glyphsMappedData;
|
||||||
|
VK_CHECK(vkMapMemory(device, glyphsMemory, 0, VK_WHOLE_SIZE, 0, (void **)&glyphsMappedData));
|
||||||
|
|
||||||
|
for (int i = 0; i < font->glyph_count; i++) {
|
||||||
|
glyphsMappedData[i].x = glyphs[i].bitmap.x;
|
||||||
|
glyphsMappedData[i].y = glyphs[i].bitmap.y;
|
||||||
|
glyphsMappedData[i].width = glyphs[i].bitmap.width;
|
||||||
|
glyphsMappedData[i].height = glyphs[i].bitmap.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// flush
|
||||||
|
constexpr int mappedMemoryRangesCount = 1;
|
||||||
|
VkMappedMemoryRange mappedMemoryRanges[mappedMemoryRangesCount]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||||
|
.memory = glyphsMemory,
|
||||||
|
.offset = 0,
|
||||||
|
.size = VK_WHOLE_SIZE,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
vkFlushMappedMemoryRanges(device, mappedMemoryRangesCount, mappedMemoryRanges);
|
||||||
|
|
||||||
|
vkUnmapMemory(device, glyphsMemory);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// draw
|
// draw
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -460,6 +610,52 @@ namespace font::outline {
|
|||||||
void font::draw(VkCommandBuffer commandBuffer,
|
void font::draw(VkCommandBuffer commandBuffer,
|
||||||
uint32_t frameIndex)
|
uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
|
// transfer
|
||||||
|
const char * string = "so when Nico wants to run this game on his\n4K monitor, he gets a dinky little 1280x720\nwindow instead?";
|
||||||
|
int outputIndex = 0;
|
||||||
|
int stringIndex = 0;
|
||||||
|
|
||||||
|
uint32_t x = 64 << 6;
|
||||||
|
uint32_t y = 64 << 6;
|
||||||
|
while (true) {
|
||||||
|
char c = string[stringIndex++];
|
||||||
|
if (c == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (c != ' ') {
|
||||||
|
instanceMappedData[maximumGlyphCount * frameIndex + outputIndex++] = {
|
||||||
|
(uint16_t)((x + loadedFont.glyphs[c - 32].metrics.horiBearingX) >> 6),
|
||||||
|
(uint16_t)((y - loadedFont.glyphs[c - 32].metrics.horiBearingY) >> 6),
|
||||||
|
(uint32_t)(c - 32),
|
||||||
|
0xaabbccdd,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\n') {
|
||||||
|
y += loadedFont.font->face_metrics.height * 1.2;
|
||||||
|
x = 64 << 6;
|
||||||
|
} else {
|
||||||
|
x += loadedFont.glyphs[c - 32].metrics.horiAdvance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// flush
|
||||||
|
constexpr int mappedMemoryRangesCount = 1;
|
||||||
|
VkMappedMemoryRange mappedMemoryRanges[mappedMemoryRangesCount]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||||
|
.memory = instanceMemory,
|
||||||
|
.offset = 0,
|
||||||
|
.size = (sizeof (GlyphInstance)),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
instanceMemorySize,
|
||||||
|
mappedMemoryRangesCount,
|
||||||
|
mappedMemoryRanges);
|
||||||
|
vkFlushMappedMemoryRanges(device, mappedMemoryRangesCount, mappedMemoryRanges);
|
||||||
|
|
||||||
|
// bind/draw
|
||||||
|
|
||||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||||
|
|
||||||
VkDescriptorSet descriptorSets[1] = {
|
VkDescriptorSet descriptorSets[1] = {
|
||||||
@ -473,9 +669,10 @@ namespace font::outline {
|
|||||||
|
|
||||||
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset, VK_INDEX_TYPE_UINT16);
|
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset, VK_INDEX_TYPE_UINT16);
|
||||||
|
|
||||||
VkDeviceSize vertexOffset{ 0 };
|
VkDeviceSize vertexOffsets[2]{ 0, instanceBufferOffset[frameIndex] };
|
||||||
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexIndex.buffer, &vertexOffset);
|
VkBuffer vertexBuffers[2]{ vertexIndex.buffer, instanceBuffer };
|
||||||
|
vkCmdBindVertexBuffers(commandBuffer, 0, 2, vertexBuffers, vertexOffsets);
|
||||||
|
|
||||||
vkCmdDrawIndexed(commandBuffer, 4, 1, 0, 0, 0);
|
vkCmdDrawIndexed(commandBuffer, 4, outputIndex, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1001,7 +1001,8 @@ int main()
|
|||||||
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
|
||||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
.clearValue{ .color{ 0.0f, 0.0f, 0.2f, 1.0f } }
|
//.clearValue{ .color{ 0.0f, 0.0f, 0.2f, 1.0f } }
|
||||||
|
.clearValue{ .color{ 0.0f, 0.0f, 0.0f, 0.0f } }
|
||||||
};
|
};
|
||||||
VkRenderingAttachmentInfo depthRenderingAttachmentInfo{
|
VkRenderingAttachmentInfo depthRenderingAttachmentInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user