mirror of
https://github.com/coah80/LegacyVulkEdition.git
synced 2026-06-24 18:15:32 +00:00
last hurrah from me
This commit is contained in:
447
Minecraft.Client/ThirdParty/vui_gpu.cpp
vendored
Normal file
447
Minecraft.Client/ThirdParty/vui_gpu.cpp
vendored
Normal file
@@ -0,0 +1,447 @@
|
||||
#include "vui_internal.h"
|
||||
|
||||
namespace vui {
|
||||
|
||||
uint32_t Renderer::Impl::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
|
||||
VkPhysicalDeviceMemoryProperties memProps;
|
||||
vkGetPhysicalDeviceMemoryProperties(physDevice, &memProps);
|
||||
for (uint32_t i = 0; i < memProps.memoryTypeCount; i++) {
|
||||
if ((typeFilter & (1 << i)) && (memProps.memoryTypes[i].propertyFlags & properties) == properties)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VkShaderModule Renderer::Impl::createShaderModule(const uint32_t *code, size_t sizeBytes) {
|
||||
VkShaderModuleCreateInfo ci{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
|
||||
ci.codeSize = sizeBytes;
|
||||
ci.pCode = code;
|
||||
VkShaderModule mod;
|
||||
vkCreateShaderModule(device, &ci, nullptr, &mod);
|
||||
return mod;
|
||||
}
|
||||
|
||||
void Renderer::Impl::initRenderPass() {
|
||||
VkAttachmentDescription colorAttachment{};
|
||||
colorAttachment.format = swapchainFormat;
|
||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
VkAttachmentReference colorRef{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
|
||||
|
||||
VkSubpassDescription subpass{};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &colorRef;
|
||||
|
||||
VkSubpassDependency dep{};
|
||||
dep.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dep.dstSubpass = 0;
|
||||
dep.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dep.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dep.srcAccessMask = 0;
|
||||
dep.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
VkRenderPassCreateInfo rpci{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
|
||||
rpci.attachmentCount = 1;
|
||||
rpci.pAttachments = &colorAttachment;
|
||||
rpci.subpassCount = 1;
|
||||
rpci.pSubpasses = &subpass;
|
||||
rpci.dependencyCount = 1;
|
||||
rpci.pDependencies = &dep;
|
||||
|
||||
vkCreateRenderPass(device, &rpci, nullptr, &renderPass);
|
||||
}
|
||||
|
||||
void Renderer::Impl::initPipeline() {
|
||||
VkDescriptorSetLayoutBinding binding{};
|
||||
binding.binding = 0;
|
||||
binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
binding.descriptorCount = 1;
|
||||
binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo dslci{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};
|
||||
dslci.bindingCount = 1;
|
||||
dslci.pBindings = &binding;
|
||||
vkCreateDescriptorSetLayout(device, &dslci, nullptr, &descriptorSetLayout);
|
||||
|
||||
VkPushConstantRange pushRange{};
|
||||
pushRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
pushRange.offset = 0;
|
||||
pushRange.size = sizeof(float) * 16;
|
||||
|
||||
VkPipelineLayoutCreateInfo plci{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
|
||||
plci.setLayoutCount = 1;
|
||||
plci.pSetLayouts = &descriptorSetLayout;
|
||||
plci.pushConstantRangeCount = 1;
|
||||
plci.pPushConstantRanges = &pushRange;
|
||||
vkCreatePipelineLayout(device, &plci, nullptr, &pipelineLayout);
|
||||
|
||||
VkShaderModule vertMod = createShaderModule(vertShaderSpv, sizeof(vertShaderSpv));
|
||||
VkShaderModule fragMod = createShaderModule(fragShaderSpv, sizeof(fragShaderSpv));
|
||||
|
||||
VkPipelineShaderStageCreateInfo stages[2]{};
|
||||
stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
stages[0].module = vertMod;
|
||||
stages[0].pName = "main";
|
||||
stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
stages[1].module = fragMod;
|
||||
stages[1].pName = "main";
|
||||
|
||||
VkVertexInputBindingDescription bindingDesc{};
|
||||
bindingDesc.binding = 0;
|
||||
bindingDesc.stride = sizeof(Vertex);
|
||||
bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
VkVertexInputAttributeDescription attrs[3]{};
|
||||
attrs[0].location = 0;
|
||||
attrs[0].binding = 0;
|
||||
attrs[0].format = VK_FORMAT_R32G32_SFLOAT;
|
||||
attrs[0].offset = offsetof(Vertex, pos);
|
||||
attrs[1].location = 1;
|
||||
attrs[1].binding = 0;
|
||||
attrs[1].format = VK_FORMAT_R32G32_SFLOAT;
|
||||
attrs[1].offset = offsetof(Vertex, uv);
|
||||
attrs[2].location = 2;
|
||||
attrs[2].binding = 0;
|
||||
attrs[2].format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
attrs[2].offset = offsetof(Vertex, color);
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput{VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
|
||||
vertexInput.vertexBindingDescriptionCount = 1;
|
||||
vertexInput.pVertexBindingDescriptions = &bindingDesc;
|
||||
vertexInput.vertexAttributeDescriptionCount = 3;
|
||||
vertexInput.pVertexAttributeDescriptions = attrs;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo ia{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
|
||||
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
|
||||
VkPipelineViewportStateCreateInfo vps{VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
|
||||
vps.viewportCount = 1;
|
||||
vps.scissorCount = 1;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo raster{VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO};
|
||||
raster.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
raster.cullMode = VK_CULL_MODE_NONE;
|
||||
raster.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
raster.lineWidth = 1.0f;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo ms{VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO};
|
||||
ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkPipelineColorBlendAttachmentState blendAttachment{};
|
||||
blendAttachment.blendEnable = VK_TRUE;
|
||||
blendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
blendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
blendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
blendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo blend{VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};
|
||||
blend.attachmentCount = 1;
|
||||
blend.pAttachments = &blendAttachment;
|
||||
|
||||
VkDynamicState dynStates[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
|
||||
VkPipelineDynamicStateCreateInfo dyn{VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO};
|
||||
dyn.dynamicStateCount = 2;
|
||||
dyn.pDynamicStates = dynStates;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil{VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
|
||||
|
||||
VkGraphicsPipelineCreateInfo pci{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
|
||||
pci.stageCount = 2;
|
||||
pci.pStages = stages;
|
||||
pci.pVertexInputState = &vertexInput;
|
||||
pci.pInputAssemblyState = &ia;
|
||||
pci.pViewportState = &vps;
|
||||
pci.pRasterizationState = &raster;
|
||||
pci.pMultisampleState = &ms;
|
||||
pci.pColorBlendState = &blend;
|
||||
pci.pDynamicState = &dyn;
|
||||
pci.pDepthStencilState = &depthStencil;
|
||||
pci.layout = pipelineLayout;
|
||||
pci.renderPass = renderPass;
|
||||
pci.subpass = 0;
|
||||
|
||||
vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pci, nullptr, &pipeline);
|
||||
|
||||
vkDestroyShaderModule(device, vertMod, nullptr);
|
||||
vkDestroyShaderModule(device, fragMod, nullptr);
|
||||
}
|
||||
|
||||
void Renderer::Impl::initSampler() {
|
||||
VkSamplerCreateInfo sci{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
|
||||
sci.magFilter = VK_FILTER_LINEAR;
|
||||
sci.minFilter = VK_FILTER_LINEAR;
|
||||
sci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
sci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
sci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
sci.maxAnisotropy = 1.0f;
|
||||
sci.maxLod = 1.0f;
|
||||
vkCreateSampler(device, &sci, nullptr, &sampler);
|
||||
}
|
||||
|
||||
void Renderer::Impl::initDescriptorPool() {
|
||||
VkDescriptorPoolSize poolSize{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 256};
|
||||
VkDescriptorPoolCreateInfo dpci{VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
|
||||
dpci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||
dpci.maxSets = 256;
|
||||
dpci.poolSizeCount = 1;
|
||||
dpci.pPoolSizes = &poolSize;
|
||||
vkCreateDescriptorPool(device, &dpci, nullptr, &descriptorPool);
|
||||
}
|
||||
|
||||
void Renderer::Impl::initVertexBuffer(uint32_t count) {
|
||||
if (vertexBuffer != VK_NULL_HANDLE) {
|
||||
vkDestroyBuffer(device, vertexBuffer, nullptr);
|
||||
vkFreeMemory(device, vertexMemory, nullptr);
|
||||
}
|
||||
vertexBufferCapacity = count;
|
||||
VkBufferCreateInfo bci{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
|
||||
bci.size = sizeof(Vertex) * count;
|
||||
bci.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
vkCreateBuffer(device, &bci, nullptr, &vertexBuffer);
|
||||
|
||||
VkMemoryRequirements memReq;
|
||||
vkGetBufferMemoryRequirements(device, vertexBuffer, &memReq);
|
||||
|
||||
VkMemoryAllocateInfo mai{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
|
||||
mai.allocationSize = memReq.size;
|
||||
mai.memoryTypeIndex = findMemoryType(memReq.memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
vkAllocateMemory(device, &mai, nullptr, &vertexMemory);
|
||||
vkBindBufferMemory(device, vertexBuffer, vertexMemory, 0);
|
||||
}
|
||||
|
||||
void Renderer::Impl::uploadTextureData(TextureEntry &tex, int x, int y, int w, int h,
|
||||
const void *rgba) {
|
||||
VkDeviceSize imageSize = (VkDeviceSize)w * h * 4;
|
||||
|
||||
VkBuffer stagingBuffer;
|
||||
VkDeviceMemory stagingMemory;
|
||||
VkBufferCreateInfo bci{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
|
||||
bci.size = imageSize;
|
||||
bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
vkCreateBuffer(device, &bci, nullptr, &stagingBuffer);
|
||||
|
||||
VkMemoryRequirements memReq;
|
||||
vkGetBufferMemoryRequirements(device, stagingBuffer, &memReq);
|
||||
VkMemoryAllocateInfo mai{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
|
||||
mai.allocationSize = memReq.size;
|
||||
mai.memoryTypeIndex = findMemoryType(memReq.memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
vkAllocateMemory(device, &mai, nullptr, &stagingMemory);
|
||||
vkBindBufferMemory(device, stagingBuffer, stagingMemory, 0);
|
||||
|
||||
void *mapped;
|
||||
vkMapMemory(device, stagingMemory, 0, imageSize, 0, &mapped);
|
||||
memcpy(mapped, rgba, imageSize);
|
||||
vkUnmapMemory(device, stagingMemory);
|
||||
|
||||
VkCommandPoolCreateInfo cpci{VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO};
|
||||
cpci.queueFamilyIndex = queueFamily;
|
||||
cpci.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
|
||||
VkCommandPool tmpPool;
|
||||
vkCreateCommandPool(device, &cpci, nullptr, &tmpPool);
|
||||
|
||||
VkCommandBufferAllocateInfo abci{VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO};
|
||||
abci.commandPool = tmpPool;
|
||||
abci.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
abci.commandBufferCount = 1;
|
||||
VkCommandBuffer cmd;
|
||||
vkAllocateCommandBuffers(device, &abci, &cmd);
|
||||
|
||||
VkCommandBufferBeginInfo bbi{VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
|
||||
bbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
vkBeginCommandBuffer(cmd, &bbi);
|
||||
|
||||
bool fullImage = (x == 0 && y == 0 && w == tex.width && h == tex.height);
|
||||
|
||||
VkImageMemoryBarrier barrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
|
||||
barrier.image = tex.image;
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
|
||||
barrier.oldLayout = fullImage ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
VkBufferImageCopy region{};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageOffset = {x, y, 0};
|
||||
region.imageExtent = {(uint32_t)w, (uint32_t)h, 1};
|
||||
vkCmdCopyBufferToImage(cmd, stagingBuffer, tex.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ®ion);
|
||||
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
vkEndCommandBuffer(cmd);
|
||||
VkSubmitInfo si{VK_STRUCTURE_TYPE_SUBMIT_INFO};
|
||||
si.commandBufferCount = 1;
|
||||
si.pCommandBuffers = &cmd;
|
||||
vkQueueSubmit(graphicsQueue, 1, &si, VK_NULL_HANDLE);
|
||||
vkQueueWaitIdle(graphicsQueue);
|
||||
|
||||
vkDestroyCommandPool(device, tmpPool, nullptr);
|
||||
vkDestroyBuffer(device, stagingBuffer, nullptr);
|
||||
vkFreeMemory(device, stagingMemory, nullptr);
|
||||
}
|
||||
|
||||
int Renderer::Impl::allocTexture(int width, int height, const void *rgba) {
|
||||
TextureEntry tex{};
|
||||
tex.width = width;
|
||||
tex.height = height;
|
||||
tex.active = true;
|
||||
|
||||
VkImageCreateInfo ici{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
|
||||
ici.imageType = VK_IMAGE_TYPE_2D;
|
||||
ici.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
ici.extent = {(uint32_t)width, (uint32_t)height, 1};
|
||||
ici.mipLevels = 1;
|
||||
ici.arrayLayers = 1;
|
||||
ici.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
ici.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
ici.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
vkCreateImage(device, &ici, nullptr, &tex.image);
|
||||
|
||||
VkMemoryRequirements memReq;
|
||||
vkGetImageMemoryRequirements(device, tex.image, &memReq);
|
||||
VkMemoryAllocateInfo mai{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
|
||||
mai.allocationSize = memReq.size;
|
||||
mai.memoryTypeIndex = findMemoryType(memReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
vkAllocateMemory(device, &mai, nullptr, &tex.memory);
|
||||
vkBindImageMemory(device, tex.image, tex.memory, 0);
|
||||
|
||||
VkImageViewCreateInfo vci{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
|
||||
vci.image = tex.image;
|
||||
vci.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
vci.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
vci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
vci.subresourceRange.levelCount = 1;
|
||||
vci.subresourceRange.layerCount = 1;
|
||||
vkCreateImageView(device, &vci, nullptr, &tex.view);
|
||||
|
||||
VkDescriptorSetAllocateInfo dsai{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO};
|
||||
dsai.descriptorPool = descriptorPool;
|
||||
dsai.descriptorSetCount = 1;
|
||||
dsai.pSetLayouts = &descriptorSetLayout;
|
||||
vkAllocateDescriptorSets(device, &dsai, &tex.descriptorSet);
|
||||
|
||||
VkDescriptorImageInfo dii{};
|
||||
dii.sampler = sampler;
|
||||
dii.imageView = tex.view;
|
||||
dii.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
VkWriteDescriptorSet wds{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};
|
||||
wds.dstSet = tex.descriptorSet;
|
||||
wds.dstBinding = 0;
|
||||
wds.descriptorCount = 1;
|
||||
wds.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
wds.pImageInfo = &dii;
|
||||
vkUpdateDescriptorSets(device, 1, &wds, 0, nullptr);
|
||||
|
||||
if (rgba)
|
||||
uploadTextureData(tex, 0, 0, width, height, rgba);
|
||||
|
||||
int id = -1;
|
||||
for (int i = 0; i < (int)textures.size(); i++) {
|
||||
if (!textures[i].active) { id = i; break; }
|
||||
}
|
||||
if (id < 0) {
|
||||
id = (int)textures.size();
|
||||
textures.push_back(tex);
|
||||
} else {
|
||||
textures[id] = tex;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void Renderer::Impl::createWhiteTexture() {
|
||||
uint32_t white = 0xFFFFFFFF;
|
||||
allocTexture(1, 1, &white);
|
||||
}
|
||||
|
||||
void Renderer::Impl::addQuad(int texId, float x0, float y0, float x1, float y1,
|
||||
float u0, float v0, float u1, float v1, Color c) {
|
||||
Vertex verts[6];
|
||||
float positions[6][2] = {
|
||||
{x0, y0}, {x1, y0}, {x1, y1},
|
||||
{x0, y0}, {x1, y1}, {x0, y1}
|
||||
};
|
||||
float uvs[6][2] = {
|
||||
{u0, v0}, {u1, v0}, {u1, v1},
|
||||
{u0, v0}, {u1, v1}, {u0, v1}
|
||||
};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
float px = positions[i][0], py = positions[i][1];
|
||||
currentTransform.transformPoint(px, py);
|
||||
verts[i].pos[0] = px;
|
||||
verts[i].pos[1] = py;
|
||||
verts[i].uv[0] = uvs[i][0];
|
||||
verts[i].uv[1] = uvs[i][1];
|
||||
verts[i].color[0] = c.r;
|
||||
verts[i].color[1] = c.g;
|
||||
verts[i].color[2] = c.b;
|
||||
verts[i].color[3] = c.a;
|
||||
}
|
||||
|
||||
bool merged = false;
|
||||
if (!drawCmds.empty()) {
|
||||
auto &last = drawCmds.back();
|
||||
bool sameScissor = (!last.hasScissor && scissorStack.empty()) ||
|
||||
(last.hasScissor && !scissorStack.empty() &&
|
||||
last.scissorX == scissorStack.back().x &&
|
||||
last.scissorY == scissorStack.back().y &&
|
||||
last.scissorW == scissorStack.back().w &&
|
||||
last.scissorH == scissorStack.back().h);
|
||||
if (last.textureId == texId && sameScissor) {
|
||||
last.vertexCount += 6;
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!merged) {
|
||||
DrawCmd dc;
|
||||
dc.textureId = texId;
|
||||
dc.vertexOffset = (uint32_t)vertices.size();
|
||||
dc.vertexCount = 6;
|
||||
dc.hasScissor = !scissorStack.empty();
|
||||
if (dc.hasScissor) {
|
||||
dc.scissorX = scissorStack.back().x;
|
||||
dc.scissorY = scissorStack.back().y;
|
||||
dc.scissorW = scissorStack.back().w;
|
||||
dc.scissorH = scissorStack.back().h;
|
||||
}
|
||||
drawCmds.push_back(dc);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
vertices.push_back(verts[i]);
|
||||
}
|
||||
|
||||
} // namespace vui
|
||||
Reference in New Issue
Block a user