get it to crappily draw 2d ui menus wtf

This commit is contained in:
Ivan Avdeev 2021-01-16 17:02:43 -08:00
parent 5541bfb541
commit 4d6739da0a
5 changed files with 186 additions and 47 deletions

View File

@ -1,9 +1,11 @@
#version 450
layout(set=0,binding=0) uniform sampler2D tex;
layout(location = 0) in vec2 vUv;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(vUv, 0., 1.);
outColor = texture(tex, vUv);
}

View File

@ -30,14 +30,23 @@ typedef struct vertex_2d_s {
float u, v;
} vertex_2d_t;
// TODO should these be dynamic?
#define MAX_PICS 4096
#define MAX_BATCHES 64
static struct {
VkPipelineLayout pipeline_layout;
VkPipeline pipeline;
uint32_t max_pics, num_pics;
vk_buffer_t pics_buffer;
struct {
uint32_t vertex_offset, vertex_count;
int texture;
} batch[MAX_BATCHES];
uint32_t current_batch;
// TODO texture bindings?
} g2d;
@ -46,9 +55,26 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f
/* gEngine.Con_Printf(S_WARN "VK FIXME: %s(%f, %f, %f, %f, %f, %f, %f, %f, %d(%s))\n", __FUNCTION__, */
/* x, y, w, h, s1, t1, s2, t2, texnum, findTexture(texnum)->name); */
if (g2d.batch[g2d.current_batch].texture != texnum)
{
if (g2d.batch[g2d.current_batch].vertex_count != 0)
{
if (g2d.current_batch == MAX_BATCHES - 1)
{
gEngine.Con_Printf(S_WARN "VK FIXME RAN OUT OF BATCHES: %s(%f, %f, %f, %f, %f, %f, %f, %f, %d(%s))\n", __FUNCTION__,
x, y, w, h, s1, t1, s2, t2, texnum, findTexture(texnum)->name);
return;
}
++g2d.current_batch;
}
g2d.batch[g2d.current_batch].texture = texnum;
g2d.batch[g2d.current_batch].vertex_offset = g2d.num_pics;
}
if (g2d.num_pics + 6 > g2d.max_pics)
{
//drawAccumulated();
gEngine.Con_Printf(S_WARN "VK FIXME RAN OUT OF BUFFER: %s(%f, %f, %f, %f, %f, %f, %f, %f, %d(%s))\n", __FUNCTION__,
x, y, w, h, s1, t1, s2, t2, texnum, findTexture(texnum)->name);
return;
@ -65,14 +91,13 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f
const float y2 = ((y + h) / vh)*2.f - 1.f;
g2d.num_pics += 6;
g2d.batch[g2d.current_batch].vertex_count += 6; // ....
p[0] = (vertex_2d_t){x1, y1, s1, t1};
p[1] = (vertex_2d_t){x1, y2, s1, t2};
p[2] = (vertex_2d_t){x2, y1, s2, t1};
p[3] = (vertex_2d_t){x2, y1, s2, t1};
p[4] = (vertex_2d_t){x1, y2, s1, t2};
p[5] = (vertex_2d_t){x2, y2, s2, t2};
// TODO store texture
}
}
@ -186,16 +211,17 @@ static VkPipeline createPipeline( void )
/* .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, */
/* }; */
/* VkDescriptorSetLayout descriptor_layouts[] = { */
VkDescriptorSetLayout descriptor_layouts[] = {
vk_core.descriptor_pool.one_texture_layout,
/* g.descriptors[Descriptors_Global]->layout, */
/* g.descriptors[Descriptors_Lightmaps]->layout, */
/* g.descriptors[Descriptors_Textures]->layout, */
/* }; */
};
VkPipelineLayoutCreateInfo plci = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
/* .setLayoutCount = COUNTOF(descriptor_layouts), */
/* .pSetLayouts = descriptor_layouts, */
.setLayoutCount = ARRAYSIZE(descriptor_layouts),
.pSetLayouts = descriptor_layouts,
/* .pushConstantRangeCount = 1, */
/* .pPushConstantRanges = &push_const, */
};
@ -203,12 +229,11 @@ static VkPipeline createPipeline( void )
VkPipeline pipeline;
// FIXME store layout separately
XVK_CHECK(vkCreatePipelineLayout(vk_core.device, &plci, NULL, &gpci.layout));
XVK_CHECK(vkCreatePipelineLayout(vk_core.device, &plci, NULL, &g2d.pipeline_layout));
gpci.layout = g2d.pipeline_layout;
XVK_CHECK(vkCreateGraphicsPipelines(vk_core.device, VK_NULL_HANDLE, 1, &gpci, NULL, &pipeline));
vkDestroyPipelineLayout(vk_core.device, gpci.layout, NULL);
for (int i = 0; i < (int)ARRAYSIZE(shader_stages); ++i)
vkDestroyShaderModule(vk_core.device, shader_stages[i].module, NULL);
@ -218,6 +243,7 @@ static VkPipeline createPipeline( void )
void vk2dBegin( void )
{
g2d.num_pics = 0;
g2d.current_batch = 0;
}
void vk2dEnd( void )
@ -228,7 +254,15 @@ void vk2dEnd( void )
vkCmdBindPipeline(vk_core.cb, VK_PIPELINE_BIND_POINT_GRAPHICS, g2d.pipeline);
vkCmdBindVertexBuffers(vk_core.cb, 0, 1, &g2d.pics_buffer.buffer, &offset);
vkCmdDraw(vk_core.cb, g2d.num_pics, 1, 0, 0);
for (int i = 0; i <= g2d.current_batch; ++i)
{
vk_texture_t *texture = findTexture(g2d.batch[i].texture);
if (texture->vk.descriptor)
vkCmdBindDescriptorSets(vk_core.cb, VK_PIPELINE_BIND_POINT_GRAPHICS, g2d.pipeline_layout, 0, 1, &texture->vk.descriptor, 0, NULL);
// FIXME else what?
vkCmdDraw(vk_core.cb, g2d.batch[i].vertex_count, 1, g2d.batch[i].vertex_offset, 0);
}
}
qboolean initVk2d( void )
@ -248,4 +282,5 @@ void deinitVk2d( void )
{
destroyBuffer(&g2d.pics_buffer);
vkDestroyPipeline(vk_core.device, g2d.pipeline, NULL);
vkDestroyPipelineLayout(vk_core.device, g2d.pipeline_layout, NULL);
}

View File

@ -563,6 +563,72 @@ static qboolean createCommandPool( void ) {
return true;
}
// ... FIXME actual numbers
#define MAX_TEXTURES 4096
static qboolean initDescriptorPool( void )
{
VkDescriptorPoolSize dps[] = {
{
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = MAX_TEXTURES,
/*
}, {
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
}, {
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = 1,
#if RTX
}, {
.type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
.descriptorCount = 1,
#endif
*/
},
};
VkDescriptorPoolCreateInfo dpci = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pPoolSizes = dps,
.poolSizeCount = ARRAYSIZE(dps),
.maxSets = MAX_TEXTURES,
};
XVK_CHECK(vkCreateDescriptorPool(vk_core.device, &dpci, NULL, &vk_core.descriptor_pool.pool));
{
// ... TODO find better place for this; this should be per-pipeline/shader
VkDescriptorSetLayoutBinding bindings[] = { {
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.pImmutableSamplers = &vk_core.default_sampler,
}};
VkDescriptorSetLayoutCreateInfo dslci = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = ARRAYSIZE(bindings),
.pBindings = bindings,
};
VkDescriptorSetLayout* tmp_layouts = Mem_Malloc(vk_core.pool, sizeof(VkDescriptorSetLayout) * MAX_DESC_SETS);
VkDescriptorSetAllocateInfo dsai = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = vk_core.descriptor_pool.pool,
.descriptorSetCount = MAX_DESC_SETS,
.pSetLayouts = tmp_layouts,
};
XVK_CHECK(vkCreateDescriptorSetLayout(vk_core.device, &dslci, NULL, &vk_core.descriptor_pool.one_texture_layout));
for (int i = 0; i < (int)MAX_DESC_SETS; ++i)
tmp_layouts[i] = vk_core.descriptor_pool.one_texture_layout;
XVK_CHECK(vkAllocateDescriptorSets(vk_core.device, &dsai, vk_core.descriptor_pool.sets));
Mem_Free(tmp_layouts);
}
return true;
}
qboolean R_VkInit( void )
{
vk_core.debug = !!(gEngine.Sys_CheckParm("-vkdebug") || gEngine.Sys_CheckParm("-gldebug"));
@ -622,7 +688,29 @@ qboolean R_VkInit( void )
return false;
// TODO initAllocator()
// TODO initPipelines()
{
VkSamplerCreateInfo sci = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.magFilter = VK_FILTER_LINEAR,
.minFilter = VK_FILTER_LINEAR,
.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.anisotropyEnable = VK_FALSE,
.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
.unnormalizedCoordinates = VK_FALSE,
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
.minLod = 0.f,
.maxLod = 16.,
};
XVK_CHECK(vkCreateSampler(vk_core.device, &sci, NULL, &vk_core.default_sampler));
}
if (!initDescriptorPool())
return false;
initTextures();
if (!initVk2d())
return false;
@ -630,8 +718,6 @@ qboolean R_VkInit( void )
if (!renderstateInit())
return false;
initTextures();
return true;
}
@ -641,6 +727,8 @@ void R_VkShutdown( void )
renderstateDestroy();
deinitVk2d();
vkDestroyDescriptorPool(vk_core.device, vk_core.descriptor_pool.pool, NULL);
vkDestroySampler(vk_core.device, vk_core.default_sampler, NULL);
destroyBuffer(&vk_core.staging);
vkDestroyCommandPool(vk_core.device, vk_core.command_pool, NULL);

View File

@ -42,6 +42,18 @@ typedef struct physical_device_s {
VkPhysicalDeviceProperties properties;
} physical_device_t;
// FIXME dynamic; better estimate
#define MAX_DESC_SETS 4096
typedef struct descriptor_pool_s
{
VkDescriptorPool pool;
int next_free;
//uint32_t *free_set;
VkDescriptorSet sets[MAX_DESC_SETS];
VkDescriptorSetLayout one_texture_layout;
} descriptor_pool_t;
typedef struct vulkan_core_s {
uint32_t vulkan_version;
VkInstance instance;
@ -72,6 +84,9 @@ typedef struct vulkan_core_s {
VkCommandBuffer cb;
vk_buffer_t staging;
VkSampler default_sampler;
descriptor_pool_t descriptor_pool;
} vulkan_core_t;
extern vulkan_core_t vk_core;
@ -138,9 +153,16 @@ const char *resultName(VkResult result);
X(vkBindImageMemory) \
X(vkCmdPipelineBarrier) \
X(vkCmdCopyBufferToImage) \
X(vkUpdateDescriptorSets) \
X(vkQueueWaitIdle) \
X(vkDestroyImage) \
X(vkCmdBindDescriptorSets) \
X(vkCreateSampler) \
X(vkDestroySampler) \
X(vkCreateDescriptorPool) \
X(vkDestroyDescriptorPool) \
X(vkCreateDescriptorSetLayout) \
X(vkAllocateDescriptorSets) \
X(vkUpdateDescriptorSets) \
#define X(f) extern PFN_##f f;
DEVICE_FUNCS(X)

View File

@ -7,6 +7,7 @@
#include "crtlib.h"
#include "crclib.h"
#include "com_strings.h"
#include "eiface.h"
#include <memory.h>
#include <math.h>
@ -435,39 +436,30 @@ static qboolean VK_UploadTexture(vk_texture_t *tex, rgbdata_t *pic)
XVK_CHECK(vkCreateImageView(vk_core.device, &ivci, NULL, &tex->vk.image_view));
}
/*
VkDescriptorSet set = NULL;
// TODO how should we approach this:
// - per-texture desc sets can be inconvenient if texture is used in different incompatible contexts
// - update descriptor sets in batch?
if (vk_core.descriptor_pool.next_free != MAX_DESC_SETS)
{
struct DescriptorKasha* descriptors = NULL;
uint32_t binding;
switch (params.kind) {
case RTexKind_Lightmap:
descriptors = g.descriptors[Descriptors_Lightmaps];
binding = DescriptorBinding_Lightmap; break;
case RTexKind_Material0:
descriptors = g.descriptors[Descriptors_Textures];
binding = DescriptorBinding_BaseMaterialTexture; break;
default:
ATTO_ASSERT(!"Unexpected texture kind");
}
ATTO_ASSERT(descriptors->count > descriptors->next_free);
set = descriptors->descriptors[descriptors->next_free++];
VkDescriptorImageInfo dii_tex = {
.imageView = imview,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet wds[] = { {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = set,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &dii_tex,
}};
vkUpdateDescriptorSets(vk_core.device, COUNTOF(wds), wds, 0, NULL);
VkDescriptorImageInfo dii_tex = {
.imageView = tex->vk.image_view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet wds[] = { {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &dii_tex,
}};
wds[0].dstSet = tex->vk.descriptor = vk_core.descriptor_pool.sets[vk_core.descriptor_pool.next_free++];
vkUpdateDescriptorSets(vk_core.device, ARRAYSIZE(wds), wds, 0, NULL);
}
else
{
tex->vk.descriptor = VK_NULL_HANDLE;
}
*/
return true;
}