font: render font texture
This commit is contained in:
parent
51167365d5
commit
4042bbd623
3
Makefile
3
Makefile
@ -53,7 +53,8 @@ OBJS = \
|
|||||||
src/minecraft/world.o \
|
src/minecraft/world.o \
|
||||||
src/minecraft/entry_table.o \
|
src/minecraft/entry_table.o \
|
||||||
src/minecraft/vulkan.o \
|
src/minecraft/vulkan.o \
|
||||||
src/minecraft/vulkan/per_world.o
|
src/minecraft/vulkan/per_world.o \
|
||||||
|
src/font/outline.o
|
||||||
|
|
||||||
WORLDS = \
|
WORLDS = \
|
||||||
data/minecraft/midnightmeadow/inthash.o \
|
data/minecraft/midnightmeadow/inthash.o \
|
||||||
|
|||||||
BIN
data/font/outline/uncial_antiqua_36.data
Normal file
BIN
data/font/outline/uncial_antiqua_36.data
Normal file
Binary file not shown.
@ -35,3 +35,6 @@ data/minecraft/midnightmeadow/global.dump
|
|||||||
data/minecraft/midnightmeadow/global.lights.vtx
|
data/minecraft/midnightmeadow/global.lights.vtx
|
||||||
|
|
||||||
data/minecraft/terrain2.dds
|
data/minecraft/terrain2.dds
|
||||||
|
|
||||||
|
shader/font.spv
|
||||||
|
data/font/outline/uncial_antiqua_36.data
|
||||||
|
|||||||
79
include/font/outline.h
Normal file
79
include/font/outline.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "outline_types.h"
|
||||||
|
#include "vulkan_helper.h"
|
||||||
|
|
||||||
|
namespace font::outline {
|
||||||
|
|
||||||
|
struct font_desc {
|
||||||
|
char const * const path;
|
||||||
|
};
|
||||||
|
|
||||||
|
font_desc const uncial_antiqua[] = {
|
||||||
|
{
|
||||||
|
.path = "data/font/outline/uncial_antiqua_36.data",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
int const uncial_antiqua_length = (sizeof (uncial_antiqua)) / (sizeof (font_desc));
|
||||||
|
|
||||||
|
struct AllocatedImage {
|
||||||
|
VkImage image;
|
||||||
|
VkDeviceMemory memory;
|
||||||
|
VkImageView imageView;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LoadedFont {
|
||||||
|
types::font * font;
|
||||||
|
types::glyph * glyphs;
|
||||||
|
AllocatedImage allocatedImage;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct font {
|
||||||
|
static constexpr int perVertexSize = (4) * 2;
|
||||||
|
static constexpr int perInstanceSize = (0) * 2;
|
||||||
|
|
||||||
|
VkInstance instance;
|
||||||
|
VkDevice device;
|
||||||
|
VkQueue queue;
|
||||||
|
VkCommandPool commandPool;
|
||||||
|
VkPhysicalDeviceProperties physicalDeviceProperties;
|
||||||
|
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;
|
||||||
|
VkFormat colorFormat;
|
||||||
|
VkFormat depthFormat;
|
||||||
|
VkSampler linearSampler;
|
||||||
|
|
||||||
|
// font-specific state
|
||||||
|
VkPipelineLayout pipelineLayout;
|
||||||
|
VkShaderModule shaderModule;
|
||||||
|
VkPipeline pipeline;
|
||||||
|
VertexIndex vertexIndex;
|
||||||
|
LoadedFont loadedFont;
|
||||||
|
|
||||||
|
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
||||||
|
static constexpr int descriptorSetLayoutCount = 1;
|
||||||
|
VkDescriptorSetLayout descriptorSetLayouts[descriptorSetLayoutCount]; // unrelated to maxFrames, unrelated to descriptorCount
|
||||||
|
VkDescriptorSet descriptorSet0;
|
||||||
|
|
||||||
|
void initial_state(VkInstance instance,
|
||||||
|
VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandPool commandPool,
|
||||||
|
VkPhysicalDeviceProperties physicalDeviceProperties,
|
||||||
|
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties,
|
||||||
|
VkFormat colorFormat,
|
||||||
|
VkFormat depthFormat,
|
||||||
|
VkSampler linearSampler);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void load_vertex_index_buffer();
|
||||||
|
void load_shader();
|
||||||
|
void create_descriptor_sets();
|
||||||
|
void write_descriptor_sets(VkImageView fontImageView);
|
||||||
|
void create_pipeline();
|
||||||
|
void draw(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex);
|
||||||
|
|
||||||
|
LoadedFont load_font(font_desc const& desc);
|
||||||
|
};
|
||||||
|
}
|
||||||
49
include/font/outline_types.h
Normal file
49
include/font/outline_types.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// this file is designed to be platform-agnostic
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace font::outline::types {
|
||||||
|
|
||||||
|
// metrics are 26.6 fixed point
|
||||||
|
struct glyph_metrics {
|
||||||
|
int32_t horiBearingX;
|
||||||
|
int32_t horiBearingY;
|
||||||
|
int32_t horiAdvance;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert((sizeof (struct glyph_metrics)) == ((sizeof (int32_t)) * 3));
|
||||||
|
|
||||||
|
struct glyph_bitmap {
|
||||||
|
uint16_t x;
|
||||||
|
uint16_t y;
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert((sizeof (struct glyph_bitmap)) == ((sizeof (uint16_t)) * 4));
|
||||||
|
|
||||||
|
struct glyph {
|
||||||
|
struct glyph_bitmap bitmap;
|
||||||
|
struct glyph_metrics metrics;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert((sizeof (struct glyph)) == ((sizeof (struct glyph_bitmap)) + (sizeof (struct glyph_metrics))));
|
||||||
|
|
||||||
|
struct font {
|
||||||
|
uint32_t first_char_code;
|
||||||
|
uint32_t last_char_code;
|
||||||
|
struct face_metrics {
|
||||||
|
int32_t height; // 26.6 fixed point
|
||||||
|
int32_t max_advance; // 26.6 fixed point
|
||||||
|
} face_metrics;
|
||||||
|
uint16_t glyph_count;
|
||||||
|
uint16_t _texture_stride;
|
||||||
|
uint16_t texture_width;
|
||||||
|
uint16_t texture_height;
|
||||||
|
uint32_t max_z_curve_ix;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert((sizeof (struct font)) == ((sizeof (uint32_t)) * 7));
|
||||||
|
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@
|
|||||||
#include "directxmath/directxmath.h"
|
#include "directxmath/directxmath.h"
|
||||||
#include "volk/volk.h"
|
#include "volk/volk.h"
|
||||||
|
|
||||||
|
#include "vulkan_helper.h"
|
||||||
#include "minecraft/vulkan/per_world.h"
|
#include "minecraft/vulkan/per_world.h"
|
||||||
|
|
||||||
namespace minecraft::vulkan {
|
namespace minecraft::vulkan {
|
||||||
@ -24,12 +25,7 @@ namespace minecraft::vulkan {
|
|||||||
static constexpr int perVertexSize = (3 + 3 + 2) * 2;
|
static constexpr int perVertexSize = (3 + 3 + 2) * 2;
|
||||||
static constexpr int perInstanceSize = (3 + 1 + 3 + 1) * 2;
|
static constexpr int perInstanceSize = (3 + 1 + 3 + 1) * 2;
|
||||||
|
|
||||||
struct {
|
VertexIndex vertexIndex;
|
||||||
VkDeviceSize jointWeightOffset;
|
|
||||||
VkDeviceSize indexOffset;
|
|
||||||
VkBuffer buffer;
|
|
||||||
VkDeviceMemory memory;
|
|
||||||
} vertexIndex;
|
|
||||||
|
|
||||||
// externally initialized, opaque handle
|
// externally initialized, opaque handle
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
|
|||||||
@ -73,3 +73,42 @@ void createImageFromFilenameTGA(VkDevice device,
|
|||||||
VkImage * outImage,
|
VkImage * outImage,
|
||||||
VkDeviceMemory * outMemory,
|
VkDeviceMemory * outMemory,
|
||||||
VkImageView * outImageView);
|
VkImageView * outImageView);
|
||||||
|
|
||||||
|
void createImage(VkDevice device,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
VkFormat format,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t levelCount,
|
||||||
|
VkImage * outImage,
|
||||||
|
VkDeviceMemory * outMemory,
|
||||||
|
VkImageView * outImageView);
|
||||||
|
|
||||||
|
void textureTransfer(VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkFence fence,
|
||||||
|
VkDeviceSize nonCoherentAtomSize,
|
||||||
|
VkPhysicalDeviceMemoryProperties const & physicalDeviceMemoryProperties,
|
||||||
|
uint32_t imageDataSize,
|
||||||
|
void * imageData,
|
||||||
|
VkImage image,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t levelCount,
|
||||||
|
uint32_t * levelOffsets);
|
||||||
|
|
||||||
|
struct VertexIndex {
|
||||||
|
VkDeviceSize indexOffset;
|
||||||
|
VkBuffer buffer;
|
||||||
|
VkDeviceMemory memory;
|
||||||
|
};
|
||||||
|
|
||||||
|
VertexIndex createVertexIndexBuffer(VkDevice device,
|
||||||
|
VkPhysicalDeviceProperties const& physicalDeviceProperties,
|
||||||
|
VkPhysicalDeviceMemoryProperties const& physicalDeviceMemoryProperties,
|
||||||
|
void const * vertexStart,
|
||||||
|
uint32_t vertexSize,
|
||||||
|
void const * indexStart,
|
||||||
|
uint32_t indexSize);
|
||||||
|
|||||||
32
shader/font.hlsl
Normal file
32
shader/font.hlsl
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// set 1: constant
|
||||||
|
[[vk::binding(0, 0)]] SamplerState ClosestSampler;
|
||||||
|
[[vk::binding(1, 0)]] Texture2D FontTexture;
|
||||||
|
|
||||||
|
struct VSInput
|
||||||
|
{
|
||||||
|
float2 Position : POSITION0;
|
||||||
|
float2 Texture : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VSOutput
|
||||||
|
{
|
||||||
|
float4 Position : SV_POSITION;
|
||||||
|
float2 Texture : NORMAL0;
|
||||||
|
};
|
||||||
|
|
||||||
|
[shader("vertex")]
|
||||||
|
VSOutput VSMain(VSInput input)
|
||||||
|
{
|
||||||
|
VSOutput output = (VSOutput)0;
|
||||||
|
output.Position = float4(input.Position, 0, 1);
|
||||||
|
output.Texture = input.Texture;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("pixel")]
|
||||||
|
float4 PSMain(VSOutput input) : SV_TARGET
|
||||||
|
{
|
||||||
|
float4 color = FontTexture.Sample(ClosestSampler, input.Texture);
|
||||||
|
return float4(color.xxx, 1.0);
|
||||||
|
}
|
||||||
481
src/font/outline.cpp
Normal file
481
src/font/outline.cpp
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "volk/volk.h"
|
||||||
|
#include "vulkan/vk_enum_string_helper.h"
|
||||||
|
|
||||||
|
#include "directxmath/directxmath.h"
|
||||||
|
#include "vulkan_helper.h"
|
||||||
|
#include "check.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
#include "font/outline.h"
|
||||||
|
#include "font/outline_types.h"
|
||||||
|
|
||||||
|
namespace font::outline {
|
||||||
|
static const _Float16 vertexData[] = {
|
||||||
|
// x y u v
|
||||||
|
(_Float16)-1.0, (_Float16)-1.0, (_Float16)0.0, (_Float16)0.0,
|
||||||
|
(_Float16)1.0, (_Float16)-1.0, (_Float16)1.0, (_Float16)0.0,
|
||||||
|
(_Float16)-1.0, (_Float16)1.0, (_Float16)0.0, (_Float16)1.0,
|
||||||
|
(_Float16)1.0, (_Float16)1.0, (_Float16)1.0, (_Float16)1.0,
|
||||||
|
};
|
||||||
|
static const uint32_t vertexSize = (sizeof (vertexData));
|
||||||
|
|
||||||
|
static const uint16_t indexData[] = {
|
||||||
|
0, 1, 2, 3,
|
||||||
|
};
|
||||||
|
static const uint32_t indexSize = (sizeof (indexData));
|
||||||
|
|
||||||
|
void font::initial_state(VkInstance instance,
|
||||||
|
VkDevice device,
|
||||||
|
VkQueue queue,
|
||||||
|
VkCommandPool commandPool,
|
||||||
|
VkPhysicalDeviceProperties physicalDeviceProperties,
|
||||||
|
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties,
|
||||||
|
VkFormat colorFormat,
|
||||||
|
VkFormat depthFormat,
|
||||||
|
VkSampler linearSampler)
|
||||||
|
{
|
||||||
|
this->instance = instance;
|
||||||
|
this->device = device;
|
||||||
|
this->queue = queue;
|
||||||
|
this->commandPool = commandPool;
|
||||||
|
|
||||||
|
this->physicalDeviceProperties = physicalDeviceProperties;
|
||||||
|
this->physicalDeviceMemoryProperties = physicalDeviceMemoryProperties;
|
||||||
|
|
||||||
|
this->colorFormat = colorFormat;
|
||||||
|
this->depthFormat = depthFormat;
|
||||||
|
|
||||||
|
this->linearSampler = linearSampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void font::init()
|
||||||
|
{
|
||||||
|
load_vertex_index_buffer();
|
||||||
|
load_shader();
|
||||||
|
create_descriptor_sets();
|
||||||
|
loadedFont = load_font(uncial_antiqua[0]);
|
||||||
|
write_descriptor_sets(loadedFont.allocatedImage.imageView);
|
||||||
|
create_pipeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// vertex index buffer
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::load_vertex_index_buffer()
|
||||||
|
{
|
||||||
|
void const * vertexStart = (void const *)vertexData;
|
||||||
|
void const * indexStart = (void const *)indexData;
|
||||||
|
|
||||||
|
vertexIndex = createVertexIndexBuffer(device,
|
||||||
|
physicalDeviceProperties,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
vertexStart, vertexSize,
|
||||||
|
indexStart, indexSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// shader
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::load_shader()
|
||||||
|
{
|
||||||
|
uint32_t shaderSize;
|
||||||
|
void const * shaderStart = file::open("shader/font.spv", &shaderSize);
|
||||||
|
|
||||||
|
VkShaderModuleCreateInfo shaderModuleCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||||
|
.codeSize = shaderSize,
|
||||||
|
.pCode = (uint32_t *)shaderStart
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &shaderModule));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// pipeline
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::create_pipeline()
|
||||||
|
{
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
|
.setLayoutCount = descriptorSetLayoutCount,
|
||||||
|
.pSetLayouts = descriptorSetLayouts,
|
||||||
|
.pushConstantRangeCount = 0,
|
||||||
|
.pPushConstantRanges = nullptr
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
||||||
|
|
||||||
|
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
||||||
|
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo shaderStages[2]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
|
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
.module = shaderModule,
|
||||||
|
.pName = "VSMain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
|
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
.module = shaderModule,
|
||||||
|
.pName = "PSMain"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineViewportStateCreateInfo viewportState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||||
|
.viewportCount = 1,
|
||||||
|
.scissorCount = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint32_t dynamicStateCount = 2;
|
||||||
|
VkDynamicState dynamicStates[dynamicStateCount]{
|
||||||
|
VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
|
VK_DYNAMIC_STATE_SCISSOR,
|
||||||
|
};
|
||||||
|
VkPipelineDynamicStateCreateInfo dynamicState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||||
|
.dynamicStateCount = dynamicStateCount,
|
||||||
|
.pDynamicStates = dynamicStates
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineDepthStencilStateCreateInfo depthStencilState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||||
|
.depthTestEnable = VK_FALSE,
|
||||||
|
.depthWriteEnable = VK_FALSE,
|
||||||
|
.depthCompareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
|
.stencilTestEnable = VK_FALSE,
|
||||||
|
.front = {
|
||||||
|
.failOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.passOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.depthFailOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
|
.compareMask = 0x01,
|
||||||
|
.writeMask = 0x01,
|
||||||
|
.reference = 1,
|
||||||
|
},
|
||||||
|
.back = {
|
||||||
|
.failOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.passOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.depthFailOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
|
.compareMask = 0x01,
|
||||||
|
.writeMask = 0x01,
|
||||||
|
.reference = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineRenderingCreateInfo renderingCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
|
||||||
|
.colorAttachmentCount = 1,
|
||||||
|
.pColorAttachmentFormats = &colorFormat,
|
||||||
|
.depthAttachmentFormat = depthFormat,
|
||||||
|
.stencilAttachmentFormat = depthFormat
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineColorBlendAttachmentState blendAttachment{
|
||||||
|
.colorWriteMask = 0xF
|
||||||
|
};
|
||||||
|
VkPipelineColorBlendStateCreateInfo colorBlendState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||||
|
.attachmentCount = 1,
|
||||||
|
.pAttachments = &blendAttachment
|
||||||
|
};
|
||||||
|
VkPipelineRasterizationStateCreateInfo rasterizationState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||||
|
//.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||||
|
.cullMode = VK_CULL_MODE_NONE,
|
||||||
|
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||||
|
.lineWidth = 1.0f
|
||||||
|
};
|
||||||
|
VkPipelineMultisampleStateCreateInfo multisampleState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||||
|
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
VkVertexInputBindingDescription vertexBindingDescriptions[2]{
|
||||||
|
{
|
||||||
|
.binding = 0,
|
||||||
|
.stride = perVertexSize,
|
||||||
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = 1,
|
||||||
|
.stride = perInstanceSize,
|
||||||
|
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VkVertexInputAttributeDescription vertexAttributeDescriptions[2]{
|
||||||
|
// per-vertex
|
||||||
|
{ // position
|
||||||
|
.location = 0,
|
||||||
|
.binding = 0,
|
||||||
|
.format = VK_FORMAT_R16G16_SFLOAT,
|
||||||
|
.offset = 0,
|
||||||
|
},
|
||||||
|
{ // texture
|
||||||
|
.location = 1,
|
||||||
|
.binding = 0,
|
||||||
|
.format = VK_FORMAT_R16G16_SFLOAT,
|
||||||
|
.offset = 4,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
VkPipelineVertexInputStateCreateInfo vertexInputState{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
|
//.vertexBindingDescriptionCount = 2,
|
||||||
|
.vertexBindingDescriptionCount = 1,
|
||||||
|
.pVertexBindingDescriptions = vertexBindingDescriptions,
|
||||||
|
.vertexAttributeDescriptionCount = 2,
|
||||||
|
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkGraphicsPipelineCreateInfo pipelineCreateInfos[1]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
|
.pNext = &renderingCreateInfo,
|
||||||
|
.stageCount = 2,
|
||||||
|
.pStages = shaderStages,
|
||||||
|
.pVertexInputState = &vertexInputState,
|
||||||
|
.pInputAssemblyState = &inputAssemblyState,
|
||||||
|
.pViewportState = &viewportState,
|
||||||
|
.pRasterizationState = &rasterizationState,
|
||||||
|
.pMultisampleState = &multisampleState,
|
||||||
|
.pDepthStencilState = &depthStencilState,
|
||||||
|
.pColorBlendState = &colorBlendState,
|
||||||
|
.pDynamicState = &dynamicState,
|
||||||
|
.layout = pipelineLayout
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, pipelineCreateInfos, nullptr, &pipeline));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// load font
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LoadedFont font::load_font(font_desc const& desc)
|
||||||
|
{
|
||||||
|
uint32_t font_data_size;
|
||||||
|
void const * font_data = file::open(desc.path, &font_data_size);
|
||||||
|
assert(font_data != nullptr);
|
||||||
|
|
||||||
|
types::font * font = (types::font *)font_data;
|
||||||
|
types::glyph * glyphs = (types::glyph *)(((ptrdiff_t)font_data) + (sizeof (types::font)));
|
||||||
|
|
||||||
|
void * texture_data = (void *)(((ptrdiff_t)glyphs) + (sizeof (types::glyph)) * font->glyph_count);
|
||||||
|
|
||||||
|
ptrdiff_t font_end = ((ptrdiff_t)font_data) + font_data_size;
|
||||||
|
int texture_size = font->texture_width * font->texture_height;
|
||||||
|
assert(font_end - ((ptrdiff_t)texture_data) == texture_size);
|
||||||
|
|
||||||
|
// transfer texture
|
||||||
|
|
||||||
|
VkCommandBuffer commandBuffer{};
|
||||||
|
VkCommandBufferAllocateInfo commandBufferAllocateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||||
|
.commandPool = commandPool,
|
||||||
|
.commandBufferCount = 1
|
||||||
|
};
|
||||||
|
VK_CHECK(vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer));
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
|
||||||
|
};
|
||||||
|
VkFence fence{};
|
||||||
|
VK_CHECK(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||||
|
|
||||||
|
void * imageData = texture_data;
|
||||||
|
uint32_t imageDataSize = texture_size;
|
||||||
|
VkFormat format = VK_FORMAT_R8_UNORM;
|
||||||
|
uint32_t width = font->texture_width;
|
||||||
|
uint32_t height = font->texture_height;
|
||||||
|
uint32_t levelCount = 1;
|
||||||
|
uint32_t levelOffset = 0;
|
||||||
|
VkImage outImage;
|
||||||
|
VkDeviceMemory outMemory;
|
||||||
|
VkImageView outImageView;
|
||||||
|
|
||||||
|
createImage(device,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
format,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
levelCount,
|
||||||
|
&outImage,
|
||||||
|
&outMemory,
|
||||||
|
&outImageView);
|
||||||
|
|
||||||
|
textureTransfer(device,
|
||||||
|
queue,
|
||||||
|
commandBuffer,
|
||||||
|
fence,
|
||||||
|
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
imageDataSize,
|
||||||
|
imageData,
|
||||||
|
outImage,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
levelCount,
|
||||||
|
&levelOffset);
|
||||||
|
|
||||||
|
vkDestroyFence(device, fence, nullptr);
|
||||||
|
vkFreeCommandBuffers(device,
|
||||||
|
commandPool,
|
||||||
|
1,
|
||||||
|
&commandBuffer);
|
||||||
|
|
||||||
|
// return
|
||||||
|
return {
|
||||||
|
.font = font,
|
||||||
|
.glyphs = glyphs,
|
||||||
|
.allocatedImage = {
|
||||||
|
.image = outImage,
|
||||||
|
.memory = outMemory,
|
||||||
|
.imageView = outImageView,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// descriptor sets
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::create_descriptor_sets()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// pool
|
||||||
|
//
|
||||||
|
constexpr int descriptorPoolSizesCount = 2;
|
||||||
|
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
||||||
|
{ // linear sampler
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
|
.maxSets = 1,
|
||||||
|
.poolSizeCount = descriptorPoolSizesCount,
|
||||||
|
.pPoolSizes = descriptorPoolSizes
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateDescriptorPool(device, &descriptorPoolCreateInfo, nullptr, &descriptorPool));
|
||||||
|
|
||||||
|
//
|
||||||
|
// (set 0, constant)
|
||||||
|
//
|
||||||
|
{
|
||||||
|
constexpr int bindingCount = 2;
|
||||||
|
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
||||||
|
{
|
||||||
|
.binding = 0,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
|
},
|
||||||
|
{ // font image
|
||||||
|
.binding = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
|
.bindingCount = bindingCount,
|
||||||
|
.pBindings = descriptorSetLayoutBindings
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayouts[0]));
|
||||||
|
|
||||||
|
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
|
.descriptorPool = descriptorPool,
|
||||||
|
.descriptorSetCount = 1,
|
||||||
|
.pSetLayouts = &descriptorSetLayouts[0]
|
||||||
|
};
|
||||||
|
VK_CHECK(vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// descriptor set writes
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::write_descriptor_sets(VkImageView fontImageView)
|
||||||
|
{
|
||||||
|
constexpr uint32_t writeCount = 2;
|
||||||
|
VkWriteDescriptorSet writeDescriptorSets[writeCount];
|
||||||
|
uint32_t writeIndex = 0;
|
||||||
|
|
||||||
|
// set1 bindings
|
||||||
|
VkDescriptorImageInfo samplerDescriptorImageInfo = {
|
||||||
|
.sampler = linearSampler,
|
||||||
|
};
|
||||||
|
writeDescriptorSets[writeIndex++] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet0,
|
||||||
|
.dstBinding = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
|
.pImageInfo = &samplerDescriptorImageInfo
|
||||||
|
};
|
||||||
|
VkDescriptorImageInfo terrainDescriptorImageInfo = {
|
||||||
|
.imageView = fontImageView,
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL
|
||||||
|
};
|
||||||
|
writeDescriptorSets[writeIndex++] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSet0,
|
||||||
|
.dstBinding = 1,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.pImageInfo = &terrainDescriptorImageInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(writeIndex == writeCount);
|
||||||
|
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// draw
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void font::draw(VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||||
|
|
||||||
|
VkDescriptorSet descriptorSets[1] = {
|
||||||
|
descriptorSet0,
|
||||||
|
};
|
||||||
|
vkCmdBindDescriptorSets(commandBuffer,
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
pipelineLayout,
|
||||||
|
0, 1, descriptorSets,
|
||||||
|
0, nullptr);
|
||||||
|
|
||||||
|
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset, VK_INDEX_TYPE_UINT16);
|
||||||
|
|
||||||
|
VkDeviceSize vertexOffset{ 0 };
|
||||||
|
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexIndex.buffer, &vertexOffset);
|
||||||
|
|
||||||
|
vkCmdDrawIndexed(commandBuffer, 4, 1, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/main.cpp
27
src/main.cpp
@ -20,6 +20,7 @@
|
|||||||
#include "collada/scene/vulkan.h"
|
#include "collada/scene/vulkan.h"
|
||||||
|
|
||||||
#include "minecraft/vulkan.h"
|
#include "minecraft/vulkan.h"
|
||||||
|
#include "font/outline.h"
|
||||||
|
|
||||||
#include "scenes/shadow_test/shadow_test.h"
|
#include "scenes/shadow_test/shadow_test.h"
|
||||||
#include "scenes/eidelwind/eidelwind.h"
|
#include "scenes/eidelwind/eidelwind.h"
|
||||||
@ -678,6 +679,22 @@ int main()
|
|||||||
shadowDepthImageViewDepth);
|
shadowDepthImageViewDepth);
|
||||||
minecraft_state.init();
|
minecraft_state.init();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// initialize font
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
font::outline::font font_state;
|
||||||
|
font_state.initial_state(instance,
|
||||||
|
device,
|
||||||
|
queue,
|
||||||
|
commandPool,
|
||||||
|
physicalDeviceProperties,
|
||||||
|
physicalDeviceMemoryProperties,
|
||||||
|
surfaceFormat.format,
|
||||||
|
depthFormat,
|
||||||
|
textureSamplers[2]);
|
||||||
|
font_state.init();
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// initialize view
|
// initialize view
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -798,7 +815,7 @@ int main()
|
|||||||
// transfer
|
// transfer
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
{
|
if (0) {
|
||||||
collada_state.vulkan.change_frame(commandBuffer, frameIndex);
|
collada_state.vulkan.change_frame(commandBuffer, frameIndex);
|
||||||
|
|
||||||
XMMATRIX projection = currentProjection();
|
XMMATRIX projection = currentProjection();
|
||||||
@ -901,7 +918,7 @@ int main()
|
|||||||
|
|
||||||
collada_state.vulkan.excludeMaterialIndex = lightMaterialIndex;
|
collada_state.vulkan.excludeMaterialIndex = lightMaterialIndex;
|
||||||
collada_state.vulkan.pipelineIndex = 0; // shadow pipeline
|
collada_state.vulkan.pipelineIndex = 0; // shadow pipeline
|
||||||
collada_state.draw();
|
//collada_state.draw();
|
||||||
|
|
||||||
vkCmdEndRendering(commandBuffer);
|
vkCmdEndRendering(commandBuffer);
|
||||||
|
|
||||||
@ -1022,11 +1039,13 @@ int main()
|
|||||||
|
|
||||||
collada_state.vulkan.excludeMaterialIndex = -1;
|
collada_state.vulkan.excludeMaterialIndex = -1;
|
||||||
collada_state.vulkan.pipelineIndex = 1; // non-shadow pipeline
|
collada_state.vulkan.pipelineIndex = 1; // non-shadow pipeline
|
||||||
collada_state.draw();
|
//collada_state.draw();
|
||||||
//collada_state.vulkan.pipelineIndex = 2; // geometry shader pipeline
|
//collada_state.vulkan.pipelineIndex = 2; // geometry shader pipeline
|
||||||
//collada_state.draw();
|
//collada_state.draw();
|
||||||
|
|
||||||
minecraft_state.draw(commandBuffer, frameIndex);
|
//minecraft_state.draw(commandBuffer, frameIndex);
|
||||||
|
|
||||||
|
font_state.draw(commandBuffer, frameIndex);
|
||||||
|
|
||||||
vkCmdEndRendering(commandBuffer);
|
vkCmdEndRendering(commandBuffer);
|
||||||
|
|
||||||
|
|||||||
@ -72,54 +72,11 @@ namespace minecraft::vulkan {
|
|||||||
uint32_t indexSize;
|
uint32_t indexSize;
|
||||||
void const * indexStart = file::open(index_filename, &indexSize);
|
void const * indexStart = file::open(index_filename, &indexSize);
|
||||||
|
|
||||||
vertexIndex.indexOffset = vertexSize;
|
vertexIndex = createVertexIndexBuffer(device,
|
||||||
|
physicalDeviceProperties,
|
||||||
// create buffer
|
|
||||||
|
|
||||||
VkDeviceSize bufferSize{ vertexSize + indexSize };
|
|
||||||
VkBufferCreateInfo vertexIndexBufferCreateInfo{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
||||||
.size = bufferSize,
|
|
||||||
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
|
||||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
|
||||||
};
|
|
||||||
VK_CHECK(vkCreateBuffer(device, &vertexIndexBufferCreateInfo, nullptr, &vertexIndex.buffer));
|
|
||||||
|
|
||||||
// allocate memory
|
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements;
|
|
||||||
vkGetBufferMemoryRequirements(device, vertexIndex.buffer, &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,
|
physicalDeviceMemoryProperties,
|
||||||
memoryRequirements,
|
vertexStart, vertexSize,
|
||||||
memoryPropertyFlags,
|
indexStart, indexSize);
|
||||||
memoryAllocateFlags,
|
|
||||||
1,
|
|
||||||
&vertexIndex.memory,
|
|
||||||
&stride);
|
|
||||||
|
|
||||||
VK_CHECK(vkBindBufferMemory(device, vertexIndex.buffer, vertexIndex.memory, 0));
|
|
||||||
|
|
||||||
// copy data
|
|
||||||
|
|
||||||
void * vertexIndexMappedData;
|
|
||||||
VK_CHECK(vkMapMemory(device, vertexIndex.memory, 0, VK_WHOLE_SIZE, 0, &vertexIndexMappedData));
|
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize);
|
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), indexStart, indexSize);
|
|
||||||
|
|
||||||
VkMappedMemoryRange mappedMemoryRange{
|
|
||||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
|
||||||
.memory = vertexIndex.memory,
|
|
||||||
.offset = 0,
|
|
||||||
.size = VK_WHOLE_SIZE,
|
|
||||||
};
|
|
||||||
vkFlushMappedMemoryRanges(device, 1, &mappedMemoryRange);
|
|
||||||
|
|
||||||
vkUnmapMemory(device, vertexIndex.memory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -418,3 +418,65 @@ void createImageFromFilenameTGA(VkDevice device,
|
|||||||
|
|
||||||
free(imageStart);
|
free(imageStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VertexIndex createVertexIndexBuffer(VkDevice device,
|
||||||
|
VkPhysicalDeviceProperties const& physicalDeviceProperties,
|
||||||
|
VkPhysicalDeviceMemoryProperties const& physicalDeviceMemoryProperties,
|
||||||
|
void const * vertexStart,
|
||||||
|
uint32_t vertexSize,
|
||||||
|
void const * indexStart,
|
||||||
|
uint32_t indexSize)
|
||||||
|
{
|
||||||
|
VertexIndex vertexIndex{};
|
||||||
|
|
||||||
|
vertexIndex.indexOffset = vertexSize;
|
||||||
|
|
||||||
|
// create buffer
|
||||||
|
|
||||||
|
VkDeviceSize bufferSize{ vertexSize + indexSize };
|
||||||
|
VkBufferCreateInfo vertexIndexBufferCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.size = bufferSize,
|
||||||
|
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||||
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateBuffer(device, &vertexIndexBufferCreateInfo, nullptr, &vertexIndex.buffer));
|
||||||
|
|
||||||
|
// allocate memory
|
||||||
|
|
||||||
|
VkMemoryRequirements memoryRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device, vertexIndex.buffer, &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,
|
||||||
|
&vertexIndex.memory,
|
||||||
|
&stride);
|
||||||
|
|
||||||
|
VK_CHECK(vkBindBufferMemory(device, vertexIndex.buffer, vertexIndex.memory, 0));
|
||||||
|
|
||||||
|
// copy data
|
||||||
|
|
||||||
|
void * vertexIndexMappedData;
|
||||||
|
VK_CHECK(vkMapMemory(device, vertexIndex.memory, 0, VK_WHOLE_SIZE, 0, &vertexIndexMappedData));
|
||||||
|
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize);
|
||||||
|
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), indexStart, indexSize);
|
||||||
|
|
||||||
|
VkMappedMemoryRange mappedMemoryRange{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||||
|
.memory = vertexIndex.memory,
|
||||||
|
.offset = 0,
|
||||||
|
.size = VK_WHOLE_SIZE,
|
||||||
|
};
|
||||||
|
vkFlushMappedMemoryRanges(device, 1, &mappedMemoryRange);
|
||||||
|
|
||||||
|
vkUnmapMemory(device, vertexIndex.memory);
|
||||||
|
|
||||||
|
return vertexIndex;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user