draw uv menu

This commit is contained in:
Ivan Avdeev 2021-01-16 13:22:31 -08:00
parent e7a99c2558
commit 48e6765222
10 changed files with 320 additions and 21 deletions

2
.gitignore vendored
View File

@ -332,3 +332,5 @@ __pycache__
.cache
compile_commands.json
cscope.out
core

View File

@ -1,5 +1,6 @@
#include "vk_2d.h"
#include "vk_buffer.h"
#include "vk_core.h"
#include "vk_common.h"
#include "vk_textures.h"
@ -11,11 +12,6 @@ void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, c
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
}
void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum )
{
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);
}
void R_DrawTileClear( int texnum, int x, int y, int w, int h )
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
@ -34,6 +30,52 @@ typedef struct vertex_2d_s {
float u, v;
} vertex_2d_t;
#define MAX_PICS 1024
static struct {
VkPipeline pipeline;
uint32_t max_pics, num_pics;
vk_buffer_t pics_buffer;
// TODO texture bindings?
} g2d;
void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum )
{
/* 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.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;
}
{
vertex_2d_t *p = ((vertex_2d_t*)(g2d.pics_buffer.mapped)) + g2d.num_pics;
const float vw = vk_core.swapchain.create_info.imageExtent.width;
const float vh = vk_core.swapchain.create_info.imageExtent.height;
const float x1 = (x / vw)*2.f - 1.f;
const float y1 = (y / vh)*2.f - 1.f;
const float x2 = ((x + w) / vw)*2.f - 1.f;
const float y2 = ((y + h) / vh)*2.f - 1.f;
g2d.num_pics += 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
}
}
static VkPipeline createPipeline( void )
{
VkVertexInputAttributeDescription attribs[] = {
@ -168,13 +210,36 @@ static VkPipeline createPipeline( void )
return pipeline;
}
void vk2dBegin( void )
{
g2d.num_pics = 0;
}
void vk2dEnd( void )
{
const VkDeviceSize offset = 0;
if (!g2d.num_pics)
return;
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);
}
qboolean initVk2d( void )
{
VkPipeline pipeline = createPipeline();
g2d.pipeline = createPipeline();
if (!createBuffer(&g2d.pics_buffer, sizeof(vertex_2d_t) * (MAX_PICS * 6),
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT ))
return false;
g2d.max_pics = MAX_PICS * 6;
return true;
}
void deinitVk2d( void )
{
// FIXME deinit stuff
}

View File

@ -10,3 +10,5 @@ void CL_FillRGBABlend( float x, float y, float w, float h, int r, int g, int b,
qboolean initVk2d( void );
void deinitVk2d( void );
void vk2dBegin( void );
void vk2dEnd( void );

49
ref_vk/vk_buffer.c Normal file
View File

@ -0,0 +1,49 @@
#include "vk_buffer.h"
#include <memory.h>
uint32_t findMemoryWithType(uint32_t type_index_bits, VkMemoryPropertyFlags flags) {
for (uint32_t i = 0; i < vk_core.physical_device.memory_properties.memoryTypeCount; ++i) {
if (!(type_index_bits & (1 << i)))
continue;
if ((vk_core.physical_device.memory_properties.memoryTypes[i].propertyFlags & flags) == flags)
return i;
}
return UINT32_MAX;
}
qboolean createBuffer(vk_buffer_t *buf, uint32_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags flags)
{
VkBufferCreateInfo bci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VkMemoryAllocateInfo mai = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
};
VkMemoryRequirements memreq;
XVK_CHECK(vkCreateBuffer(vk_core.device, &bci, NULL, &buf->buffer));
vkGetBufferMemoryRequirements(vk_core.device, buf->buffer, &memreq);
gEngine.Con_Reportf("memreq: memoryTypeBits=0x%x alignment=%zu size=%zu", memreq.memoryTypeBits, memreq.alignment, memreq.size);
mai.allocationSize = memreq.size;
mai.memoryTypeIndex = findMemoryWithType(memreq.memoryTypeBits, flags);
XVK_CHECK(vkAllocateMemory(vk_core.device, &mai, NULL, &buf->device_memory));
XVK_CHECK(vkBindBufferMemory(vk_core.device, buf->buffer, buf->device_memory, 0));
XVK_CHECK(vkMapMemory(vk_core.device, buf->device_memory, 0, bci.size, 0, &buf->mapped));
return true;
}
void destroyBuffer(vk_buffer_t *buf) {
vkUnmapMemory(vk_core.device, buf->device_memory);
vkDestroyBuffer(vk_core.device, buf->buffer, NULL);
vkFreeMemory(vk_core.device, buf->device_memory, NULL);
memset(buf, 0, sizeof(*buf));
}

17
ref_vk/vk_buffer.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "vk_core.h"
typedef struct vk_buffer_s
{
// TODO coalesce allocations
VkDeviceMemory device_memory;
VkBuffer buffer;
void *mapped;
uint32_t size;
} vk_buffer_t;
qboolean createBuffer(vk_buffer_t *buf, uint32_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags flags);
void destroyBuffer(vk_buffer_t *buf);

View File

@ -2,6 +2,7 @@
#include "vk_common.h"
#include "vk_textures.h"
#include "vk_2d.h"
#include "vk_renderstate.h"
#include "xash3d_types.h"
#include "cvardef.h"
@ -373,8 +374,8 @@ static qboolean createRenderPass( void ) {
VkAttachmentDescription attachments[] = {{
.format = VK_FORMAT_B8G8R8A8_SRGB,// FIXME too early swapchain.create_info.imageFormat;
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
//.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
//.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
@ -621,6 +622,9 @@ qboolean R_VkInit( void )
if (!initVk2d())
return false;
if (!renderstateInit())
return false;
initTextures();
return true;
@ -628,6 +632,8 @@ qboolean R_VkInit( void )
void R_VkShutdown( void )
{
renderstateDestroy();
deinitVk2d();
vkDestroySwapchainKHR(vk_core.device, vk_core.swapchain.swapchain, NULL);
@ -671,3 +677,31 @@ VkShaderModule loadShader(const char *filename) {
Mem_Free(buf);
return shader;
}
VkSemaphore createSemaphore( void ) {
VkSemaphore sema;
VkSemaphoreCreateInfo sci = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.flags = 0,
};
XVK_CHECK(vkCreateSemaphore(vk_core.device, &sci, NULL, &sema));
return sema;
}
void destroySemaphore(VkSemaphore sema) {
vkDestroySemaphore(vk_core.device, sema, NULL);
}
VkFence createFence( void ) {
VkFence fence;
VkFenceCreateInfo fci = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = 0,
};
XVK_CHECK(vkCreateFence(vk_core.device, &fci, NULL, &fence));
return fence;
}
void destroyFence(VkFence fence) {
vkDestroyFence(vk_core.device, fence, NULL);
}

View File

@ -1,4 +1,8 @@
#pragma once
#include "vk_common.h"
#include "xash3d_types.h"
#include "com_strings.h" // S_ERROR
#define VK_NO_PROTOTYPES
#include <vulkan/vulkan.h>
@ -8,6 +12,10 @@ void R_VkShutdown( void );
// FIXME load from embedded static structs
VkShaderModule loadShader(const char *filename);
VkSemaphore createSemaphore( void );
void destroySemaphore(VkSemaphore sema);
VkFence createFence( void );
void destroyFence(VkFence fence);
typedef struct physical_device_s {
VkPhysicalDevice device;
@ -73,6 +81,31 @@ const char *resultName(VkResult result);
X(vkCreateShaderModule) \
X(vkCreateCommandPool) \
X(vkAllocateCommandBuffers) \
X(vkCreateBuffer) \
X(vkGetBufferMemoryRequirements) \
X(vkAllocateMemory) \
X(vkBindBufferMemory) \
X(vkMapMemory) \
X(vkUnmapMemory) \
X(vkDestroyBuffer) \
X(vkFreeMemory) \
X(vkAcquireNextImageKHR) \
X(vkCmdBeginRenderPass) \
X(vkCmdExecuteCommands) \
X(vkCmdEndRenderPass) \
X(vkEndCommandBuffer) \
X(vkQueueSubmit) \
X(vkQueuePresentKHR) \
X(vkWaitForFences) \
X(vkResetFences) \
X(vkCreateSemaphore) \
X(vkDestroySemaphore) \
X(vkCreateFence) \
X(vkDestroyFence) \
X(vkBeginCommandBuffer) \
X(vkCmdBindPipeline) \
X(vkCmdBindVertexBuffers) \
X(vkCmdDraw) \
#define X(f) extern PFN_##f f;
DEVICE_FUNCS(X)

View File

@ -1,7 +1,13 @@
#include "vk_renderstate.h"
#include "vk_2d.h"
#include "vk_core.h"
#include "cvardef.h"
#include "const.h"
#include "ref_api.h"
#include "com_strings.h"
#include "eiface.h" // ARRAYSIZE
extern ref_api_t gEngine;
extern ref_globals_t *gpGlobals;
@ -15,6 +21,13 @@ typedef struct render_state_s {
int blending_mode; // kRenderNormal, ...
} render_state_t;
static struct
{
VkSemaphore image_available;
VkSemaphore done;
VkFence fence;
} grs;
render_state_t render_state = {0};
static const char *renderModeName(int mode)
@ -38,7 +51,7 @@ void GL_SetRenderMode( int renderMode )
render_state.blending_mode = renderMode;
}
void TriColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
void TriColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a )
{
//gEngine.Con_Printf(S_WARN "VK FIXME: %s(%d, %d, %d, %d)\n", __FUNCTION__, (int)r, (int)g, (int)b, (int)a);
@ -56,3 +69,93 @@ void R_Set2DMode( qboolean enable )
//gEngine.Con_Printf(S_WARN "VK FIXME: %s(%d)\n", __FUNCTION__, enable);
render_state.mode_2d = enable;
}
void R_BeginFrame( qboolean clearScene )
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s(%d)\n", __FUNCTION__, clearScene);
vk2dBegin();
}
void R_RenderScene( void )
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
}
void R_EndFrame( void )
{
//gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
uint32_t swapchain_image_index;
VkClearValue clear_value[] = {
{.color = {{1., 0., 0., 0.}}},
//{.depthStencil = {1., 0.}}
};
VkRenderPassBeginInfo rpbi = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = vk_core.render_pass,
.renderArea.extent.width = vk_core.swapchain.create_info.imageExtent.width,
.renderArea.extent.height = vk_core.swapchain.create_info.imageExtent.height,
.clearValueCount = ARRAYSIZE(clear_value),
.pClearValues = clear_value,
};
VkPipelineStageFlags stageflags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo subinfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = NULL,
.commandBufferCount = 1,
.pCommandBuffers = &vk_core.cb,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &grs.image_available,
.signalSemaphoreCount = 1,
.pSignalSemaphores = &grs.done,
.pWaitDstStageMask = &stageflags,
};
VkPresentInfoKHR presinfo = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pSwapchains = &vk_core.swapchain.swapchain,
.pImageIndices = &swapchain_image_index,
.swapchainCount = 1,
.pWaitSemaphores = &grs.done,
.waitSemaphoreCount = 1,
};
XVK_CHECK(vkAcquireNextImageKHR(vk_core.device, vk_core.swapchain.swapchain, UINT64_MAX, grs.image_available,
VK_NULL_HANDLE, &swapchain_image_index));
rpbi.framebuffer = vk_core.swapchain.framebuffers[swapchain_image_index];
{
VkCommandBufferBeginInfo beginfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
};
XVK_CHECK(vkBeginCommandBuffer(vk_core.cb, &beginfo));
}
vkCmdBeginRenderPass(vk_core.cb, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
vk2dEnd();
vkCmdEndRenderPass(vk_core.cb);
XVK_CHECK(vkEndCommandBuffer(vk_core.cb));
XVK_CHECK(vkQueueSubmit(vk_core.queue, 1, &subinfo, grs.fence));
XVK_CHECK(vkQueuePresentKHR(vk_core.queue, &presinfo));
// TODO bad sync
XVK_CHECK(vkWaitForFences(vk_core.device, 1, &grs.fence, VK_TRUE, INT64_MAX));
XVK_CHECK(vkResetFences(vk_core.device, 1, &grs.fence));
}
qboolean renderstateInit( void )
{
grs.image_available = createSemaphore();
grs.done = createSemaphore();
grs.fence = createFence();
return true;
}
void renderstateDestroy( void )
{
}

View File

@ -6,3 +6,9 @@ void GL_SetRenderMode( int renderMode );
void TriColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a );
void R_AllowFog( qboolean allow );
void R_Set2DMode( qboolean enable );
void R_BeginFrame( qboolean clearScene );
void R_RenderScene( void );
void R_EndFrame( void );
qboolean renderstateInit( void );
void renderstateDestroy( void );

View File

@ -38,18 +38,6 @@ void GL_ClearExtensions( void )
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
}
void R_BeginFrame( qboolean clearScene )
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s(%d)\n", __FUNCTION__, clearScene);
}
void R_RenderScene( void )
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
}
void R_EndFrame( void )
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
}
void R_PushScene( void )
{
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);