[vulkan] Make a start on the 2D pipeline

Short wrappers for Draw functins are in vid_render_vulkan.c so the
vulkan context can be passed on to the actual functions. The 2D shaders
are set up similar to those in glsl, but with full 32-bit color (rgba)
support instead of paletted. However, the textures are not loaded yet,
nor is anything bound.
This commit is contained in:
Bill Currie 2021-01-10 15:52:27 +09:00
parent fed7149508
commit ba6450d0b4
13 changed files with 742 additions and 158 deletions

237
include/QF/Vulkan/draw.h Normal file
View file

@ -0,0 +1,237 @@
/*
draw.h
Video buffer handling definitions and prototypes
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef __QF_draw_h
#define __QF_draw_h
/** \defgroup video Video Sub-sytem */
/** \defgroup video_renderer Renderer Sub-system
\ingroup video
*/
/** \defgroup video_renderer_draw Generic draw functions
\ingroup video_renderer
*/
///@{
#include "QF/wad.h"
extern byte *draw_chars;
/** Initialize the draw stuff.
*/
void Draw_Init (void);
/** Draws one 8*8 graphics character with 0 being transparent.
It can be clipped to the top of the screen to allow the console to be
smoothly scrolled off.
\param x horizontal location of the top left corner of the character.
\param y vertical location of the top left corner of the character.
\param ch 8 bit character to draw.
\note The character drawn is from the quake character set, which is
(by default) standard ascii for 0x20-0x7e (white). 0xa0-0xfe is
also standard ascii (brown). 0x01-0x1f and 0x80-0x9f are
various drawing characters, and 0x7f is a backwards arrow.
*/
void Draw_Character (int x, int y, unsigned ch);
/** Draws a character string to the screen.
No line wrapping is performed.
\param x horizontal location of the top left corner of the character.
\param y vertical location of the top left corner of the character.
\param str 8 bit character string to draw.
\note See Draw_Character() for character set description.
String is normal nul terminated C string.
*/
void Draw_String (int x, int y, const char *str);
/** Draws a character sub-string to the screen.
No line wrapping is performed.
\param x horizontal location of the top left corner of the character.
\param y vertical location of the top left corner of the character.
\param str 8 bit character string to draw.
\param count Maximum characters of the string to draw.
\note See Draw_Character() for character set description.
Draws up to \p count characters, or stops at the first nul
character.
*/
void Draw_nString (int x, int y, const char *str, int count);
/** Draws a character string to the screen.
No line wrapping is performed.
\param x horizontal location of the top left corner of the character.
\param y vertical location of the top left corner of the character.
\param str 8 bit character string to draw.
\note See Draw_Character() for character set description.
String is normal nul terminated C string.
Characters of the string are forced to have their high bit set
(ie, they will be in the range 0x80-0xff).
*/
void Draw_AltString (int x, int y, const char *str);
/** Draw the console background with various optional effects.
\param lines Vertical size in pixels of the console.
\param alpha Console transparency level (255 = opaque).
\note \p alpha is effective only in the OpenGL renderer. Effectively
255 (opaque) for the software renderer.
\c gl_conspin causes the background to spin.
\c gl_constretch causes the background to stretch rather than slide.
*/
void Draw_ConsoleBackground (int lines, byte alpha);
/** Draw a crosshair at the center of the screen.
\c crosshair specifies which crosshair (1 = '+', 2 = large 'x' shape,
3 = fancy '+' shape)
\c cl_crossx and \c cl_crossy offset the crosshair from the center of the
screen.
*/
void Draw_Crosshair (void);
/** Draw the specified crosshair on the screen.
\param ch crosshair to draw
\param x horizontal position of the center of the crosshair.
\param y vertical position of the center of the crosshair.
See Draw_Crosshair() for description of crosshair values.
*/
void Draw_CrosshairAt (int ch, int x, int y);
/** Clear a rectangle with a tiled background.
\param x horizontal position of the upper left corner of the rectangle
\param y horizontal position of the upper left corner of the rectangle
\param w width of the rectangle
\param h height of the rectangle
The background used is the "backtile" WAD lump.
*/
void Draw_TileClear (int x, int y, int w, int h);
/** Clear a rectangle with a solid color.
\param x horizontal position of the upper left corner of the rectangle
\param y horizontal position of the upper left corner of the rectangle
\param w width of the rectangle
\param h height of the rectangle
\param c 8 bit color index.
The color comes from the quake palette.
*/
void Draw_Fill (int x, int y, int w, int h, int c);
/** Draw a text box on the screen
\param x horizontal location of the upper left corner of the box
\param y vertical location of the upper left corner of the box
\param width horizontal size in character cells of the region
\param lines vertical size in character cells of the region
\param alpha transparency of the box
*/
void Draw_TextBox (int x, int y, int width, int lines, byte alpha);
/** Darken the screen.
*/
void Draw_FadeScreen (void);
/** Shift the screen colors.
*/
void Draw_BlendScreen (quat_t color);
///@}
/** \defgroup video_renderer_draw_qpic QPic functions
\ingroup video_renderer_draw
*/
///@{
/** Load a qpic from the filesystem.
\param path path of the file within the quake filesystem
\param alpha transparency level of the pic.
\return pointer qpic data.
\note Up to MAX_CACHED_PICS qpics can be loaded at a time this way
*/
qpic_t *Draw_CachePic (const char *path, qboolean alpha);
/** Remove a qpic from the qpic cache.
This affects only those qpics that were loaded via Draw_CachePic.
\param path path of the file within the quake filesystem
*/
void Draw_UncachePic (const char *path);
/** Create a qpic from raw data.
\param width The width of the pic.
\param height The height of the pic.
\param data The raw data bytes. The system palette will be used for
colors.
\return pointer qpic data.
*/
qpic_t *Draw_MakePic (int width, int height, const byte *data);
/** Destroy a qpic created by Draw_MakePic.
\param pic The qpic to destory.
*/
void Draw_DestroyPic (qpic_t *pic);
/** Load a qpic from gfx.wad.
\param name name of the was lump to load
\return pointer qpic data.
*/
qpic_t *Draw_PicFromWad (const char *name);
/** Draw a qpic to the screen
\param x horizontal location of the upper left corner of the qpic
\param y vertical location of the upper left corner of the qpic
\param pic qpic to draw
*/
void Draw_Pic (int x, int y, qpic_t *pic);
/** Draw a qpic to the screen
\param x horizontal location of the upper left corner of the qpic
\param y vertical location of the upper left corner of the qpic
\param pic qpic to draw
*/
void Draw_Picf (float x, float y, qpic_t *pic);
/** Draw a sub-region of a qpic to the screan
\param x horizontal screen location of the upper left corner of the
sub-region
\param y vertical screen location of the upper left corner of the
sub-region
\param pic qpic to draw
\param srcx horizontal qpic location of the upper left corner of the
sub-region
\param srcy vertical qpic location of the upper left corner of the
sub-region
\param width horizontal size of the sub-region to be drawn
\param height vertical size of the sub-region to be drawn
*/
void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height);
///@}
#endif//__QF_draw_h

View file

@ -25,13 +25,49 @@
*/
#ifndef __gl_draw_h
#define __gl_draw_h
#ifndef __QF_Vulkan_qf_draw_h
#define __QF_Vulkan_qf_draw_h
void Vulkan_Set2D (void);
void Vulkan_Set2DScaled (void);
void Vulkan_End2D (void);
void Vulkan_DrawReset (void);
void Vulkan_FlushText (void);
struct vulkan_ctx_s;
#endif//__gl_draw_h
void Vulkan_Draw_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Character (int x, int y, unsigned ch,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_String (int x, int y, const char *str,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_nString (int x, int y, const char *str, int count,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_AltString (int x, int y, const char *str,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_ConsoleBackground (int lines, byte alpha,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Crosshair (struct vulkan_ctx_s *ctx);
void Vulkan_Draw_CrosshairAt (int ch, int x, int y, struct vulkan_ctx_s *ctx);
void Vulkan_Draw_TileClear (int x, int y, int w, int h,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Fill (int x, int y, int w, int h, int c,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_FadeScreen (struct vulkan_ctx_s *ctx);
void Vulkan_Draw_BlendScreen (quat_t color, struct vulkan_ctx_s *ctx);
qpic_t *Vulkan_Draw_CachePic (const char *path, qboolean alpha,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_UncachePic (const char *path, struct vulkan_ctx_s *ctx);
qpic_t *Vulkan_Draw_MakePic (int width, int height, const byte *data,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_DestroyPic (qpic_t *pic, struct vulkan_ctx_s *ctx);
qpic_t *Vulkan_Draw_PicFromWad (const char *name, struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Pic (int x, int y, qpic_t *pic, struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Picf (float x, float y, qpic_t *pic, struct vulkan_ctx_s *ctx);
void Vulkan_Draw_SubPic(int x, int y, qpic_t *pic,
int srcx, int srcy, int width, int height,
struct vulkan_ctx_s *ctx);
void Vulkan_Set2D (struct vulkan_ctx_s *ctx);
void Vulkan_Set2DScaled (struct vulkan_ctx_s *ctx);
void Vulkan_End2D (struct vulkan_ctx_s *ctx);
void Vulkan_DrawReset (struct vulkan_ctx_s *ctx);
void Vulkan_FlushText (struct vulkan_ctx_s *ctx);
#endif//__QF_Vulkan_qf_draw_h

View file

@ -40,7 +40,7 @@ void Vulkan_DestroyFramebuffers (struct vulkan_ctx_s *ctx);
void Vulkan_CreateFramebuffers (struct vulkan_ctx_s *ctx);
void Vulkan_CreateRenderPass (struct vulkan_ctx_s *ctx);
void Vulkan_DestroyRenderPass (struct vulkan_ctx_s *ctx);
void Vulkan_CreatePipelines (struct vulkan_ctx_s *ctx);
VkPipeline Vulkan_CreatePipeline (struct vulkan_ctx_s *ctx, const char *name);
void Vulkan_CreateSwapchain (struct vulkan_ctx_s *ctx);
void Vulkan_CreateDevice (struct vulkan_ctx_s *ctx);
void Vulkan_Init_Common (struct vulkan_ctx_s *ctx);

View file

@ -20,6 +20,8 @@ typedef struct vulkan_framebuffer_s {
VkSemaphore imageAvailableSemaphore;
VkSemaphore renderDoneSemaphore;
VkCommandBuffer cmdBuffer;
VkDescriptorSet twodDescriptors;
} vulkan_framebuffer_t;
typedef struct vulkan_framebufferset_s
@ -49,6 +51,7 @@ typedef struct vulkan_ctx_s {
struct hashtab_s *setLayouts;
struct hashtab_s *pipelineLayouts;
struct hashtab_s *descriptorPools;
struct hashtab_s *samplers;
VkCommandPool cmdpool;
VkCommandBuffer cmdbuffer;

View file

@ -213,7 +213,7 @@ libs_video_renderer_vid_render_vulkan_la_LDFLAGS= $(plugin_ldflags)
libs_video_renderer_vid_render_vulkan_la_LIBADD= $(vulkan_libs)
libs_video_renderer_vid_render_vulkan_la_DEPENDENCIES=$(vulkan_libs)
libs_video_renderer_vid_render_vulkan_la_SOURCES = \
$(common_sources) \
$(video_renderer_common_sources) \
libs/video/renderer/vid_render_vulkan.c \
libs/video/renderer/vulkan/buffer.c \
libs/video/renderer/vulkan/command.c \
@ -249,16 +249,26 @@ vkparse_src = \
vkparse_plist = \
$(srcdir)/libs/video/renderer/vulkan/vkparse.plist
twodv_src = libs/video/renderer/vulkan/twod.vert
twodv_c = libs/video/renderer/vulkan/twod.vert.spvc
twodf_src = libs/video/renderer/vulkan/twod.frag
twodf_c = libs/video/renderer/vulkan/twod.frag.spvc
passthrough_src = libs/video/renderer/vulkan/passthrough.vert
passthrough_c = libs/video/renderer/vulkan/passthrough.vert.spvc
pushcolor_src = libs/video/renderer/vulkan/pushcolor.frag
pushcolor_c = libs/video/renderer/vulkan/pushcolor.frag.spvc
$(twodv_c): $(twodv_src)
$(twodf_c): $(twodf_src)
$(passthrough_c): $(passthrough_src)
$(pushcolor_c): $(pushcolor_src)
vkshader_c = \
$(twodv_c) \
$(twodf_c) \
$(passthrough_c) \
$(pushcolor_c)

View file

@ -39,6 +39,7 @@
#include "QF/plugin/general.h"
#include "QF/plugin/vid_render.h"
#include "QF/Vulkan/qf_draw.h"
#include "QF/Vulkan/qf_vid.h"
#include "QF/Vulkan/command.h"
#include "QF/Vulkan/device.h"
@ -66,7 +67,8 @@ vulkan_R_Init (void)
Vulkan_CreateFramebuffers (vulkan_ctx);
// FIXME this should be staged so screen updates can begin while pipelines
// are being built
Vulkan_CreatePipelines (vulkan_ctx);
vulkan_ctx->pipeline = Vulkan_CreatePipeline (vulkan_ctx, "pipeline");
Vulkan_Draw_Init (vulkan_ctx);
qfv_swapchain_t *sc = vulkan_ctx->swapchain;
@ -81,7 +83,7 @@ vulkan_R_Init (void)
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 0,
vulkan_ctx->renderpass.renderpass, 0,
{ {0, 0}, sc->extent },
2, clearValues
2, clearValues + 2
};
for (size_t i = 0; i < vulkan_ctx->framebuffers.size; i++) {
__auto_type framebuffer = &vulkan_ctx->framebuffers.a[i];
@ -153,18 +155,124 @@ vulkan_SCR_UpdateScreen (double time, void (*f)(void), void (**g)(void))
}
}
static void
vulkan_Draw_Character (int x, int y, unsigned ch)
{
Vulkan_Draw_Character (x, y, ch, vulkan_ctx);
}
static void
vulkan_Draw_String (int x, int y, const char *str)
{
Vulkan_Draw_String (x, y, str, vulkan_ctx);
}
static void
vulkan_Draw_nString (int x, int y, const char *str, int count)
{
Vulkan_Draw_nString (x, y, str, count, vulkan_ctx);
}
static void
vulkan_Draw_AltString (int x, int y, const char *str)
{
Vulkan_Draw_AltString (x, y, str, vulkan_ctx);
}
static void
vulkan_Draw_ConsoleBackground (int lines, byte alpha)
{
Vulkan_Draw_ConsoleBackground (lines, alpha, vulkan_ctx);
}
static void
vulkan_Draw_Crosshair (void)
{
Vulkan_Draw_Crosshair (vulkan_ctx);
}
static void
vulkan_Draw_CrosshairAt (int ch, int x, int y)
{
Vulkan_Draw_CrosshairAt (ch, x, y, vulkan_ctx);
}
static void
vulkan_Draw_TileClear (int x, int y, int w, int h)
{
Vulkan_Draw_TileClear (x, y, w, h, vulkan_ctx);
}
static void
vulkan_Draw_Fill (int x, int y, int w, int h, int c)
{
Vulkan_Draw_Fill (x, y, w, h, c, vulkan_ctx);
}
static void
vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha)
{
Vulkan_Draw_TextBox (x, y, width, lines, alpha, vulkan_ctx);
}
static void
vulkan_Draw_FadeScreen (void)
{
Vulkan_Draw_FadeScreen (vulkan_ctx);
}
static void
vulkan_Draw_BlendScreen (quat_t color)
{
Vulkan_Draw_BlendScreen (color, vulkan_ctx);
}
static qpic_t *
vulkan_Draw_CachePic (const char *path, qboolean alpha)
{
return 0;
return Vulkan_Draw_CachePic (path, alpha, vulkan_ctx);
}
static qpic_t qpic = { 1, 1, {0} };
static void
vulkan_Draw_UncachePic (const char *path)
{
Vulkan_Draw_UncachePic (path, vulkan_ctx);
}
static qpic_t *
vulkan_Draw_MakePic (int width, int height, const byte *data)
{
return &qpic;
return Vulkan_Draw_MakePic (width, height, data, vulkan_ctx);
}
static void
vulkan_Draw_DestroyPic (qpic_t *pic)
{
Vulkan_Draw_DestroyPic (pic, vulkan_ctx);
}
static qpic_t *
vulkan_Draw_PicFromWad (const char *name)
{
return Vulkan_Draw_PicFromWad (name, vulkan_ctx);
}
static void
vulkan_Draw_Pic (int x, int y, qpic_t *pic)
{
Vulkan_Draw_Pic (x, y, pic, vulkan_ctx);
}
static void
vulkan_Draw_Picf (float x, float y, qpic_t *pic)
{
Vulkan_Draw_Picf (x, y, pic, vulkan_ctx);
}
static void
vulkan_Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height)
{
Vulkan_Draw_SubPic (x, y, pic, srcx, srcy, width, height, vulkan_ctx);
}
static vid_model_funcs_t model_funcs = {
@ -194,26 +302,26 @@ static vid_model_funcs_t model_funcs = {
};
vid_render_funcs_t vulkan_vid_render_funcs = {
0,//vulkan_Draw_Character,
0,//vulkan_Draw_String,
0,//vulkan_Draw_nString,
0,//vulkan_Draw_AltString,
0,//vulkan_Draw_ConsoleBackground,
0,//vulkan_Draw_Crosshair,
0,//vulkan_Draw_CrosshairAt,
0,//vulkan_Draw_TileClear,
0,//vulkan_Draw_Fill,
0,//vulkan_Draw_TextBox,
0,//vulkan_Draw_FadeScreen,
0,//vulkan_Draw_BlendScreen,
vulkan_Draw_Character,
vulkan_Draw_String,
vulkan_Draw_nString,
vulkan_Draw_AltString,
vulkan_Draw_ConsoleBackground,
vulkan_Draw_Crosshair,
vulkan_Draw_CrosshairAt,
vulkan_Draw_TileClear,
vulkan_Draw_Fill,
vulkan_Draw_TextBox,
vulkan_Draw_FadeScreen,
vulkan_Draw_BlendScreen,
vulkan_Draw_CachePic,
0,//vulkan_Draw_UncachePic,
vulkan_Draw_UncachePic,
vulkan_Draw_MakePic,
0,//vulkan_Draw_DestroyPic,
0,//vulkan_Draw_PicFromWad,
0,//vulkan_Draw_Pic,
0,//vulkan_Draw_Picf,
0,//vulkan_Draw_SubPic,
vulkan_Draw_DestroyPic,
vulkan_Draw_PicFromWad,
vulkan_Draw_Pic,
vulkan_Draw_Picf,
vulkan_Draw_SubPic,
vulkan_SCR_UpdateScreen,
SCR_DrawRam,

View file

@ -165,7 +165,7 @@ QFV_CreateDevice (vulkan_ctx_t *ctx, const char **extensions)
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 0, 0,
family, 1, &priority
};
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceFeatures features = {};
VkDeviceCreateInfo dCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 0, 0,
1, &qCreateInfo,
@ -173,7 +173,6 @@ QFV_CreateDevice (vulkan_ctx_t *ctx, const char **extensions)
next, ext,
&features
};
memset (&features, 0, sizeof (features));
qfv_device_t *device = calloc (1, sizeof (qfv_device_t)
+ sizeof (qfv_devfuncs_t));
device->funcs = (qfv_devfuncs_t *) (device + 1);

View file

@ -7,8 +7,61 @@
// $builtin refers to compiled-in shaders
passthrough = $builtin/passthrough.vert;
pushcolor = $builtin/pushcolor.frag;
twodv = $builtin/twod.vert;
twodf = $builtin/twod.frag;
};
samplers = {
quakepic = {
magFilter = nearest;
minFilter = nearest;
mipmapMode = nearest;
addressModeU = clamp_to_edge;
addressModeV = clamp_to_edge;
addressModeW = clamp_to_edge;
mipLodBias = 0;
anisotropyEnable = 0;//FIXME false!!!
maxAnisotropy = 0;
compareEnable = 0;//FIXME false!!!
compareOp = always;
minLod = 0;
maxLod = 0.25f;
borderColor = float_transparent_black;
unnormalizedCoordinates = 0;//FIXME false!!!
};
};
descriptorPools = {
twod = {
flags = 0;
maxSets = $swapchain.images.size;
bindings = (
{
type = uniform_buffer;
descriptorCount = $swapchain.images.size;
},
{
type = combined_image_sampler;
descriptorCount = $swapchain.images.size;
},
);
};
};
setLayouts = {
twod = {
bindings = (
{
binding = 0;
descriptorType = uniform_buffer;
descriptorCount = 1;
stageFlags = vertex;
},
{
binding = 1;
descriptorType = combined_image_sampler;
descriptorCount = 1;
stageFlags = fragment;
},
);
};
something = {
flags = 0;
bindings = (
@ -28,6 +81,9 @@
};
};
pipelineLayouts = {
twod = {
setLayouts = (twod);
};
something = {
setLayouts = (something);
pushConstantRanges = (
@ -39,88 +95,96 @@
);
};
};
pipeline = {
stages = (
{ stage = vertex; name = main; module = passthrough; },
{ stage = fragment; name = main; module = pushcolor; },
);
vertexInput = {
bindings = (
{
binding = 0;
stride = "4 * 4";
inputRate = vertex;
},
);
attributes = (
{
location = 0;
binding = 0;
format = r32g32b32a32_sfloat;
offset = 0;
},
pipelines = {
twod = {
stages = (
{ stage = vertex; name = main; module = twodv; },
{ stage = fragment; name = main; module = twodf; },
);
vertexInput = {
bindings = (
{
binding = 0;
stride = "2 * 4 * 4";
inputRate = vertex;
},
);
attributes = (
{
location = 0;
binding = 0;
format = r32g32b32a32_sfloat;
offset = 0;
},
{
location = 1;
binding = 0;
format = r32g32b32a32_sfloat;
offset = 4;
},
);
};
inputAssembly = {
topology = triangle_list;
primitiveRestartEnable = 0;
};
viewport = {
viewports = (
{
x = 0; y = 0;
width = 640; height = 480;
minDepth = 0; maxDepth = 1;
}
);
scissors = (
{
offset = { x = 0; y = 0 };
extent = { width = 640; height = 480; };
},
);
};
rasterization = {
depthClampEnable = 0;
rasterizerDiscardEnable = 0;
polygonMode = fill;
cullMode = back;
frontFace = counter_clockwise;
depthBiasEnable = 0;
lineWidth = 1;
};
multisample = {
rasterizationSamples = $msaaSamples;
sampleShadingEnable = 0;
minSampleShading = 0.5f;
alphaToCoverageEnable = 0;
alphaToOneEnable = 0;
};
depthStencil = {
depthTestEnable = 1;
depthWriteEnable = 1;
depthCompareOp = less;
depthBoundsTestEnable = 0;
stencilTestEnable = 0;
};
colorBlend = {
logicOpEnable = 0;
attachments = ({
blendEnable = 0;
srcColorBlendFactor = src_color;
dstColorBlendFactor = zero;
colorBlendOp = add;
srcAlphaBlendFactor = src_alpha;
dstAlphaBlendFactor = zero;
alphaBlendOp = add;
colorWriteMask = r|g|b|a;
});
};
dynamic = {
dynamicState = ( viewport, scissor );
};
layout = twod;
//renderPass = renderpass;
};
inputAssembly = {
topology = triangle_list;
primitiveRestartEnable = 0;
};
viewport = {
viewports = (
{
x = 0; y = 0;
width = 640; height = 480;
minDepth = 0; maxDepth = 1;
}
);
scissors = (
{
offset = { x = 0; y = 0 };
extent = { width = 640; height = 480; };
},
);
};
rasterization = {
depthClampEnable = 0;
rasterizerDiscardEnable = 0;
polygonMode = fill;
cullMode = back;
frontFace = counter_clockwise;
depthBiasEnable = 0;
lineWidth = 1;
};
multisample = {
rasterizationSamples = $msaaSamples;
sampleShadingEnable = 0;
minSampleShading = 0.5f;
alphaToCoverageEnable = 0;
alphaToOneEnable = 0;
};
depthStencil = {
depthTestEnable = 1;
depthWriteEnable = 1;
depthCompareOp = less;
depthBoundsTestEnable = 0;
stencilTestEnable = 0;
};
colorBlend = {
logicOpEnable = 0;
attachments = ({
blendEnable = 0;
srcColorBlendFactor = src_color;
dstColorBlendFactor = zero;
colorBlendOp = add;
srcAlphaBlendFactor = src_alpha;
dstAlphaBlendFactor = zero;
alphaBlendOp = add;
colorWriteMask = r|g|b|a;
});
};
dynamic = {
dynamicState = ( viewport, scissor );
};
layout = something;
//renderPass = renderpass;
};
renderpass = {
attachments = (

View file

@ -54,6 +54,10 @@
#include "vid_vulkan.h"
static
#include "libs/video/renderer/vulkan/twod.vert.spvc"
static
#include "libs/video/renderer/vulkan/twod.frag.spvc"
static
#include "libs/video/renderer/vulkan/passthrough.vert.spvc"
static
@ -66,6 +70,8 @@ typedef struct shaderdata_s {
} shaderdata_t;
static shaderdata_t builtin_shaders[] = {
{ "twod.vert", twod_vert, sizeof (twod_vert) },
{ "twod.frag", twod_frag, sizeof (twod_frag) },
{ "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) },
{ "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) },
{}

View file

@ -0,0 +1,19 @@
#version 450
layout (set = 0, binding = 1) uniform sampler2D Texture;
layout (location = 0) in vec2 st;
layout (location = 1) in vec4 color;
layout (location = 0) out vec4 frag_color;
void
main (void)
{
vec4 pix;
pix = texture (Texture, st);
if (pix.a < 0.5)
discard;
frag_color = pix * color;
}

View file

@ -0,0 +1,27 @@
#version 450
layout (set = 0, binding = 0) uniform Matrices {
mat4 Projection;
mat4 View;
mat4 Model;
};
/** Vertex position.
x, y, s, t
\a vertex provides the onscreen location at which to draw the icon
(\a x, \a y) and texture coordinate for the icon (\a s=z, \a t=w).
*/
layout (location = 0) in vec4 vertex;
layout (location = 1) in vec4 vcolor;
layout (location = 0) out vec2 st;
layout (location = 1) out vec4 color;
void
main (void)
{
gl_Position = Projection * vec4 (vertex.xy, 0.0, 1.0);
st = vertex.zw;
color = vcolor;
}

View file

@ -3,10 +3,10 @@
2D drawing support for Vulkan
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2011/12/23
Date: 2021/1/10
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -49,10 +49,24 @@
#include "QF/sys.h"
#include "QF/vid.h"
#include "compat.h"
#include "QF/Vulkan/qf_draw.h"
#include "QF/Vulkan/qf_vid.h"
#include "QF/Vulkan/descriptor.h"
#include "QF/Vulkan/device.h"
#include "QF/Vulkan/image.h"
#include "r_internal.h"
#include "vid_vulkan.h"
#include "vkparse.h"
//FIXME move into a context struct
VkImage conchars_image;
VkDeviceMemory conchars_memory;
VkImageView conchars_view;
VkSampler conchars_sampler;
VkPipeline twod;
static qpic_t *
pic_data (const char *name, int w, int h, const byte *data)
@ -67,135 +81,189 @@ pic_data (const char *name, int w, int h, const byte *data)
}
qpic_t *
vulkan_Draw_MakePic (int width, int height, const byte *data)
Vulkan_Draw_MakePic (int width, int height, const byte *data,
vulkan_ctx_t *ctx)
{
return pic_data (0, width, height, data);
}
void
vulkan_Draw_DestroyPic (qpic_t *pic)
Vulkan_Draw_DestroyPic (qpic_t *pic, vulkan_ctx_t *ctx)
{
}
qpic_t *
vulkan_Draw_PicFromWad (const char *name)
Vulkan_Draw_PicFromWad (const char *name, vulkan_ctx_t *ctx)
{
return pic_data (0, 1, 1, (const byte *)"");
}
qpic_t *
vulkan_Draw_CachePic (const char *path, qboolean alpha)
Vulkan_Draw_CachePic (const char *path, qboolean alpha, vulkan_ctx_t *ctx)
{
return pic_data (0, 1, 1, (const byte *)"");
}
void
vulkan_Draw_UncachePic (const char *path)
Vulkan_Draw_UncachePic (const char *path, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha)
Vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha,
vulkan_ctx_t *ctx)
{
}
static void
Vulkan_Draw_Shutdown (void *data)
{
vulkan_ctx_t *ctx = data;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
dfunc->vkDestroyPipeline (device->dev, twod, 0);
dfunc->vkDestroyImageView (device->dev, conchars_view, 0);
dfunc->vkFreeMemory (device->dev, conchars_memory, 0);
dfunc->vkDestroyImage (device->dev, conchars_image, 0);
}
void
Vulkan_Draw_Init (vulkan_ctx_t *ctx)
{
Sys_RegisterShutdown (Vulkan_Draw_Shutdown, ctx);
qfv_device_t *device = ctx->device;
qpic_t *charspic = Draw_Font8x8Pic ();
VkExtent3D extent = { charspic->width, charspic->height, 1 };
conchars_image = QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
extent, 1, 1,
VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT,
1);
conchars_memory = QFV_AllocImageMemory (device, conchars_image,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
0, 0);
QFV_BindImageMemory (device, conchars_image, conchars_memory, 0);
conchars_view = QFV_CreateImageView (device, conchars_image,
VK_IMAGE_VIEW_TYPE_2D,
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
VK_IMAGE_ASPECT_COLOR_BIT);
conchars_sampler = Hash_Find (ctx->samplers, "quakepic");
twod = Vulkan_CreatePipeline (ctx, "twod");
handleref_t *h;
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (ctx->framebuffers.size, alloca);
for (size_t i = 0; i < layouts->size; i++) {
h = Hash_Find (ctx->setLayouts, "twod");
layouts->a[i] = (VkDescriptorSetLayout) h->handle;
}
h = Hash_Find (ctx->descriptorPools, "twod");
__auto_type pool = (VkDescriptorPool) h->handle;
__auto_type sets = QFV_AllocateDescriptorSet (device, pool, layouts);
for (size_t i = 0; i < ctx->framebuffers.size; i++) {
ctx->framebuffers.a[i].twodDescriptors = sets->a[i];
}
}
void
Vulkan_Draw_Character (int x, int y, unsigned int chr, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_Init (void)
Vulkan_Draw_String (int x, int y, const char *str, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_Character (int x, int y, unsigned int chr)
Vulkan_Draw_nString (int x, int y, const char *str, int count,
vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_String (int x, int y, const char *str)
Vulkan_Draw_AltString (int x, int y, const char *str, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_nString (int x, int y, const char *str, int count)
Vulkan_Draw_CrosshairAt (int ch, int x, int y, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_AltString (int x, int y, const char *str)
Vulkan_Draw_Crosshair (vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_CrosshairAt (int ch, int x, int y)
Vulkan_Draw_Pic (int x, int y, qpic_t *pic, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_Crosshair (void)
Vulkan_Draw_Picf (float x, float y, qpic_t *pic, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_Pic (int x, int y, qpic_t *pic)
Vulkan_Draw_SubPic (int x, int y, qpic_t *pic,
int srcx, int srcy, int width, int height,
vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_Picf (float x, float y, qpic_t *pic)
Vulkan_Draw_ConsoleBackground (int lines, byte alpha, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_SubPic (int x, int y, qpic_t *pic, int srcx, int srcy, int width,
int height)
Vulkan_Draw_TileClear (int x, int y, int w, int h, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_ConsoleBackground (int lines, byte alpha)
Vulkan_Draw_Fill (int x, int y, int w, int h, int c, vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_TileClear (int x, int y, int w, int h)
Vulkan_Draw_FadeScreen (vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_Fill (int x, int y, int w, int h, int c)
Vulkan_Set2D (vulkan_ctx_t *ctx)
{
}
void
vulkan_Draw_FadeScreen (void)
Vulkan_Set2DScaled (vulkan_ctx_t *ctx)
{
}
void
Vulkan_Set2D (void)
Vulkan_End2D (vulkan_ctx_t *ctx)
{
}
void
Vulkan_Set2DScaled (void)
Vulkan_DrawReset (vulkan_ctx_t *ctx)
{
}
void
Vulkan_End2D (void)
Vulkan_FlushText (vulkan_ctx_t *ctx)
{
}
void
Vulkan_DrawReset (void)
{
}
void
Vulkan_FlushText (void)
{
}
void
vulkan_Draw_BlendScreen (quat_t color)
Vulkan_Draw_BlendScreen (quat_t color, vulkan_ctx_t *ctx)
{
}

View file

@ -420,18 +420,25 @@ Vulkan_DestroyRenderPass (vulkan_ctx_t *ctx)
ctx->renderpass.depthImage = 0;
}
void
Vulkan_CreatePipelines (vulkan_ctx_t *ctx)
VkPipeline
Vulkan_CreatePipeline (vulkan_ctx_t *ctx, const char *name)
{
qfv_load_pipeline (ctx);
plitem_t *item = ctx->pipelineDef;
if (!item || !(item = PL_ObjectForKey (item, "pipeline"))) {
Sys_Printf ("error loading pipeline\n");
if (!item || !(item = PL_ObjectForKey (item, "pipelines"))) {
Sys_Printf ("error loading pipelines\n");
return 0;
} else {
Sys_Printf ("Found pipeline def\n");
Sys_Printf ("Found pipelines def\n");
}
ctx->pipeline = QFV_ParsePipeline (ctx, item);
if (!(item = PL_ObjectForKey (item, name))) {
Sys_Printf ("error loading pipeline %s\n", name);
return 0;
} else {
Sys_Printf ("Found pipeline def %s\n", name);
}
return QFV_ParsePipeline (ctx, item);
}
void