mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
[vulkan] Start moving towards a deferred renderer
After getting lights even vaguely working for alias models, I realized that it just wasn't going to be feasible to do nice lighting with forward rendering. This gets the bulk of the work done for deferred rendering, but still need to sort out the shaders before any real testing can be done.
This commit is contained in:
parent
121425a75b
commit
a94949c009
17 changed files with 1347 additions and 551 deletions
|
@ -3,8 +3,17 @@
|
|||
|
||||
#include "QF/darray.h"
|
||||
|
||||
typedef struct qfv_imageset_s DARRAY_TYPE (VkImage) qfv_imageset_t;
|
||||
typedef struct qfv_imageviewset_s DARRAY_TYPE (VkImageView) qfv_imageviewset_t;
|
||||
typedef struct qfv_imageset_s
|
||||
DARRAY_TYPE (VkImage) qfv_imageset_t;
|
||||
|
||||
#define QFV_AllocImages(num, allocator) \
|
||||
DARRAY_ALLOCFIXED (qfv_imageset_t, num, allocator)
|
||||
|
||||
typedef struct qfv_imageviewset_s
|
||||
DARRAY_TYPE (VkImageView) qfv_imageviewset_t;
|
||||
|
||||
#define QFV_AllocImageViews(num, allocator) \
|
||||
DARRAY_ALLOCFIXED (qfv_imageviewset_t, num, allocator)
|
||||
|
||||
typedef struct qfv_imageresource_s {
|
||||
struct qfv_device_s *device;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "QF/model.h"
|
||||
#include "QF/modelgen.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
||||
typedef struct aliasvrt_s {
|
||||
float vertex[4];
|
||||
|
@ -61,32 +62,22 @@ typedef struct qfv_alias_skin_s {
|
|||
byte colorb[4];
|
||||
} qfv_alias_skin_t;
|
||||
|
||||
typedef struct qfv_light_s {
|
||||
vec3_t color;
|
||||
float dist;
|
||||
vec3_t position;
|
||||
int type;
|
||||
vec3_t direction;
|
||||
float cone;
|
||||
} qfv_light_t;
|
||||
|
||||
#define ALIAS_LIGHTS 8
|
||||
|
||||
typedef struct qfv_light_buffer_s {
|
||||
int light_count;
|
||||
qfv_light_t lights[ALIAS_LIGHTS] __attribute__((aligned(16)));
|
||||
} qfv_light_buffer_t;
|
||||
|
||||
#define ALIAS_BUFFER_INFOS 2
|
||||
#define ALIAS_BUFFER_INFOS 1
|
||||
#define ALIAS_IMAGE_INFOS 1
|
||||
|
||||
enum {
|
||||
QFV_aliasDepth,
|
||||
QFV_aliasGBuffer,
|
||||
//QFV_aliasTranslucent,
|
||||
|
||||
QFV_aliasNumPasses
|
||||
};
|
||||
|
||||
typedef struct aliasframe_s {
|
||||
VkCommandBuffer cmd;
|
||||
qfv_cmdbufferset_t cmdSet;
|
||||
VkDescriptorBufferInfo bufferInfo[ALIAS_BUFFER_INFOS];
|
||||
VkDescriptorImageInfo imageInfo[ALIAS_IMAGE_INFOS];
|
||||
VkWriteDescriptorSet descriptors[ALIAS_BUFFER_INFOS + ALIAS_IMAGE_INFOS];
|
||||
qfv_light_buffer_t *lights;
|
||||
VkBuffer light_buffer;
|
||||
} aliasframe_t;
|
||||
|
||||
typedef struct aliasframeset_s
|
||||
|
@ -94,11 +85,10 @@ typedef struct aliasframeset_s
|
|||
|
||||
typedef struct aliasctx_s {
|
||||
aliasframeset_t frames;
|
||||
VkPipeline pipeline;
|
||||
VkPipeline depth;
|
||||
VkPipeline gbuf;
|
||||
VkPipelineLayout layout;
|
||||
VkSampler sampler;
|
||||
|
||||
VkDeviceMemory light_memory;
|
||||
} aliasctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "QF/darray.h"
|
||||
#include "QF/model.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
||||
typedef struct bspvert_s {
|
||||
quat_t vertex;
|
||||
|
@ -69,13 +70,19 @@ typedef enum {
|
|||
// Texture, GlowMap, LightMap, SkySheet, SkyCube
|
||||
#define BSP_IMAGE_INFOS 5
|
||||
|
||||
enum {
|
||||
QFV_bspDepth,
|
||||
QFV_bspGBuffer,
|
||||
QFV_bspTranslucent,
|
||||
|
||||
QFV_bspNumPasses
|
||||
};
|
||||
|
||||
typedef struct bspframe_s {
|
||||
uint32_t *index_data; // pointer into mega-buffer for this frame (c)
|
||||
uint32_t index_offset; // offset of index_data within mega-buffer (c)
|
||||
uint32_t index_count; // number if indices queued (d)
|
||||
VkCommandBuffer bsp_cmd;
|
||||
VkCommandBuffer turb_cmd;
|
||||
VkCommandBuffer sky_cmd;
|
||||
qfv_cmdbufferset_t cmdSet;
|
||||
VkDescriptorBufferInfo bufferInfo[BSP_BUFFER_INFOS];
|
||||
VkDescriptorImageInfo imageInfo[BSP_IMAGE_INFOS];
|
||||
VkWriteDescriptorSet descriptors[BSP_BUFFER_INFOS + BSP_IMAGE_INFOS];
|
||||
|
|
|
@ -35,9 +35,22 @@
|
|||
#endif
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
//FIXME location
|
||||
enum {
|
||||
QFV_passDepth, // geometry
|
||||
QFV_passGBuffer, // geometry
|
||||
QFV_passTranslucent, // geometry
|
||||
QFV_passLighting, // single quad
|
||||
QFV_passCompose, // single quad
|
||||
|
||||
QFV_NumPasses
|
||||
};
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
void Vulkan_DestroyFramebuffers (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_DestroyFrames (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_CreateFrames (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_CreateFramebuffers (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_DestroyFramebuffers (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_CreateRenderPass (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_DestroyRenderPass (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_CreateMatrices (struct vulkan_ctx_s *ctx);
|
||||
|
|
|
@ -27,6 +27,12 @@ typedef struct qfv_subpassdependency_s
|
|||
#define QFV_AllocSubpassDependencies(num, allocator) \
|
||||
DARRAY_ALLOCFIXED (qfv_subpassdependency_t, num, allocator)
|
||||
|
||||
typedef struct qfv_framebufferset_s
|
||||
DARRAY_TYPE (VkFramebuffer) qfv_framebufferset_t;
|
||||
|
||||
#define QFV_AllocFrameBuffers(num, allocator) \
|
||||
DARRAY_ALLOCFIXED (qfv_framebufferset_t, num, allocator)
|
||||
|
||||
struct qfv_device_s;
|
||||
struct qfv_imageviewset_s;
|
||||
VkRenderPass
|
||||
|
|
|
@ -8,20 +8,15 @@
|
|||
|
||||
#include "QF/darray.h"
|
||||
|
||||
typedef struct vulkan_renderpass_s {
|
||||
VkRenderPass renderpass;
|
||||
struct qfv_imageresource_s *colorImage;
|
||||
struct qfv_imageresource_s *depthImage;
|
||||
} vulkan_renderpass_t;
|
||||
|
||||
typedef struct vulkan_framebuffer_s {
|
||||
typedef struct vulkan_frame_s {
|
||||
VkFramebuffer framebuffer;
|
||||
VkFence fence;
|
||||
VkSemaphore imageAvailableSemaphore;
|
||||
VkSemaphore renderDoneSemaphore;
|
||||
VkCommandBuffer cmdBuffer;
|
||||
|
||||
struct qfv_cmdbufferset_s *subCommand;
|
||||
int cmdSetCount;
|
||||
struct qfv_cmdbufferset_s *cmdSets;
|
||||
} vulkan_frame_t;
|
||||
|
||||
typedef struct vulkan_matrices_s {
|
||||
|
@ -59,11 +54,22 @@ typedef struct vulkan_ctx_s {
|
|||
VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain
|
||||
struct plitem_s *pipelineDef;
|
||||
|
||||
struct plitem_s *renderpassDef;
|
||||
VkRenderPass renderpass;
|
||||
struct qfv_imageset_s *attachment_images;
|
||||
struct qfv_imageviewset_s *attachment_views;
|
||||
VkDeviceMemory attachmentMemory;
|
||||
|
||||
uint32_t swapImageIndex;
|
||||
struct qfv_framebufferset_s *framebuffers;
|
||||
|
||||
struct hashtab_s *shaderModules;
|
||||
struct hashtab_s *setLayouts;
|
||||
struct hashtab_s *pipelineLayouts;
|
||||
struct hashtab_s *descriptorPools;
|
||||
struct hashtab_s *samplers;
|
||||
struct hashtab_s *images;
|
||||
struct hashtab_s *imageViews;
|
||||
|
||||
struct aliasctx_s *alias_context;
|
||||
struct bspctx_s *bsp_context;
|
||||
|
@ -72,7 +78,6 @@ typedef struct vulkan_ctx_s {
|
|||
VkCommandPool cmdpool;
|
||||
VkCommandBuffer cmdbuffer;
|
||||
VkFence fence; // for ctx->cmdbuffer only
|
||||
vulkan_renderpass_t renderpass;
|
||||
struct qfv_stagebuf_s *staging;
|
||||
VkPipeline pipeline;
|
||||
size_t curFrame;
|
||||
|
|
|
@ -209,6 +209,8 @@ libs_video_renderer_vid_render_sw32_la_SOURCES=\
|
|||
|
||||
pipeline_src = libs/video/renderer/vulkan/qfpipeline.plist
|
||||
pipeline_gen = libs/video/renderer/vulkan/qfpipeline.plc
|
||||
renderpass_src = libs/video/renderer/vulkan/deferred.plist
|
||||
renderpass_gen = libs/video/renderer/vulkan/deferred.plc
|
||||
|
||||
video_renderer_vulkan_libs = \
|
||||
libs/models/libmodels_vulkan.la
|
||||
|
@ -250,7 +252,7 @@ libs/video/renderer/vulkan/vkparse.lo: libs/video/renderer/vulkan/vkparse.c $(vk
|
|||
|
||||
libs/video/renderer/vulkan/shader.lo: libs/video/renderer/vulkan/shader.c $(vkshader_c)
|
||||
|
||||
libs/video/renderer/vulkan/vulkan_vid_common.lo: libs/video/renderer/vulkan/vulkan_vid_common.c $(vkparse_src) $(pipeline_gen)
|
||||
libs/video/renderer/vulkan/vulkan_vid_common.lo: libs/video/renderer/vulkan/vulkan_vid_common.c $(vkparse_src) $(pipeline_gen) ${renderpass_gen}
|
||||
|
||||
|
||||
qwaq_curses = ruamoko/qwaq/qwaq-curses$(EXEEXT)
|
||||
|
|
|
@ -87,8 +87,9 @@ vulkan_R_Init (void)
|
|||
Vulkan_CreateStagingBuffers (vulkan_ctx);
|
||||
Vulkan_CreateMatrices (vulkan_ctx);
|
||||
Vulkan_CreateSwapchain (vulkan_ctx);
|
||||
Vulkan_CreateFramebuffers (vulkan_ctx);
|
||||
Vulkan_CreateFrames (vulkan_ctx);
|
||||
Vulkan_CreateRenderPass (vulkan_ctx);
|
||||
Vulkan_CreateFramebuffers (vulkan_ctx);
|
||||
// FIXME this should be staged so screen updates can begin while pipelines
|
||||
// are being built
|
||||
vulkan_ctx->pipeline = Vulkan_CreatePipeline (vulkan_ctx, "pipeline");
|
||||
|
@ -111,6 +112,8 @@ vulkan_R_Init (void)
|
|||
static void
|
||||
vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs)
|
||||
{
|
||||
const VkSubpassContents subpassContents
|
||||
= VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
|
||||
static int count = 0;
|
||||
static double startTime;
|
||||
uint32_t imageIndex = 0;
|
||||
|
@ -128,20 +131,9 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs)
|
|||
QFV_AcquireNextImage (vulkan_ctx->swapchain,
|
||||
frame->imageAvailableSemaphore,
|
||||
0, &imageIndex);
|
||||
vulkan_ctx->swapImageIndex = imageIndex;
|
||||
|
||||
int attachCount = vulkan_ctx->msaaSamples > 1 ? 3 : 2;
|
||||
__auto_type attachments = DARRAY_ALLOCFIXED (qfv_imageviewset_t,
|
||||
attachCount, alloca);
|
||||
qfv_swapchain_t *sc = vulkan_ctx->swapchain;
|
||||
attachments->a[0] = sc->imageViews->a[imageIndex];
|
||||
attachments->a[1] = vulkan_ctx->renderpass.depthImage->view;
|
||||
if (attachCount > 2) {
|
||||
attachments->a[2] = vulkan_ctx->renderpass.colorImage->view;
|
||||
}
|
||||
|
||||
VkRenderPass renderpass = vulkan_ctx->renderpass.renderpass;
|
||||
frame->framebuffer = QFV_CreateFramebuffer (device, renderpass,
|
||||
attachments, sc->extent, 1);
|
||||
frame->framebuffer = vulkan_ctx->framebuffers->a[imageIndex];
|
||||
|
||||
scr_3dfunc ();
|
||||
while (*scr_funcs) {
|
||||
|
@ -160,20 +152,26 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs)
|
|||
};
|
||||
VkRenderPassBeginInfo renderPassInfo = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 0,
|
||||
vulkan_ctx->renderpass.renderpass, 0,
|
||||
{ {0, 0}, sc->extent },
|
||||
vulkan_ctx->renderpass, 0,
|
||||
{ {0, 0}, vulkan_ctx->swapchain->extent },
|
||||
3, clearValues
|
||||
};
|
||||
|
||||
dfunc->vkBeginCommandBuffer (frame->cmdBuffer, &beginInfo);
|
||||
renderPassInfo.framebuffer = frame->framebuffer;
|
||||
dfunc->vkCmdBeginRenderPass (frame->cmdBuffer, &renderPassInfo,
|
||||
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
|
||||
subpassContents);
|
||||
|
||||
dfunc->vkCmdExecuteCommands (frame->cmdBuffer, frame->subCommand->size,
|
||||
frame->subCommand->a);
|
||||
// reset for next time around
|
||||
frame->subCommand->size = 0;
|
||||
for (int i = 0; i < frame->cmdSetCount; i++) {
|
||||
dfunc->vkCmdExecuteCommands (frame->cmdBuffer, frame->cmdSets[i].size,
|
||||
frame->cmdSets[i].a);
|
||||
// reset for next time around
|
||||
frame->cmdSets[i].size = 0;
|
||||
|
||||
if (i < frame->cmdSetCount) {
|
||||
dfunc->vkCmdNextSubpass (frame->cmdBuffer, subpassContents);
|
||||
}
|
||||
}
|
||||
|
||||
dfunc->vkCmdEndRenderPass (frame->cmdBuffer);
|
||||
dfunc->vkEndCommandBuffer (frame->cmdBuffer);
|
||||
|
|
342
libs/video/renderer/vulkan/deferred.plist
Normal file
342
libs/video/renderer/vulkan/deferred.plist
Normal file
|
@ -0,0 +1,342 @@
|
|||
{
|
||||
images = {
|
||||
depth = {
|
||||
imageType = VK_IMAGE_TYPE_2D; //FIXME short form is 2d...
|
||||
format = x8_d24_unorm_pack32;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
arrayLayers = 1;
|
||||
tiling = optimal;
|
||||
usage = depth_stencil_attachment|input_attachment;
|
||||
};
|
||||
color = {
|
||||
imageType = VK_IMAGE_TYPE_2D;
|
||||
format = r8g8b8a8_unorm;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
arrayLayers = 1;
|
||||
tiling = optimal;
|
||||
usage = color_attachment|input_attachment;
|
||||
};
|
||||
normals = {
|
||||
imageType = VK_IMAGE_TYPE_2D;
|
||||
format = r16g16b16a16_sfloat;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
arrayLayers = 1;
|
||||
tiling = optimal;
|
||||
usage = color_attachment|input_attachment;
|
||||
};
|
||||
opaque = {
|
||||
imageType = VK_IMAGE_TYPE_2D;
|
||||
format = r8g8b8a8_unorm;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
arrayLayers = 1;
|
||||
tiling = optimal;
|
||||
usage = color_attachment|input_attachment;
|
||||
};
|
||||
translucent = {
|
||||
imageType = VK_IMAGE_TYPE_2D;
|
||||
format = r8g8b8a8_unorm;
|
||||
samples = 1;
|
||||
extent = {
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
depth = 1;
|
||||
};
|
||||
mipLevels = 1;
|
||||
arrayLayers = 1;
|
||||
tiling = optimal;
|
||||
usage = color_attachment|input_attachment;
|
||||
};
|
||||
};
|
||||
imageViews = {
|
||||
depth = {
|
||||
image = depth;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
format = $properties.images.depth.format;
|
||||
components = {
|
||||
r = identity;
|
||||
g = identity;
|
||||
b = identity;
|
||||
a = identity;
|
||||
};
|
||||
subresourceRange = {
|
||||
aspectMask = depth;
|
||||
levelCount = 1;
|
||||
layerCount = 1;
|
||||
};
|
||||
};
|
||||
color = {
|
||||
image = color;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
format = $properties.images.color.format;
|
||||
components = {
|
||||
r = identity;
|
||||
g = identity;
|
||||
b = identity;
|
||||
a = identity;
|
||||
};
|
||||
subresourceRange = {
|
||||
aspectMask = color;
|
||||
levelCount = 1;
|
||||
layerCount = 1;
|
||||
};
|
||||
};
|
||||
normals = {
|
||||
image = normals;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
format = $properties.images.normals.format;
|
||||
components = {
|
||||
r = identity;
|
||||
g = identity;
|
||||
b = identity;
|
||||
a = identity;
|
||||
};
|
||||
subresourceRange = {
|
||||
aspectMask = color;
|
||||
levelCount = 1;
|
||||
layerCount = 1;
|
||||
};
|
||||
};
|
||||
opaque = {
|
||||
image = opaque;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
format = $properties.images.opaque.format;
|
||||
components = {
|
||||
r = identity;
|
||||
g = identity;
|
||||
b = identity;
|
||||
a = identity;
|
||||
};
|
||||
subresourceRange = {
|
||||
aspectMask = color;
|
||||
levelCount = 1;
|
||||
layerCount = 1;
|
||||
};
|
||||
};
|
||||
translucent = {
|
||||
image = translucent;
|
||||
viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
format = $properties.images.translucent.format;
|
||||
components = {
|
||||
r = identity;
|
||||
g = identity;
|
||||
b = identity;
|
||||
a = identity;
|
||||
};
|
||||
subresourceRange = {
|
||||
aspectMask = color;
|
||||
levelCount = 1;
|
||||
layerCount = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
framebuffer = {
|
||||
renderPass = renderpass;
|
||||
attachments = (depth, color, normals, opaque, translucent,
|
||||
"$swapchain.views[$swapImageIndex]");
|
||||
width = $swapchain.extent.width;
|
||||
height = $swapchain.extent.height;
|
||||
};
|
||||
renderpass = {
|
||||
attachments = (
|
||||
{
|
||||
format = $properties.images.depth.format;
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = dont_care;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
initialLayout = undefined;
|
||||
finalLayout = depth_stencil_attachment_optimal;
|
||||
},
|
||||
{
|
||||
format = $properties.images.color.format;
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = dont_care;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
initialLayout = undefined;
|
||||
finalLayout = color_attachment_optimal;
|
||||
},
|
||||
{
|
||||
format = $properties.images.normals.format;
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = dont_care;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
initialLayout = undefined;
|
||||
finalLayout = color_attachment_optimal;
|
||||
},
|
||||
{
|
||||
format = $properties.images.opaque.format;
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = dont_care;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
initialLayout = undefined;
|
||||
finalLayout = color_attachment_optimal;
|
||||
},
|
||||
{
|
||||
format = $properties.images.translucent.format;
|
||||
samples = 1;
|
||||
loadOp = dont_care;
|
||||
storeOp = dont_care;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
initialLayout = undefined;
|
||||
finalLayout = color_attachment_optimal;
|
||||
},
|
||||
{
|
||||
format = $swapchain.format;
|
||||
samples = 1;
|
||||
loadOp = clear;
|
||||
storeOp = store;
|
||||
stencilLoadOp = dont_care;
|
||||
stencilStoreOp = dont_care;
|
||||
initialLayout = undefined;
|
||||
finalLayout = present_src_khr;
|
||||
},
|
||||
);
|
||||
subpasses = (
|
||||
{ // depth
|
||||
pipelineBindPoint = graphics;
|
||||
depthStencilAttachment = {
|
||||
attachment = 0;
|
||||
layout = depth_stencil_attachment_optimal;
|
||||
};
|
||||
},
|
||||
{ // g-buffer generation
|
||||
pipelineBindPoint = graphics;
|
||||
colorAttachments = (
|
||||
{ // color
|
||||
attachment = 1;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
{ // normals
|
||||
attachment = 2;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
depthStencilAttachment = {
|
||||
attachment = 0;
|
||||
layout = depth_stencil_attachment_optimal;
|
||||
};
|
||||
},
|
||||
{ // lighting
|
||||
pipelineBindPoint = graphics;
|
||||
inputAttachments = (
|
||||
{ // depth
|
||||
attachment = 0;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // color
|
||||
attachment = 1;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // normals
|
||||
attachment = 2;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
);
|
||||
colorAttachments = (
|
||||
{ // opaque
|
||||
attachment = 3;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
},
|
||||
{ // translucent
|
||||
pipelineBindPoint = graphics;
|
||||
colorAttachments = (
|
||||
{ // translucent
|
||||
attachment = 4;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
},
|
||||
{ // compose
|
||||
pipelineBindPoint = graphics;
|
||||
inputAttachments = (
|
||||
{ // opaque
|
||||
attachment = 3;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
{ // translucent
|
||||
attachment = 4;
|
||||
layout = shader_read_only_optimal;
|
||||
},
|
||||
);
|
||||
colorAttachments = (
|
||||
{ // swapchain
|
||||
attachment = 5;
|
||||
layout = color_attachment_optimal;
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
dependencies = (
|
||||
{
|
||||
srcSubpass = 0;
|
||||
dstSubpass = 1;
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = shader_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 1;
|
||||
dstSubpass = 2;
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = shader_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 2;
|
||||
dstSubpass = 4;
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = shader_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
{
|
||||
srcSubpass = 3;
|
||||
dstSubpass = 4;
|
||||
srcStageMask = color_attachment_output;
|
||||
dstStageMask = fragment_shader;
|
||||
srcAccessMask = color_attachment_write;
|
||||
dstAccessMask = shader_read;
|
||||
dependencyFlags = by_region;
|
||||
},
|
||||
);
|
||||
};
|
||||
}
|
|
@ -273,7 +273,45 @@
|
|||
};
|
||||
};
|
||||
pipelines = {
|
||||
alias = {
|
||||
alias_depth = {
|
||||
stages = (
|
||||
{
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/alias.vert;
|
||||
},
|
||||
);
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
"$properties.pipelines.alias_gbuf.vertexInput.bindings[0]",
|
||||
"$properties.pipelines.alias_gbuf.vertexInput.bindings[1]",
|
||||
);
|
||||
attributes = (
|
||||
"$properties.pipelines.alias_gbuf.vertexInput.attributes[0]",
|
||||
"$properties.pipelines.alias_gbuf.vertexInput.attributes[1]",
|
||||
"$properties.pipelines.alias_gbuf.vertexInput.attributes[2]",
|
||||
"$properties.pipelines.alias_gbuf.vertexInput.attributes[3]",
|
||||
);
|
||||
};
|
||||
inputAssembly = $properties.pipelines.alias_gbuf.inputAssembly;
|
||||
viewport = $properties.pipelines.alias_gbuf.viewport;
|
||||
rasterization = $properties.pipelines.alias_gbuf.rasterization;
|
||||
multisample = $properties.pipelines.alias_gbuf.multisample;
|
||||
depthStencil = {
|
||||
depthTestEnable = true;
|
||||
depthWriteEnable = true;
|
||||
depthCompareOp = less_or_equal;
|
||||
depthBoundsTestEnable = false;
|
||||
stencilTestEnable = false;
|
||||
};
|
||||
colorBlend = $properties.pipelines.alias_gbuf.colorBlend;
|
||||
dynamic = {
|
||||
dynamicState = ( viewport, scissor );
|
||||
};
|
||||
layout = alias_layout;
|
||||
//renderPass = renderpass;
|
||||
};
|
||||
alias_gbuf = {
|
||||
stages = (
|
||||
{
|
||||
stage = vertex;
|
||||
|
@ -404,7 +442,41 @@
|
|||
layout = alias_layout;
|
||||
//renderPass = renderpass;
|
||||
};
|
||||
quakebsp_main = {
|
||||
bsp_depth = {
|
||||
stages = (
|
||||
{
|
||||
stage = vertex;
|
||||
name = main;
|
||||
module = $builtin/quakebsp.vert;
|
||||
},
|
||||
);
|
||||
vertexInput = {
|
||||
bindings = (
|
||||
"$properties.pipelines.bsp_gbuf.vertexInput.bindings[0]",
|
||||
);
|
||||
attributes = (
|
||||
"$properties.pipelines.bsp_gbuf.vertexInput.attributes[0]",
|
||||
);
|
||||
};
|
||||
inputAssembly = $properties.pipelines.bsp_main.inputAssembly;
|
||||
viewport = $properties.pipelines.bsp_main.viewport;
|
||||
rasterization = $properties.pipelines.bsp_main.rasterization;
|
||||
multisample = $properties.pipelines.bsp_main.multisample;
|
||||
depthStencil = {
|
||||
depthTestEnable = true;
|
||||
depthWriteEnable = true;
|
||||
depthCompareOp = less_or_equal;
|
||||
depthBoundsTestEnable = false;
|
||||
stencilTestEnable = false;
|
||||
};
|
||||
colorBlend = $properties.pipelines.bsp_gbuf.colorBlend;
|
||||
dynamic = {
|
||||
dynamicState = ( viewport, scissor );
|
||||
};
|
||||
layout = quakebsp_layout;
|
||||
//renderPass = renderpass;
|
||||
};
|
||||
bsp_gbuf = {
|
||||
stages = (
|
||||
{
|
||||
stage = vertex;
|
||||
|
@ -523,86 +595,15 @@
|
|||
};
|
||||
},
|
||||
);
|
||||
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 = 16;
|
||||
},
|
||||
);
|
||||
};
|
||||
inputAssembly = {
|
||||
topology = triangle_fan;
|
||||
primitiveRestartEnable = true;
|
||||
};
|
||||
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 = false;
|
||||
rasterizerDiscardEnable = false;
|
||||
polygonMode = fill;
|
||||
cullMode = back;
|
||||
frontFace = clockwise;
|
||||
depthBiasEnable = false;
|
||||
lineWidth = 1;
|
||||
};
|
||||
multisample = {
|
||||
rasterizationSamples = $msaaSamples;
|
||||
sampleShadingEnable = false;
|
||||
minSampleShading = 0.5f;
|
||||
alphaToCoverageEnable = false;
|
||||
alphaToOneEnable = false;
|
||||
};
|
||||
depthStencil = {
|
||||
depthTestEnable = true;
|
||||
depthWriteEnable = true;
|
||||
depthCompareOp = less_or_equal;
|
||||
depthBoundsTestEnable = false;
|
||||
stencilTestEnable = false;
|
||||
};
|
||||
colorBlend = {
|
||||
logicOpEnable = false;
|
||||
attachments = ({
|
||||
blendEnable = true;
|
||||
srcColorBlendFactor = src_alpha;
|
||||
dstColorBlendFactor = one_minus_src_alpha;
|
||||
colorBlendOp = add;
|
||||
srcAlphaBlendFactor = src_alpha;
|
||||
dstAlphaBlendFactor = one_minus_src_alpha;
|
||||
alphaBlendOp = add;
|
||||
colorWriteMask = r|g|b|a;
|
||||
});
|
||||
};
|
||||
vertexInput = $properties.pipelines.bsp_gbuf.vertexInput;
|
||||
inputAssembly = $properties.pipelines.bsp_gbuf.inputAssembly;
|
||||
viewport = $properties.pipelines.bsp_gbuf.viewport;
|
||||
rasterization = $properties.pipelines.bsp_gbuf.rasterization;
|
||||
multisample = $properties.pipelines.bsp_gbuf.multisample;
|
||||
depthStencil = $properties.pipelines.bsp_gbuf.depthStencil;
|
||||
colorBlend = $properties.pipelines.bsp_gbuf.colorBlend;
|
||||
dynamic = {
|
||||
dynamicState = ( viewport, scissor, blend_constants );
|
||||
dynamicState = ( viewport, scissor );
|
||||
};
|
||||
layout = quakebsp_layout;
|
||||
//renderPass = renderpass;
|
||||
|
|
|
@ -460,7 +460,8 @@ parse_VkDescriptorSetLayout (const plfield_t *field, const plitem_t *item,
|
|||
ret = !cexpr_eval_string (name, &ectx);
|
||||
if (ret) {
|
||||
VkDescriptorSetLayout setLayout;
|
||||
setLayout = QFV_ParseDescriptorSetLayout (ctx, setItem);
|
||||
setLayout = QFV_ParseDescriptorSetLayout (ctx, setItem,
|
||||
pctx->properties);
|
||||
*handle = (VkDescriptorSetLayout) setLayout;
|
||||
|
||||
QFV_AddHandle (ctx->setLayouts, name, (uint64_t) setLayout);
|
||||
|
@ -495,7 +496,7 @@ parse_VkPipelineLayout (const plitem_t *item, void **data,
|
|||
ret = !cexpr_eval_string (name, &ectx);
|
||||
if (ret) {
|
||||
VkPipelineLayout layout;
|
||||
layout = QFV_ParsePipelineLayout (ctx, setItem);
|
||||
layout = QFV_ParsePipelineLayout (ctx, setItem, context->properties);
|
||||
*handle = (VkPipelineLayout) layout;
|
||||
|
||||
QFV_AddHandle (ctx->pipelineLayouts, name, (uint64_t) layout);
|
||||
|
@ -503,6 +504,92 @@ parse_VkPipelineLayout (const plitem_t *item, void **data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_VkImage (const plitem_t *item, void **data, plitem_t *messages,
|
||||
parsectx_t *context)
|
||||
{
|
||||
__auto_type handle = (VkImage *) data[0];
|
||||
int ret = 1;
|
||||
exprctx_t ectx = *context->ectx;
|
||||
vulkan_ctx_t *ctx = context->vctx;
|
||||
|
||||
const char *name = PL_String (item);
|
||||
Sys_Printf ("parse_VkImage: %s\n", name);
|
||||
if (name[0] != '$') {
|
||||
name = va (ctx->va_ctx, "$"QFV_PROPERTIES".images.%s", name);
|
||||
}
|
||||
|
||||
*handle = (VkImage) QFV_GetHandle (ctx->images, name);
|
||||
if (*handle) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
plitem_t *imageItem = 0;
|
||||
exprval_t result = { &cexpr_plitem, &imageItem };
|
||||
ectx.symtab = 0;
|
||||
ectx.result = &result;
|
||||
ret = !cexpr_eval_string (name, &ectx);
|
||||
if (ret) {
|
||||
VkImage image;
|
||||
image = QFV_ParseImage (ctx, imageItem, context->properties);
|
||||
*handle = (VkImage) image;
|
||||
|
||||
QFV_AddHandle (ctx->images, name, (uint64_t) image);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static exprtype_t imageview_type = {
|
||||
"VkImageView",
|
||||
sizeof (VkImageView),
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
static int
|
||||
parse_VkImageView (const plfield_t *field, const plitem_t *item, void *data,
|
||||
plitem_t *messages, void *_context)
|
||||
{
|
||||
parsectx_t *context = _context;
|
||||
__auto_type handle = (VkImageView *) data;
|
||||
int ret = 1;
|
||||
exprctx_t ectx = *context->ectx;
|
||||
vulkan_ctx_t *ctx = context->vctx;
|
||||
|
||||
const char *name = PL_String (item);
|
||||
Sys_Printf ("parse_VkImageView: %s\n", name);
|
||||
if (name[0] != '$') {
|
||||
name = va (ctx->va_ctx, "$"QFV_PROPERTIES".imageViews.%s", name);
|
||||
}
|
||||
|
||||
*handle = (VkImageView) QFV_GetHandle (ctx->imageViews, name);
|
||||
if (*handle) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
exprval_t *value = 0;
|
||||
exprval_t result = { &cexpr_exprval, &value };
|
||||
ectx.symtab = 0;
|
||||
ectx.result = &result;
|
||||
ret = !cexpr_eval_string (name, &ectx);
|
||||
|
||||
plitem_t *imageViewItem = 0;
|
||||
if (ret) {
|
||||
VkImageView imageView;
|
||||
if (value->type == &imageview_type) {
|
||||
imageView = *(VkImageView *) value->value;
|
||||
} else if (value->type == &cexpr_plitem) {
|
||||
imageView = QFV_ParseImageView (ctx, imageViewItem,
|
||||
context->properties);
|
||||
QFV_AddHandle (ctx->imageViews, name, (uint64_t) imageView);
|
||||
} else {
|
||||
PL_Message (messages, item, "not a VkImageView");
|
||||
return 0;
|
||||
}
|
||||
*handle = (VkImageView) imageView;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *
|
||||
handleref_getkey (const void *hr, void *unused)
|
||||
{
|
||||
|
@ -592,6 +679,36 @@ sampler_free (void *hr, void *_ctx)
|
|||
handleref_free (handleref, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
image_free (void *hr, void *_ctx)
|
||||
{
|
||||
__auto_type handleref = (handleref_t *) hr;
|
||||
__auto_type image = (VkImage) handleref->handle;
|
||||
__auto_type ctx = (vulkan_ctx_t *) _ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
if (image) {
|
||||
dfunc->vkDestroyImage (device->dev, image, 0);
|
||||
};
|
||||
handleref_free (handleref, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
imageView_free (void *hr, void *_ctx)
|
||||
{
|
||||
__auto_type handleref = (handleref_t *) hr;
|
||||
__auto_type imageView = (VkImageView) handleref->handle;
|
||||
__auto_type ctx = (vulkan_ctx_t *) _ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
if (imageView) {
|
||||
dfunc->vkDestroyImageView (device->dev, imageView, 0);
|
||||
};
|
||||
handleref_free (handleref, ctx);
|
||||
}
|
||||
|
||||
static hashtab_t *enum_symtab;
|
||||
|
||||
static int
|
||||
|
@ -605,23 +722,71 @@ parse_BasePipeline (const plitem_t *item, void **data,
|
|||
|
||||
#include "libs/video/renderer/vulkan/vkparse.cinc"
|
||||
|
||||
static exprsym_t imageset_symbols[] = {
|
||||
{"size", &cexpr_size_t, (void *)field_offset (qfv_imageset_t, size)},
|
||||
static void
|
||||
imageviewset_index (const exprval_t *a, size_t index, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
__auto_type set = *(qfv_imageviewset_t **) a->value;
|
||||
exprval_t *val = 0;
|
||||
if (index >= set->size) {
|
||||
cexpr_error (ctx, "invalid index: %zd", index);
|
||||
} else {
|
||||
val = cexpr_value (&imageview_type, ctx);
|
||||
*(VkImageView *) val->value = set->a[index];
|
||||
}
|
||||
*(exprval_t **) c->value = val;
|
||||
}
|
||||
|
||||
static void
|
||||
imageviewset_int (const exprval_t *a, const exprval_t *b, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
size_t index = *(int *) b->value;
|
||||
imageviewset_index (a, index, c, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
imageviewset_uint (const exprval_t *a, const exprval_t *b, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
size_t index = *(unsigned *) b->value;
|
||||
imageviewset_index (a, index, c, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
imageviewset_size_t (const exprval_t *a, const exprval_t *b, exprval_t *c,
|
||||
exprctx_t *ctx)
|
||||
{
|
||||
size_t index = *(size_t *) b->value;
|
||||
imageviewset_index (a, index, c, ctx);
|
||||
}
|
||||
|
||||
binop_t imageviewset_binops[] = {
|
||||
{ '.', &cexpr_field, &cexpr_exprval, cexpr_struct_pointer_getfield },
|
||||
{ '[', &cexpr_int, &imageview_type, imageviewset_int },
|
||||
{ '[', &cexpr_uint, &imageview_type, imageviewset_uint },
|
||||
{ '[', &cexpr_size_t, &imageview_type, imageviewset_size_t },
|
||||
{}
|
||||
};
|
||||
|
||||
static exprsym_t imageviewset_symbols[] = {
|
||||
{"size", &cexpr_size_t, (void *)field_offset (qfv_imageviewset_t, size)},
|
||||
{ }
|
||||
};
|
||||
static exprtab_t imageset_symtab = {
|
||||
imageset_symbols,
|
||||
static exprtab_t imageviewset_symtab = {
|
||||
imageviewset_symbols,
|
||||
};
|
||||
exprtype_t imageset_type = {
|
||||
"imageset",
|
||||
sizeof (qfv_imageset_t *),
|
||||
cexpr_struct_pointer_binops,
|
||||
exprtype_t imageviewset_type = {
|
||||
"imageviewset",
|
||||
sizeof (qfv_imageviewset_t *),
|
||||
imageviewset_binops,
|
||||
0,
|
||||
&imageset_symtab,
|
||||
&imageviewset_symtab,
|
||||
};
|
||||
static exprsym_t qfv_swapchain_t_symbols[] = {
|
||||
{"format", &VkFormat_type, (void *)field_offset (qfv_swapchain_t, format)},
|
||||
{"images", &imageset_type, (void *)field_offset (qfv_swapchain_t, images)},
|
||||
{"extent", &VkExtent2D_type, (void *)field_offset (qfv_swapchain_t, extent)},
|
||||
{"views", &imageviewset_type, (void *)field_offset (qfv_swapchain_t, imageViews)},
|
||||
{ }
|
||||
};
|
||||
static exprtab_t qfv_swapchain_t_symtab = {
|
||||
|
@ -714,7 +879,7 @@ QFV_InitParse (vulkan_ctx_t *ctx)
|
|||
vkgen_init_symtabs (&context);
|
||||
cexpr_init_symtab (&qfv_swapchain_t_symtab, &context);
|
||||
cexpr_init_symtab (&vulkan_frameset_t_symtab, &context);
|
||||
cexpr_init_symtab (&imageset_symtab, &context);
|
||||
cexpr_init_symtab (&imageviewset_symtab, &context);
|
||||
|
||||
if (!ctx->setLayouts) {
|
||||
ctx->shaderModules = handlref_symtab (shaderModule_free, ctx);
|
||||
|
@ -722,6 +887,8 @@ QFV_InitParse (vulkan_ctx_t *ctx)
|
|||
ctx->pipelineLayouts = handlref_symtab (pipelineLayout_free, ctx);
|
||||
ctx->descriptorPools = handlref_symtab (descriptorPool_free, ctx);
|
||||
ctx->samplers = handlref_symtab (sampler_free, ctx);
|
||||
ctx->images = handlref_symtab (image_free, ctx);
|
||||
ctx->imageViews = handlref_symtab (imageView_free, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -733,16 +900,17 @@ QFV_GetEnum (const char *name)
|
|||
|
||||
static int
|
||||
parse_object (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plparser_t parser, void *object)
|
||||
plparser_t parser, void *object, plitem_t *properties)
|
||||
{
|
||||
plitem_t *messages = PL_NewArray ();
|
||||
exprctx_t exprctx = {};
|
||||
parsectx_t parsectx = { &exprctx, ctx };
|
||||
parsectx_t parsectx = { &exprctx, ctx, properties };
|
||||
exprsym_t var_syms[] = {
|
||||
{"swapchain", &qfv_swapchain_t_type, ctx->swapchain},
|
||||
{"frames", &vulkan_frameset_t_type, &ctx->frames},
|
||||
{"msaaSamples", &VkSampleCountFlagBits_type, &ctx->msaaSamples},
|
||||
{QFV_PROPERTIES, &cexpr_plitem, &ctx->pipelineDef},
|
||||
{"swapImageIndex", &cexpr_uint, &ctx->swapImageIndex},
|
||||
{QFV_PROPERTIES, &cexpr_plitem, &parsectx.properties},
|
||||
{}
|
||||
};
|
||||
exprtab_t vars_tab = { var_syms, 0 };
|
||||
|
@ -775,13 +943,14 @@ parse_qfv_renderpass (const plfield_t *field, const plitem_t *item, void *data,
|
|||
}
|
||||
|
||||
VkRenderPass
|
||||
QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist)
|
||||
QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
|
||||
qfv_renderpass_t renderpass_data = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_qfv_renderpass, &renderpass_data)) {
|
||||
if (!parse_object (ctx, plist, parse_qfv_renderpass, &renderpass_data,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -805,7 +974,7 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
}
|
||||
|
||||
VkPipeline
|
||||
QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist)
|
||||
QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
|
||||
|
@ -813,11 +982,11 @@ QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
memset (&cInfo->a[0], 0, sizeof (cInfo->a[0]));
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkGraphicsPipelineCreateInfo,
|
||||
&cInfo->a[0])) {
|
||||
&cInfo->a[0], properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cInfo->a[0].renderPass = ctx->renderpass.renderpass;
|
||||
cInfo->a[0].renderPass = ctx->renderpass;
|
||||
__auto_type plSet = QFV_CreateGraphicsPipelines (device, 0, cInfo);
|
||||
VkPipeline pipeline = plSet->a[0];
|
||||
free (plSet);
|
||||
|
@ -825,14 +994,16 @@ QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
}
|
||||
|
||||
VkDescriptorPool
|
||||
QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist)
|
||||
QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
VkDescriptorPoolCreateInfo cInfo = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkDescriptorPoolCreateInfo, &cInfo)) {
|
||||
if (!parse_object (ctx, plist, parse_VkDescriptorPoolCreateInfo, &cInfo,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -843,7 +1014,8 @@ QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
}
|
||||
|
||||
VkDescriptorSetLayout
|
||||
QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx, plitem_t *plist)
|
||||
QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
@ -851,7 +1023,7 @@ QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
VkDescriptorSetLayoutCreateInfo cInfo = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkDescriptorSetLayoutCreateInfo,
|
||||
&cInfo)) {
|
||||
&cInfo, properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -862,7 +1034,8 @@ QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
}
|
||||
|
||||
VkPipelineLayout
|
||||
QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist)
|
||||
QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
@ -870,7 +1043,7 @@ QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
VkPipelineLayoutCreateInfo cInfo = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkPipelineLayoutCreateInfo,
|
||||
&cInfo)) {
|
||||
&cInfo, properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -881,14 +1054,15 @@ QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
}
|
||||
|
||||
VkSampler
|
||||
QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist)
|
||||
QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
VkSamplerCreateInfo cInfo = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkSamplerCreateInfo, &cInfo)) {
|
||||
if (!parse_object (ctx, plist, parse_VkSamplerCreateInfo, &cInfo,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -897,3 +1071,195 @@ QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist)
|
|||
|
||||
return sampler;
|
||||
}
|
||||
|
||||
VkImage
|
||||
QFV_ParseImage (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
VkImageCreateInfo cInfo = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkImageCreateInfo, &cInfo,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
VkImage image;
|
||||
dfunc->vkCreateImage (device->dev, &cInfo, 0, &image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
VkImageView
|
||||
QFV_ParseImageView (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
VkImageViewCreateInfo cInfo = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkImageViewCreateInfo, &cInfo,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
VkImageView imageView;
|
||||
dfunc->vkCreateImageView (device->dev, &cInfo, 0, &imageView);
|
||||
|
||||
return imageView;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t count;
|
||||
VkImageCreateInfo *info;
|
||||
} imagecreate_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t count;
|
||||
VkImageViewCreateInfo *info;
|
||||
} imageviewcreate_t;
|
||||
|
||||
static plelement_t qfv_imagecreate_dict = {
|
||||
QFDictionary,
|
||||
sizeof (VkImageCreateInfo),
|
||||
array_alloc,
|
||||
parse_VkImageCreateInfo,
|
||||
};
|
||||
|
||||
static plelement_t qfv_imageviewcreate_dict = {
|
||||
QFDictionary,
|
||||
sizeof (VkImageViewCreateInfo),
|
||||
array_alloc,
|
||||
parse_VkImageViewCreateInfo,
|
||||
};
|
||||
|
||||
static int
|
||||
parse_imagecreate_dict (const plfield_t *field, const plitem_t *item,
|
||||
void *data, plitem_t *messages, void *context)
|
||||
{
|
||||
plfield_t f = { "images", 0, QFArray, parse_array,
|
||||
&qfv_imagecreate_dict };
|
||||
typedef struct arr_s DARRAY_TYPE(byte) arr_t;
|
||||
arr_t *arr = 0;
|
||||
int ret;
|
||||
|
||||
if ((ret = PL_ParseLabeledArray (&f, item, &arr, messages, context))) {
|
||||
imagecreate_t *imagecreate = data;
|
||||
imagecreate->count = arr->size;
|
||||
imagecreate->info = (VkImageCreateInfo *) arr->a;
|
||||
} else {
|
||||
//FIXME leaky boat when succeeds
|
||||
if (arr) {
|
||||
free (arr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_imageviewcreate_dict (const plfield_t *field, const plitem_t *item,
|
||||
void *data, plitem_t *messages, void *context)
|
||||
{
|
||||
plfield_t f = { "images", 0, QFArray, parse_array,
|
||||
&qfv_imageviewcreate_dict };
|
||||
typedef struct arr_s DARRAY_TYPE(byte) arr_t;
|
||||
arr_t *arr = 0;
|
||||
int ret;
|
||||
|
||||
if ((ret = PL_ParseLabeledArray (&f, item, &arr, messages, context))) {
|
||||
imageviewcreate_t *imageviewcreate = data;
|
||||
imageviewcreate->count = arr->size;
|
||||
imageviewcreate->info = (VkImageViewCreateInfo *) arr->a;
|
||||
} else {
|
||||
//FIXME leaky boat when succeeds
|
||||
if (arr) {
|
||||
free (arr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
qfv_imageset_t *
|
||||
QFV_ParseImageSet (vulkan_ctx_t *ctx, plitem_t *item, plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
imagecreate_t create = {};
|
||||
|
||||
pltype_t type = PL_Type (item);
|
||||
|
||||
if (type == QFDictionary) {
|
||||
if (!parse_object (ctx, item, parse_imagecreate_dict, &create,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
Sys_Printf ("Neither array nor dictionary: %d\n", PL_Line (item));
|
||||
return 0;
|
||||
}
|
||||
|
||||
__auto_type set = QFV_AllocImages (create.count, malloc);
|
||||
for (uint32_t i = 0; i < create.count; i++) {
|
||||
dfunc->vkCreateImage (device->dev, &create.info[i], 0, &set->a[i]);
|
||||
|
||||
const char *name = PL_KeyAtIndex (item, i);
|
||||
name = va (ctx->va_ctx, "$"QFV_PROPERTIES".images.%s", name);
|
||||
QFV_AddHandle (ctx->images, name, (uint64_t) set->a[i]);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
qfv_imageviewset_t *
|
||||
QFV_ParseImageViewSet (vulkan_ctx_t *ctx, plitem_t *item,
|
||||
plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
imageviewcreate_t create = {};
|
||||
|
||||
pltype_t type = PL_Type (item);
|
||||
|
||||
if (type == QFDictionary) {
|
||||
if (!parse_object (ctx, item, parse_imageviewcreate_dict, &create,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
Sys_Printf ("Neither array nor dictionary: %d\n", PL_Line (item));
|
||||
return 0;
|
||||
}
|
||||
|
||||
__auto_type set = QFV_AllocImageViews (create.count, malloc);
|
||||
for (uint32_t i = 0; i < create.count; i++) {
|
||||
dfunc->vkCreateImageView (device->dev, &create.info[i], 0, &set->a[i]);
|
||||
|
||||
const char *name = PL_KeyAtIndex (item, i);
|
||||
name = va (ctx->va_ctx, "$"QFV_PROPERTIES".imageViews.%s", name);
|
||||
QFV_AddHandle (ctx->imageViews, name, (uint64_t) set->a[i]);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
VkFramebuffer
|
||||
QFV_ParseFramebuffer (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
VkFramebufferCreateInfo cInfo = {};
|
||||
|
||||
if (!parse_object (ctx, plist, parse_VkFramebufferCreateInfo, &cInfo,
|
||||
properties)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
VkFramebuffer framebuffer;
|
||||
dfunc->vkCreateFramebuffer (device->dev, &cInfo, 0, &framebuffer);
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
typedef struct parsectx_s {
|
||||
struct exprctx_s *ectx;
|
||||
struct vulkan_ctx_s *vctx;
|
||||
struct plitem_s *properties;
|
||||
void *data;
|
||||
} parsectx_t;
|
||||
|
||||
#include "QF/cexpr.h"
|
||||
|
@ -32,12 +34,29 @@ exprenum_t *QFV_GetEnum (const char *name);
|
|||
uint64_t QFV_GetHandle (struct hashtab_s *tab, const char *name);
|
||||
void QFV_AddHandle (struct hashtab_s *tab, const char *name, uint64_t handle);
|
||||
|
||||
VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist);
|
||||
VkPipeline QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist);
|
||||
VkDescriptorPool QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist);
|
||||
VkRenderPass QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkPipeline QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkDescriptorPool QFV_ParseDescriptorPool (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkDescriptorSetLayout QFV_ParseDescriptorSetLayout (vulkan_ctx_t *ctx,
|
||||
plitem_t *plist);
|
||||
VkPipelineLayout QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist);
|
||||
VkSampler QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist);
|
||||
plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkPipelineLayout QFV_ParsePipelineLayout (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkSampler QFV_ParseSampler (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkImage QFV_ParseImage (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkImageView QFV_ParseImageView (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
struct qfv_imageset_s *QFV_ParseImageSet (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
struct qfv_imageviewset_s *QFV_ParseImageViewSet (vulkan_ctx_t *ctx,
|
||||
plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
VkFramebuffer QFV_ParseFramebuffer (vulkan_ctx_t *ctx, plitem_t *plist,
|
||||
plitem_t *properties);
|
||||
|
||||
#endif//__vkparse_h
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
VkGraphicsPipelineCreateInfo,
|
||||
VkDescriptorPoolCreateInfo,
|
||||
VkSamplerCreateInfo,
|
||||
VkImageCreateInfo,
|
||||
VkImageViewCreateInfo,
|
||||
VkFramebufferCreateInfo,
|
||||
);
|
||||
parse = {
|
||||
VkSubpassDescription = {
|
||||
|
@ -282,6 +285,48 @@
|
|||
fields = (basePipelineHandle);
|
||||
};
|
||||
basePipelineIndex = auto;
|
||||
};
|
||||
VkImageCreateInfo = {
|
||||
flags = auto;
|
||||
imageType = auto;
|
||||
format = auto;
|
||||
extent = auto;
|
||||
mipLevels = auto;
|
||||
arrayLayers = auto;
|
||||
samples = auto;
|
||||
tiling = auto;
|
||||
usage = auto;
|
||||
sharingMode = skip; // FIXME for now
|
||||
queueFamilyIndexCount = skip; // FIXME for now
|
||||
pQueueFamilyIndices = skip; // FIXME for now
|
||||
initialLayout = auto;
|
||||
};
|
||||
VkImageViewCreateInfo = {
|
||||
flags = auto;
|
||||
image = {
|
||||
type = (custom, (QFDictionary, QFString),
|
||||
parse_VkImage);
|
||||
fields = (image);
|
||||
};
|
||||
viewType = auto;
|
||||
format = auto;
|
||||
components = auto;
|
||||
subresourceRange = auto;
|
||||
};
|
||||
VkFramebufferCreateInfo = {
|
||||
//flags = auto; reserved for future use (Bits enum does not exist)
|
||||
renderPass = {
|
||||
type = (custom, QFString, parse_VkShaderModule);
|
||||
fields = (renderPass);
|
||||
};
|
||||
attachments = {
|
||||
type = (array, VkImageView);
|
||||
size = attachmentCount;
|
||||
values = pAttachments;
|
||||
};
|
||||
width = auto;
|
||||
height = auto;
|
||||
layers = auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,16 +64,65 @@
|
|||
#include "r_internal.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
void
|
||||
Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx)
|
||||
static const char *alias_pass_names[] = {
|
||||
"depth",
|
||||
"g-buffer",
|
||||
"translucent",
|
||||
};
|
||||
|
||||
static void
|
||||
emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
||||
qfv_alias_skin_t *skin,
|
||||
void *vert_constants, int vert_size,
|
||||
void *frag_constants, int frag_size,
|
||||
aliashdr_t *hdr, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
|
||||
|
||||
__auto_type mesh = (qfv_alias_mesh_t *) ((byte *) hdr + hdr->commands);
|
||||
|
||||
VkDeviceSize offsets[] = {
|
||||
pose1 * hdr->poseverts * sizeof (aliasvrt_t),
|
||||
pose2 * hdr->poseverts * sizeof (aliasvrt_t),
|
||||
0,
|
||||
};
|
||||
VkBuffer buffers[] = {
|
||||
mesh->vertex_buffer,
|
||||
mesh->vertex_buffer,
|
||||
mesh->uv_buffer,
|
||||
};
|
||||
int bindingCount = skin ? 3 : 2;
|
||||
|
||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, bindingCount, buffers, offsets);
|
||||
dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0,
|
||||
VK_INDEX_TYPE_UINT32);
|
||||
dfunc->vkCmdPushConstants (cmd, actx->layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, vert_size, vert_constants);
|
||||
if (skin) {
|
||||
dfunc->vkCmdPushConstants (cmd, actx->layout,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
68, frag_size, frag_constants);
|
||||
aframe->imageInfo[0].imageView = skin->view;
|
||||
dfunc->vkCmdPushDescriptorSetKHR (cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
actx->layout,
|
||||
0, ALIAS_IMAGE_INFOS,
|
||||
aframe->descriptors
|
||||
+ ALIAS_BUFFER_INFOS);
|
||||
}
|
||||
dfunc->vkCmdDrawIndexed (cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DrawAlias (entity_t *ent, vulkan_ctx_t *ctx)
|
||||
{
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
|
||||
model_t *model = ent->model;
|
||||
aliashdr_t *hdr;
|
||||
qfv_alias_mesh_t *mesh;
|
||||
qfv_alias_skin_t *skin;
|
||||
float vertex_constants[17];
|
||||
byte fragment_constants[3][4];
|
||||
|
@ -81,7 +130,6 @@ Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx)
|
|||
if (!(hdr = model->aliashdr)) {
|
||||
hdr = Cache_Get (&model->cache);
|
||||
}
|
||||
mesh = (qfv_alias_mesh_t *) ((byte *) hdr + hdr->commands);
|
||||
|
||||
memcpy (vertex_constants, ent->transform, sizeof (ent->transform));
|
||||
vertex_constants[16] = R_AliasGetLerpedFrames (ent, hdr);
|
||||
|
@ -97,90 +145,26 @@ Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx)
|
|||
QuatCopy (skin->colora, fragment_constants[1]);
|
||||
QuatCopy (skin->colorb, fragment_constants[2]);
|
||||
|
||||
VkDeviceSize offsets[] = {
|
||||
ent->pose1 * hdr->poseverts * sizeof (aliasvrt_t),
|
||||
ent->pose2 * hdr->poseverts * sizeof (aliasvrt_t),
|
||||
0,
|
||||
};
|
||||
VkBuffer buffers[] = {
|
||||
mesh->vertex_buffer,
|
||||
mesh->vertex_buffer,
|
||||
mesh->uv_buffer,
|
||||
};
|
||||
dfunc->vkCmdBindVertexBuffers (aframe->cmd, 0, 3, buffers, offsets);
|
||||
dfunc->vkCmdBindIndexBuffer (aframe->cmd, mesh->index_buffer, 0,
|
||||
VK_INDEX_TYPE_UINT32);
|
||||
dfunc->vkCmdPushConstants (aframe->cmd, actx->layout,
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, sizeof (vertex_constants), vertex_constants);
|
||||
dfunc->vkCmdPushConstants (aframe->cmd, actx->layout,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
68, sizeof (fragment_constants),
|
||||
fragment_constants);
|
||||
aframe->imageInfo[0].imageView = skin->view;
|
||||
dfunc->vkCmdPushDescriptorSetKHR (aframe->cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
actx->layout,
|
||||
0, ALIAS_IMAGE_INFOS,
|
||||
aframe->descriptors
|
||||
+ ALIAS_BUFFER_INFOS);
|
||||
dfunc->vkCmdDrawIndexed (aframe->cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0);
|
||||
emit_commands (aframe->cmdSet.a[QFV_aliasDepth], ent->pose1, ent->pose2,
|
||||
0, vertex_constants, sizeof (vertex_constants),
|
||||
fragment_constants, sizeof (fragment_constants),
|
||||
hdr, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
calc_lighting (qfv_light_t *light, entity_t *ent)
|
||||
{
|
||||
vec3_t ambient_color;
|
||||
//FIXME should be ent->position
|
||||
float l = R_LightPoint (&r_worldentity.model->brush, r_origin) / 128.0;
|
||||
|
||||
//XXX l = max (light, max (ent->model->min_light, ent->min_light));
|
||||
light->type = 2;
|
||||
VectorSet (1, 1, 1, ambient_color); //FIXME
|
||||
// position doubles as ambient light
|
||||
VectorScale (ambient_color, l, light->position);
|
||||
VectorSet (-1, 0, 0, light->direction); //FIXME
|
||||
VectorCopy (light->position, light->color);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_AliasBegin (vulkan_ctx_t *ctx)
|
||||
alias_begin_subpass (VkCommandBuffer cmd, VkPipeline pipeline,
|
||||
vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
|
||||
dlight_t *lights[ALIAS_LIGHTS];
|
||||
//XXX quat_t fog;
|
||||
|
||||
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
|
||||
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
|
||||
VkCommandBuffer cmd = aframe->cmd;
|
||||
DARRAY_APPEND (cframe->subCommand, cmd);
|
||||
|
||||
//FIXME ambient needs to be per entity
|
||||
aframe->lights->light_count = 1;
|
||||
calc_lighting (&aframe->lights->lights[0], 0);
|
||||
R_FindNearLights (r_origin, ALIAS_LIGHTS - 1, lights);
|
||||
for (int i = 0; i < ALIAS_LIGHTS - 1; i++) {
|
||||
if (!lights[i]) {
|
||||
break;
|
||||
}
|
||||
aframe->lights->light_count++;
|
||||
VectorCopy (lights[i]->color, aframe->lights->lights[i + 1].color);
|
||||
VectorCopy (lights[i]->origin, aframe->lights->lights[i + 1].position);
|
||||
aframe->lights->lights[i + 1].dist = lights[i]->radius;
|
||||
aframe->lights->lights[i + 1].type = 0;
|
||||
}
|
||||
|
||||
//FIXME need per frame matrices
|
||||
aframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d;
|
||||
aframe->bufferInfo[1].buffer = aframe->light_buffer;
|
||||
|
||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
ctx->renderpass.renderpass, 0,
|
||||
ctx->renderpass, 0,
|
||||
cframe->framebuffer,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
@ -192,7 +176,7 @@ Vulkan_AliasBegin (vulkan_ctx_t *ctx)
|
|||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||
|
||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
actx->pipeline);
|
||||
pipeline);
|
||||
//VkDescriptorSet sets[] = {
|
||||
// aframe->descriptors[0].dstSet,
|
||||
// aframe->descriptors[1].dstSet,
|
||||
|
@ -213,15 +197,43 @@ Vulkan_AliasBegin (vulkan_ctx_t *ctx)
|
|||
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_AliasEnd (vulkan_ctx_t *ctx)
|
||||
static void
|
||||
alias_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_AliasBegin (vulkan_ctx_t *ctx)
|
||||
{
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
|
||||
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
|
||||
dfunc->vkEndCommandBuffer (aframe->cmd);
|
||||
|
||||
//XXX quat_t fog;
|
||||
DARRAY_APPEND (&cframe->cmdSets[QFV_passDepth],
|
||||
aframe->cmdSet.a[QFV_aliasDepth]);
|
||||
DARRAY_APPEND (&cframe->cmdSets[QFV_passGBuffer],
|
||||
aframe->cmdSet.a[QFV_aliasGBuffer]);
|
||||
|
||||
//FIXME need per frame matrices
|
||||
aframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d;
|
||||
|
||||
alias_begin_subpass (aframe->cmdSet.a[QFV_aliasDepth], actx->depth, ctx);
|
||||
alias_begin_subpass (aframe->cmdSet.a[QFV_aliasGBuffer], actx->gbuf, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_AliasEnd (vulkan_ctx_t *ctx)
|
||||
{
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
|
||||
|
||||
alias_end_subpass (aframe->cmdSet.a[QFV_aliasDepth], ctx);
|
||||
alias_end_subpass (aframe->cmdSet.a[QFV_aliasGBuffer], ctx);
|
||||
}
|
||||
|
||||
static VkDescriptorBufferInfo base_buffer_info = {
|
||||
|
@ -247,7 +259,6 @@ void
|
|||
Vulkan_Alias_Init (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
aliasctx_t *actx = calloc (1, sizeof (aliasctx_t));
|
||||
ctx->alias_context = actx;
|
||||
|
@ -257,7 +268,8 @@ Vulkan_Alias_Init (vulkan_ctx_t *ctx)
|
|||
DARRAY_RESIZE (&actx->frames, frames);
|
||||
actx->frames.grow = 0;
|
||||
|
||||
actx->pipeline = Vulkan_CreatePipeline (ctx, "alias");
|
||||
actx->depth = Vulkan_CreatePipeline (ctx, "alias_depth");
|
||||
actx->gbuf = Vulkan_CreatePipeline (ctx, "alias_gbuf");
|
||||
actx->layout = Vulkan_CreatePipelineLayout (ctx, "alias_layout");
|
||||
actx->sampler = Vulkan_CreateSampler (ctx, "alias_sampler");
|
||||
|
||||
|
@ -276,43 +288,22 @@ Vulkan_Alias_Init (vulkan_ctx_t *ctx)
|
|||
}*/
|
||||
//__auto_type pool = QFV_GetDescriptorPool (ctx, "alias.pool");
|
||||
|
||||
__auto_type cmdBuffers = QFV_AllocCommandBufferSet (frames, alloca);
|
||||
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, cmdBuffers);
|
||||
|
||||
__auto_type lbuffers = QFV_AllocBufferSet (frames, alloca);
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
lbuffers->a[i] = QFV_CreateBuffer (device, sizeof (qfv_light_buffer_t),
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_BUFFER,
|
||||
lbuffers->a[i],
|
||||
va (ctx->va_ctx, "buffer:alias:%s:%zd",
|
||||
"lights", i));
|
||||
}
|
||||
VkMemoryRequirements requirements;
|
||||
dfunc->vkGetBufferMemoryRequirements (device->dev, lbuffers->a[0],
|
||||
&requirements);
|
||||
actx->light_memory = QFV_AllocBufferMemory (device, lbuffers->a[0],
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||
frames * requirements.size, 0);
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY,
|
||||
actx->light_memory, va (ctx->va_ctx,
|
||||
"memory:alias:%s", "lights"));
|
||||
byte *light_data;
|
||||
dfunc->vkMapMemory (device->dev, actx->light_memory, 0,
|
||||
frames * requirements.size, 0, (void **) &light_data);
|
||||
|
||||
//__auto_type sets = QFV_AllocateDescriptorSet (device, pool, layouts);
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
__auto_type aframe = &actx->frames.a[i];
|
||||
aframe->cmd = cmdBuffers->a[i];
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
aframe->cmd,
|
||||
va (ctx->va_ctx, "cmd:alias:%zd", i));
|
||||
aframe->light_buffer = lbuffers->a[i];
|
||||
aframe->lights = (qfv_light_buffer_t *) (light_data + i * requirements.size);
|
||||
QFV_BindBufferMemory (device, lbuffers->a[i], actx->light_memory,
|
||||
i * requirements.size);
|
||||
|
||||
DARRAY_INIT (&aframe->cmdSet, QFV_aliasNumPasses);
|
||||
DARRAY_RESIZE (&aframe->cmdSet, QFV_aliasNumPasses);
|
||||
aframe->cmdSet.grow = 0;
|
||||
|
||||
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, &aframe->cmdSet);
|
||||
|
||||
for (int j = 0; j < QFV_aliasNumPasses; j++) {
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
aframe->cmdSet.a[j],
|
||||
va (ctx->va_ctx, "cmd:alias:%zd:%s", i,
|
||||
alias_pass_names[j]));
|
||||
}
|
||||
for (int j = 0; j < ALIAS_BUFFER_INFOS; j++) {
|
||||
aframe->bufferInfo[j] = base_buffer_info;
|
||||
aframe->descriptors[j] = base_buffer_write;
|
||||
|
@ -333,7 +324,7 @@ Vulkan_Alias_Init (vulkan_ctx_t *ctx)
|
|||
}
|
||||
|
||||
void
|
||||
Vulkan_Alias_Shutdown (struct vulkan_ctx_s *ctx)
|
||||
Vulkan_Alias_Shutdown (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
@ -341,11 +332,11 @@ Vulkan_Alias_Shutdown (struct vulkan_ctx_s *ctx)
|
|||
|
||||
for (size_t i = 0; i < actx->frames.size; i++) {
|
||||
__auto_type aframe = &actx->frames.a[i];
|
||||
dfunc->vkDestroyBuffer (device->dev, aframe->light_buffer, 0);
|
||||
free (aframe->cmdSet.a);
|
||||
}
|
||||
dfunc->vkFreeMemory (device->dev, actx->light_memory, 0);
|
||||
|
||||
dfunc->vkDestroyPipeline (device->dev, actx->pipeline, 0);
|
||||
DARRAY_CLEAR (&actx->frames);
|
||||
dfunc->vkDestroyPipeline (device->dev, actx->depth, 0);
|
||||
dfunc->vkDestroyPipeline (device->dev, actx->gbuf, 0);
|
||||
free (actx->frames.a);
|
||||
free (actx);
|
||||
}
|
||||
|
|
|
@ -69,6 +69,12 @@
|
|||
#include "r_internal.h"
|
||||
#include "vid_vulkan.h"
|
||||
|
||||
static const char *bsp_pass_names[] = {
|
||||
"depth",
|
||||
"g-buffer",
|
||||
"translucent",
|
||||
};
|
||||
|
||||
static float identity[] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
|
@ -779,33 +785,44 @@ bind_view (qfv_bsp_tex tex, VkImageView view, bspframe_t *bframe,
|
|||
+ BSP_BUFFER_INFOS);
|
||||
}
|
||||
|
||||
static void
|
||||
push_transform (vec_t *transform, VkPipelineLayout layout,
|
||||
qfv_devfuncs_t *dfunc, VkCommandBuffer cmd)
|
||||
{
|
||||
dfunc->vkCmdPushConstants (cmd, layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, 16 * sizeof (float), transform);
|
||||
}
|
||||
|
||||
static void
|
||||
push_fragconst (fragconst_t *fragconst, VkPipelineLayout layout,
|
||||
qfv_devfuncs_t *dfunc, VkCommandBuffer cmd)
|
||||
{
|
||||
dfunc->vkCmdPushConstants (cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, sizeof (fragconst_t), fragconst);
|
||||
}
|
||||
|
||||
static void
|
||||
push_descriptors (int count, VkWriteDescriptorSet *descriptors,
|
||||
VkPipelineLayout layout, qfv_devfuncs_t *dfunc,
|
||||
VkCommandBuffer cmd)
|
||||
{
|
||||
dfunc->vkCmdPushDescriptorSetKHR (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout, 0, count, descriptors);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_elechain (elechain_t *ec, VkPipelineLayout layout, qfv_devfuncs_t *dfunc,
|
||||
VkCommandBuffer cmd)
|
||||
{
|
||||
elements_t *el;
|
||||
|
||||
/*if (colloc >= 0) {
|
||||
float *color;
|
||||
color = ec->color;
|
||||
if (!color)
|
||||
color = bctx->default_color;
|
||||
if (!QuatCompare (color, bctx->last_color)) {
|
||||
QuatCopy (color, bctx->last_color);
|
||||
qfeglVertexAttrib4fv (quake_bsp.color.location, color);
|
||||
}
|
||||
}*/
|
||||
if (ec->transform) {
|
||||
dfunc->vkCmdPushConstants (cmd, layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, 16 * sizeof (float), ec->transform);
|
||||
push_transform (ec->transform, layout, dfunc, cmd);
|
||||
} else {
|
||||
//FIXME should cache current transform
|
||||
dfunc->vkCmdPushConstants (cmd, layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, 16 * sizeof (float), identity);
|
||||
push_transform (identity, layout, dfunc, cmd);
|
||||
}
|
||||
for (el = ec->elements; el; el = el->next) {
|
||||
//FIXME check if these are contiguous and if so merge into one
|
||||
//command
|
||||
if (!el->index_count)
|
||||
continue;
|
||||
dfunc->vkCmdDrawIndexed (cmd, el->index_count, 1, el->first_index,
|
||||
|
@ -828,35 +845,18 @@ get_view (qfv_tex_t *tex, qfv_tex_t *default_tex)
|
|||
}
|
||||
|
||||
static void
|
||||
bsp_begin (vulkan_ctx_t *ctx)
|
||||
bsp_begin_subpass (VkCommandBuffer cmd, VkPipeline pipeline, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
//XXX quat_t fog;
|
||||
|
||||
bctx->default_color[3] = 1;
|
||||
QuatCopy (bctx->default_color, bctx->last_color);
|
||||
|
||||
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
VkCommandBuffer cmd = bframe->bsp_cmd;
|
||||
DARRAY_APPEND (cframe->subCommand, cmd);
|
||||
|
||||
//FIXME need per frame matrices
|
||||
bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d;
|
||||
bframe->imageInfo[0].imageView = 0; // set by tex chain loop
|
||||
bframe->imageInfo[1].imageView = 0; // set by tex chain loop
|
||||
bframe->imageInfo[2].imageView = QFV_ScrapImageView (bctx->light_scrap);
|
||||
bframe->imageInfo[3].imageView = get_view (bctx->skysheet_tex,
|
||||
bctx->default_skysheet);
|
||||
bframe->imageInfo[4].imageView = get_view (bctx->skybox_tex,
|
||||
bctx->default_skybox);
|
||||
|
||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
ctx->renderpass.renderpass, 0,
|
||||
ctx->renderpass, 0,
|
||||
cframe->framebuffer,
|
||||
0, 0, 0,
|
||||
};
|
||||
|
@ -868,7 +868,7 @@ bsp_begin (vulkan_ctx_t *ctx)
|
|||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||
|
||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
bctx->main);
|
||||
pipeline);
|
||||
VkViewport viewport = {0, 0, vid.width, vid.height, 0, 1};
|
||||
VkRect2D scissor = { {0, 0}, {vid.width, vid.height} };
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &viewport);
|
||||
|
@ -893,14 +893,54 @@ bsp_begin (vulkan_ctx_t *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
bsp_end (vulkan_ctx_t *ctx)
|
||||
bsp_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_begin (vulkan_ctx_t *ctx)
|
||||
{
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
//XXX quat_t fog;
|
||||
|
||||
bctx->default_color[3] = 1;
|
||||
QuatCopy (bctx->default_color, bctx->last_color);
|
||||
|
||||
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
dfunc->vkEndCommandBuffer (bframe->bsp_cmd);
|
||||
|
||||
DARRAY_APPEND (&cframe->cmdSets[QFV_passDepth],
|
||||
bframe->cmdSet.a[QFV_bspDepth]);
|
||||
DARRAY_APPEND (&cframe->cmdSets[QFV_passGBuffer],
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
|
||||
//FIXME need per frame matrices
|
||||
bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d;
|
||||
bframe->imageInfo[0].imageView = 0; // set by tex chain loop
|
||||
bframe->imageInfo[1].imageView = 0; // set by tex chain loop
|
||||
bframe->imageInfo[2].imageView = QFV_ScrapImageView (bctx->light_scrap);
|
||||
bframe->imageInfo[3].imageView = get_view (bctx->skysheet_tex,
|
||||
bctx->default_skysheet);
|
||||
bframe->imageInfo[4].imageView = get_view (bctx->skybox_tex,
|
||||
bctx->default_skybox);
|
||||
|
||||
//FIXME pipeline
|
||||
bsp_begin_subpass (bframe->cmdSet.a[QFV_bspDepth], bctx->main, ctx);
|
||||
bsp_begin_subpass (bframe->cmdSet.a[QFV_bspGBuffer], bctx->main, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
bsp_end (vulkan_ctx_t *ctx)
|
||||
{
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
|
||||
bsp_end_subpass (bframe->cmdSet.a[QFV_bspDepth], ctx);
|
||||
bsp_end_subpass (bframe->cmdSet.a[QFV_bspGBuffer], ctx);
|
||||
}
|
||||
|
||||
/*static void
|
||||
|
@ -982,8 +1022,6 @@ spin (mat4_t mat, bspctx_t *bctx)
|
|||
static void
|
||||
sky_begin (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
bctx->default_color[3] = 1;
|
||||
|
@ -993,8 +1031,10 @@ sky_begin (vulkan_ctx_t *ctx)
|
|||
|
||||
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
VkCommandBuffer cmd = bframe->sky_cmd;
|
||||
DARRAY_APPEND (cframe->subCommand, cmd);
|
||||
|
||||
//FIXME where should skys go? g-buffer is overkill. Translucent pre-pass?
|
||||
DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent],
|
||||
bframe->cmdSet.a[QFV_bspTranslucent]);
|
||||
|
||||
//FIXME need per frame matrices
|
||||
bframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d;
|
||||
|
@ -1006,54 +1046,18 @@ sky_begin (vulkan_ctx_t *ctx)
|
|||
bframe->imageInfo[4].imageView = get_view (bctx->skybox_tex,
|
||||
bctx->default_skybox);
|
||||
|
||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
ctx->renderpass.renderpass, 0,
|
||||
cframe->framebuffer,
|
||||
0, 0, 0,
|
||||
};
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
||||
| VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &inherit,
|
||||
};
|
||||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||
|
||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
bctx->sky);
|
||||
VkViewport viewport = {0, 0, vid.width, vid.height, 0, 1};
|
||||
VkRect2D scissor = { {0, 0}, {vid.width, vid.height} };
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &scissor);
|
||||
|
||||
VkDeviceSize offsets[] = { 0 };
|
||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, 1, &bctx->vertex_buffer, offsets);
|
||||
dfunc->vkCmdBindIndexBuffer (cmd, bctx->index_buffer, bframe->index_offset,
|
||||
VK_INDEX_TYPE_UINT32);
|
||||
|
||||
// push VP matrices
|
||||
dfunc->vkCmdPushDescriptorSetKHR (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
bctx->layout,
|
||||
0, 1, bframe->descriptors + 0);
|
||||
// push static images
|
||||
dfunc->vkCmdPushDescriptorSetKHR (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
bctx->layout,
|
||||
0, 5, bframe->descriptors + 1);
|
||||
|
||||
//XXX glsl_Fog_GetColor (fog);
|
||||
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
|
||||
//FIXME sky pass
|
||||
bsp_begin_subpass (bframe->cmdSet.a[QFV_bspTranslucent], bctx->sky, ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
sky_end (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
|
||||
dfunc->vkEndCommandBuffer (bframe->sky_cmd);
|
||||
|
||||
//FIXME sky pass
|
||||
bsp_end_subpass (bframe->cmdSet.a[QFV_bspTranslucent], ctx);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -1133,13 +1137,13 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx)
|
|||
Vulkan_FlushLightmaps (ctx);
|
||||
bsp_begin (ctx);
|
||||
|
||||
dfunc->vkCmdPushConstants (bframe->bsp_cmd, bctx->layout,
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, 16 * sizeof (float), identity);
|
||||
push_transform (identity, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspDepth]);
|
||||
push_transform (identity, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
fragconst_t frag_constants = { time: vr_data.realtime };
|
||||
dfunc->vkCmdPushConstants (bframe->bsp_cmd, bctx->layout,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
64, sizeof (fragconst_t), &frag_constants);
|
||||
push_fragconst (&frag_constants, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
//XXX qfeglActiveTexture (GL_TEXTURE0 + 0);
|
||||
for (size_t i = 0; i < bctx->texture_chains.size; i++) {
|
||||
vulktex_t *tex;
|
||||
|
@ -1153,13 +1157,15 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx)
|
|||
ctx->default_white);
|
||||
bframe->imageInfo[1].imageView = get_view (tex->glow,
|
||||
ctx->default_black);
|
||||
dfunc->vkCmdPushDescriptorSetKHR (bframe->bsp_cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
bctx->layout,
|
||||
0, 2, bframe->descriptors + 1);
|
||||
|
||||
push_descriptors (2, bframe->descriptors + 1, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc, bframe->bsp_cmd);
|
||||
draw_elechain (ec, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspDepth]);
|
||||
draw_elechain (ec, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
}
|
||||
tex->elechain = 0;
|
||||
tex->elechain_tail = &tex->elechain;
|
||||
|
@ -1246,22 +1252,24 @@ Vulkan_DrawSky (vulkan_ctx_t *ctx)
|
|||
return;
|
||||
|
||||
sky_begin (ctx);
|
||||
dfunc->vkCmdPushConstants (bframe->sky_cmd, bctx->layout,
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, 16 * sizeof (float), identity);
|
||||
//FIXME sky pass
|
||||
push_transform (identity, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTranslucent]);
|
||||
fragconst_t frag_constants = { time: vr_data.realtime };
|
||||
dfunc->vkCmdPushConstants (bframe->sky_cmd, bctx->layout,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
64, sizeof (fragconst_t), &frag_constants);
|
||||
push_fragconst (&frag_constants, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTranslucent]);
|
||||
for (is = bctx->sky_chain; is; is = is->tex_chain) {
|
||||
surf = is->surface;
|
||||
if (tex != surf->texinfo->texture->render) {
|
||||
if (tex) {
|
||||
bind_view (qfv_bsp_skysheet,
|
||||
get_view (tex->tex, ctx->default_black),
|
||||
bframe, bframe->sky_cmd, bctx->layout, dfunc);
|
||||
bframe,
|
||||
bframe->cmdSet.a[QFV_bspTranslucent],//FIXME
|
||||
bctx->layout, dfunc);
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc, bframe->sky_cmd);
|
||||
draw_elechain (ec, bctx->layout, dfunc,//FIXME
|
||||
bframe->cmdSet.a[QFV_bspTranslucent]);
|
||||
}
|
||||
tex->elechain = 0;
|
||||
tex->elechain_tail = &tex->elechain;
|
||||
|
@ -1271,11 +1279,12 @@ Vulkan_DrawSky (vulkan_ctx_t *ctx)
|
|||
add_surf_elements (tex, is, &ec, &el, bctx, bframe);
|
||||
}
|
||||
if (tex) {
|
||||
bind_view (qfv_bsp_skysheet,
|
||||
get_view (tex->tex, ctx->default_black),
|
||||
bframe, bframe->sky_cmd, bctx->layout, dfunc);
|
||||
bind_view (qfv_bsp_skysheet, get_view (tex->tex, ctx->default_black),
|
||||
bframe, bframe->cmdSet.a[QFV_bspTranslucent],//FIXME
|
||||
bctx->layout, dfunc);
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc, bframe->sky_cmd);
|
||||
draw_elechain (ec, bctx->layout, dfunc,//FIXME
|
||||
bframe->cmdSet.a[QFV_bspTranslucent]);
|
||||
}
|
||||
tex->elechain = 0;
|
||||
tex->elechain_tail = &tex->elechain;
|
||||
|
@ -1453,23 +1462,21 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx)
|
|||
bctx->layout = Vulkan_CreatePipelineLayout (ctx, "quakebsp_layout");
|
||||
bctx->sampler = Vulkan_CreateSampler (ctx, "quakebsp_sampler");
|
||||
|
||||
__auto_type cmdBuffers = QFV_AllocCommandBufferSet (3 * frames, alloca);
|
||||
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, cmdBuffers);
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
__auto_type bframe = &bctx->frames.a[i];
|
||||
bframe->bsp_cmd = cmdBuffers->a[i * 3 + 0];
|
||||
bframe->turb_cmd = cmdBuffers->a[i * 3 + 1];
|
||||
bframe->sky_cmd = cmdBuffers->a[i * 3 + 2];
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
bframe->bsp_cmd,
|
||||
va (ctx->va_ctx, "cmd:bsp:%zd", i));
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
bframe->turb_cmd,
|
||||
va (ctx->va_ctx, "cmd:turb:%zd", i));
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
bframe->sky_cmd,
|
||||
va (ctx->va_ctx, "cmd:sky:%zd", i));
|
||||
|
||||
DARRAY_INIT (&bframe->cmdSet, QFV_bspNumPasses);
|
||||
DARRAY_RESIZE (&bframe->cmdSet, QFV_bspNumPasses);
|
||||
bframe->cmdSet.grow = 0;
|
||||
|
||||
QFV_AllocateCommandBuffers (device, ctx->cmdpool, 1, &bframe->cmdSet);
|
||||
|
||||
for (int j = 0; j < QFV_bspNumPasses; j++) {
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_COMMAND_BUFFER,
|
||||
bframe->cmdSet.a[i],
|
||||
va (ctx->va_ctx, "cmd:bsp:%zd:%s", i,
|
||||
bsp_pass_names[j]));
|
||||
}
|
||||
|
||||
for (int j = 0; j < BSP_BUFFER_INFOS; j++) {
|
||||
bframe->bufferInfo[j] = base_buffer_info;
|
||||
|
@ -1495,6 +1502,11 @@ Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx)
|
|||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
for (size_t i = 0; i < bctx->frames.size; i++) {
|
||||
__auto_type bframe = &bctx->frames.a[i];
|
||||
free (bframe->cmdSet.a);
|
||||
}
|
||||
|
||||
dfunc->vkDestroyPipeline (device->dev, bctx->main, 0);
|
||||
dfunc->vkDestroyPipeline (device->dev, bctx->sky, 0);
|
||||
DARRAY_CLEAR (&bctx->texture_chains);
|
||||
|
|
|
@ -696,7 +696,8 @@ Vulkan_FlushText (vulkan_ctx_t *ctx)
|
|||
drawframe_t *dframe = &dctx->frames.a[ctx->curFrame];
|
||||
|
||||
VkCommandBuffer cmd = dframe->cmd;
|
||||
DARRAY_APPEND (cframe->subCommand, cmd);
|
||||
//FIXME which pass?
|
||||
DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent], cmd);
|
||||
|
||||
VkMappedMemoryRange range = {
|
||||
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
|
||||
|
@ -708,7 +709,7 @@ Vulkan_FlushText (vulkan_ctx_t *ctx)
|
|||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
ctx->renderpass.renderpass, 0,
|
||||
ctx->renderpass, 0,
|
||||
cframe->framebuffer,
|
||||
0, 0, 0
|
||||
};
|
||||
|
|
|
@ -78,6 +78,10 @@ static const char quakeforge_pipeline[] =
|
|||
#include "libs/video/renderer/vulkan/qfpipeline.plc"
|
||||
;
|
||||
|
||||
static const char quakeforge_renderpass[] =
|
||||
#include "libs/video/renderer/vulkan/deferred.plc"
|
||||
;
|
||||
|
||||
cvar_t *vulkan_frame_count;
|
||||
cvar_t *vulkan_presentation_mode;
|
||||
cvar_t *msaaSamples;
|
||||
|
@ -163,6 +167,7 @@ void
|
|||
Vulkan_Init_Common (vulkan_ctx_t *ctx)
|
||||
{
|
||||
Sys_Printf ("Vulkan_Init_Common\n");
|
||||
|
||||
QFV_InitParse (ctx);
|
||||
Vulkan_Init_Cvars ();
|
||||
ctx->instance = QFV_CreateInstance (ctx, PACKAGE_STRING, 0x000702ff, 0, instance_extensions);//FIXME version
|
||||
|
@ -185,9 +190,9 @@ Vulkan_Shutdown_Common (vulkan_ctx_t *ctx)
|
|||
QFV_DestroyPipeline (ctx->device, ctx->pipeline);
|
||||
}
|
||||
if (ctx->frames.size) {
|
||||
Vulkan_DestroyFramebuffers (ctx);
|
||||
Vulkan_DestroyFrames (ctx);
|
||||
}
|
||||
if (ctx->renderpass.colorImage) {
|
||||
if (ctx->renderpass) {
|
||||
Vulkan_DestroyRenderPass (ctx);
|
||||
}
|
||||
if (ctx->swapchain) {
|
||||
|
@ -216,6 +221,15 @@ void
|
|||
Vulkan_CreateDevice (vulkan_ctx_t *ctx)
|
||||
{
|
||||
ctx->device = QFV_CreateDevice (ctx, device_extensions);
|
||||
|
||||
//FIXME msaa and deferred rendering...
|
||||
//also, location
|
||||
ctx->msaaSamples = 1;
|
||||
/*ctx->msaaSamples = min ((VkSampleCountFlagBits) msaaSamples->int_val,
|
||||
QFV_GetMaxSampleCount (device->physDev));
|
||||
if (ctx->msaaSamples > 1) {
|
||||
name = "renderpass_msaa";
|
||||
}*/
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -257,138 +271,54 @@ qfv_load_pipeline (vulkan_ctx_t *ctx, const char *name)
|
|||
return item;
|
||||
}
|
||||
|
||||
static plitem_t *
|
||||
qfv_load_renderpass (vulkan_ctx_t *ctx, const char *name)
|
||||
{
|
||||
if (!ctx->renderpassDef) {
|
||||
ctx->renderpassDef = PL_GetPropertyList (quakeforge_renderpass,
|
||||
&ctx->hashlinks);
|
||||
}
|
||||
|
||||
plitem_t *item = ctx->renderpassDef;
|
||||
if (!item || !(item = PL_ObjectForKey (item, name))) {
|
||||
Sys_Printf ("error loading %s\n", name);
|
||||
} else {
|
||||
Sys_Printf ("Found %s def\n", name);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_image_size (VkImage image, qfv_device_t *device)
|
||||
{
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
size_t size;
|
||||
size_t align;
|
||||
|
||||
VkMemoryRequirements requirements;
|
||||
dfunc->vkGetImageMemoryRequirements (device->dev, image, &requirements);
|
||||
size = requirements.size;
|
||||
align = requirements.alignment - 1;
|
||||
size = (size + align) & ~(align);
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_CreateRenderPass (vulkan_ctx_t *ctx)
|
||||
{
|
||||
const char *name = "renderpass";//FIXME
|
||||
qfv_device_t *device = ctx->device;
|
||||
VkDevice dev = device->dev;
|
||||
qfv_devfuncs_t *df = device->funcs;
|
||||
VkCommandBuffer cmd = ctx->cmdbuffer;
|
||||
qfv_swapchain_t *sc = ctx->swapchain;
|
||||
|
||||
ctx->msaaSamples = min ((VkSampleCountFlagBits) msaaSamples->int_val,
|
||||
QFV_GetMaxSampleCount (device->physDev));
|
||||
if (ctx->msaaSamples > 1) {
|
||||
name = "renderpass_msaa";
|
||||
}
|
||||
plitem_t *item = qfv_load_renderpass (ctx, name);
|
||||
|
||||
//FIXME a tad inconsistent
|
||||
plitem_t *item = qfv_load_pipeline (ctx, name);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
qfv_imageresource_t *colorImage = malloc (sizeof (*colorImage));
|
||||
qfv_imageresource_t *depthImage = malloc (sizeof (*depthImage));
|
||||
|
||||
VkExtent3D extent = {sc->extent.width, sc->extent.height, 1};
|
||||
|
||||
Sys_MaskPrintf (SYS_VULKAN, "color resource\n");
|
||||
colorImage->image
|
||||
= QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,
|
||||
sc->format, extent, 1, 1, ctx->msaaSamples,
|
||||
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
|
||||
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
colorImage->object
|
||||
= QFV_AllocImageMemory (device, colorImage->image,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, 0);
|
||||
QFV_BindImageMemory (device, colorImage->image, colorImage->object, 0);
|
||||
colorImage->view
|
||||
= QFV_CreateImageView (device, colorImage->image,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
sc->format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
Sys_MaskPrintf (SYS_VULKAN, " image: %p object: %p view:%p\n",
|
||||
colorImage->image, colorImage->object, colorImage->view);
|
||||
|
||||
Sys_MaskPrintf (SYS_VULKAN, "depth resource\n");
|
||||
VkFormat depthFormat = VK_FORMAT_D32_SFLOAT;
|
||||
depthImage->image
|
||||
= QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,
|
||||
depthFormat, extent, 1, 1, ctx->msaaSamples,
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
depthImage->object
|
||||
= QFV_AllocImageMemory (device, depthImage->image,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0, 0);
|
||||
QFV_BindImageMemory (device, depthImage->image, depthImage->object, 0);
|
||||
depthImage->view
|
||||
= QFV_CreateImageView (device, depthImage->image,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
Sys_MaskPrintf (SYS_VULKAN, " image: %p object: %p view:%p\n",
|
||||
depthImage->image, depthImage->object, depthImage->view);
|
||||
|
||||
VkImageMemoryBarrier barrier;
|
||||
qfv_pipelinestagepair_t stages;
|
||||
|
||||
df->vkWaitForFences (dev, 1, &ctx->fence, VK_TRUE, ~0ull);
|
||||
df->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 0,
|
||||
};
|
||||
df->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||
|
||||
stages = imageLayoutTransitionStages[qfv_LT_Undefined_to_Color];
|
||||
barrier = imageLayoutTransitionBarriers[qfv_LT_Undefined_to_Color];
|
||||
barrier.image = colorImage->image;
|
||||
|
||||
df->vkCmdPipelineBarrier (cmd, stages.src, stages.dst, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
1, &barrier);
|
||||
|
||||
stages = imageLayoutTransitionStages[qfv_LT_Undefined_to_DepthStencil];
|
||||
barrier = imageLayoutTransitionBarriers[qfv_LT_Undefined_to_DepthStencil];
|
||||
barrier.image = depthImage->image;
|
||||
if (depthFormat == VK_FORMAT_D32_SFLOAT_S8_UINT
|
||||
|| depthFormat == VK_FORMAT_D24_UNORM_S8_UINT) {
|
||||
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
|
||||
df->vkCmdPipelineBarrier (cmd, stages.src, stages.dst, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
1, &barrier);
|
||||
df->vkEndCommandBuffer (cmd);
|
||||
|
||||
VkSubmitInfo submitInfo = {
|
||||
VK_STRUCTURE_TYPE_SUBMIT_INFO, 0,
|
||||
0, 0, 0,
|
||||
1, &cmd,
|
||||
0, 0
|
||||
};
|
||||
df->vkResetFences (dev, 1, &ctx->fence);
|
||||
df->vkQueueSubmit (device->queue.queue, 1, &submitInfo, ctx->fence);
|
||||
|
||||
ctx->renderpass.colorImage = colorImage;
|
||||
ctx->renderpass.depthImage = depthImage;
|
||||
ctx->renderpass.renderpass = QFV_ParseRenderPass (ctx, item);
|
||||
ctx->renderpass = QFV_ParseRenderPass (ctx, item, ctx->renderpassDef);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_RENDER_PASS,
|
||||
ctx->renderpass.renderpass,
|
||||
va (ctx->va_ctx, "pipeline:%s", name));
|
||||
ctx->renderpass, va (ctx->va_ctx, "renderpass:%s",
|
||||
name));
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DestroyRenderPass (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
VkDevice dev = device->dev;
|
||||
qfv_devfuncs_t *df = device->funcs;
|
||||
|
||||
df->vkDestroyRenderPass (dev, ctx->renderpass.renderpass, 0);
|
||||
|
||||
df->vkDestroyImageView (dev, ctx->renderpass.colorImage->view, 0);
|
||||
df->vkDestroyImage (dev, ctx->renderpass.colorImage->image, 0);
|
||||
df->vkFreeMemory (dev, ctx->renderpass.colorImage->object, 0);
|
||||
free (ctx->renderpass.colorImage);
|
||||
ctx->renderpass.colorImage = 0;
|
||||
|
||||
df->vkDestroyImageView (dev, ctx->renderpass.depthImage->view, 0);
|
||||
df->vkDestroyImage (dev, ctx->renderpass.depthImage->image, 0);
|
||||
df->vkFreeMemory (dev, ctx->renderpass.depthImage->object, 0);
|
||||
free (ctx->renderpass.depthImage);
|
||||
ctx->renderpass.depthImage = 0;
|
||||
}
|
||||
|
||||
VkPipeline
|
||||
|
@ -401,7 +331,7 @@ Vulkan_CreatePipeline (vulkan_ctx_t *ctx, const char *name)
|
|||
} else {
|
||||
Sys_Printf ("Found pipeline def %s\n", name);
|
||||
}
|
||||
VkPipeline pipeline = QFV_ParsePipeline (ctx, item);
|
||||
VkPipeline pipeline = QFV_ParsePipeline (ctx, item, ctx->pipelineDef);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_PIPELINE, pipeline,
|
||||
va (ctx->va_ctx, "pipeline:%s", name));
|
||||
return pipeline;
|
||||
|
@ -425,7 +355,7 @@ Vulkan_CreateDescriptorPool (vulkan_ctx_t *ctx, const char *name)
|
|||
} else {
|
||||
Sys_Printf ("Found descriptor pool def %s\n", name);
|
||||
}
|
||||
pool = QFV_ParseDescriptorPool (ctx, item);
|
||||
pool = QFV_ParseDescriptorPool (ctx, item, ctx->pipelineDef);
|
||||
QFV_AddHandle (tab, path, (uint64_t) pool);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_DESCRIPTOR_POOL, pool,
|
||||
va (ctx->va_ctx, "descriptor_pool:%s", name));
|
||||
|
@ -450,7 +380,7 @@ Vulkan_CreatePipelineLayout (vulkan_ctx_t *ctx, const char *name)
|
|||
} else {
|
||||
Sys_Printf ("Found pipeline layout def %s\n", name);
|
||||
}
|
||||
layout = QFV_ParsePipelineLayout (ctx, item);
|
||||
layout = QFV_ParsePipelineLayout (ctx, item, ctx->pipelineDef);
|
||||
QFV_AddHandle (tab, path, (uint64_t) layout);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, layout,
|
||||
va (ctx->va_ctx, "pipeline_layout:%s", name));
|
||||
|
@ -475,7 +405,7 @@ Vulkan_CreateSampler (vulkan_ctx_t *ctx, const char *name)
|
|||
} else {
|
||||
Sys_Printf ("Found sampler def %s\n", name);
|
||||
}
|
||||
sampler = QFV_ParseSampler (ctx, item);
|
||||
sampler = QFV_ParseSampler (ctx, item, ctx->pipelineDef);
|
||||
QFV_AddHandle (tab, path, (uint64_t) sampler);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_SAMPLER, sampler,
|
||||
va (ctx->va_ctx, "sampler:%s", name));
|
||||
|
@ -500,7 +430,7 @@ Vulkan_CreateDescriptorSetLayout(vulkan_ctx_t *ctx, const char *name)
|
|||
} else {
|
||||
Sys_Printf ("Found descriptor set def %s\n", name);
|
||||
}
|
||||
set = QFV_ParseDescriptorSetLayout (ctx, item);
|
||||
set = QFV_ParseDescriptorSetLayout (ctx, item, ctx->pipelineDef);
|
||||
QFV_AddHandle (tab, path, (uint64_t) set);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,
|
||||
set, va (ctx->va_ctx, "descriptor_set:%s", name));
|
||||
|
@ -508,7 +438,7 @@ Vulkan_CreateDescriptorSetLayout(vulkan_ctx_t *ctx, const char *name)
|
|||
}
|
||||
|
||||
void
|
||||
Vulkan_CreateFramebuffers (vulkan_ctx_t *ctx)
|
||||
Vulkan_CreateFrames (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
VkCommandPool cmdpool = ctx->cmdpool;
|
||||
|
@ -531,13 +461,16 @@ Vulkan_CreateFramebuffers (vulkan_ctx_t *ctx)
|
|||
frame->renderDoneSemaphore = QFV_CreateSemaphore (device);
|
||||
frame->cmdBuffer = cmdBuffers->a[i];
|
||||
|
||||
frame->subCommand = malloc (sizeof (qfv_cmdbufferset_t));
|
||||
DARRAY_INIT (frame->subCommand, 4);
|
||||
frame->cmdSetCount = QFV_NumPasses;
|
||||
frame->cmdSets = malloc (QFV_NumPasses * sizeof (qfv_cmdbufferset_t));
|
||||
for (int j = 0; j < QFV_NumPasses; j++) {
|
||||
DARRAY_INIT (&frame->cmdSets[j], 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DestroyFramebuffers (vulkan_ctx_t *ctx)
|
||||
Vulkan_DestroyFrames (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *df = device->funcs;
|
||||
|
@ -553,3 +486,59 @@ Vulkan_DestroyFramebuffers (vulkan_ctx_t *ctx)
|
|||
|
||||
DARRAY_CLEAR (&ctx->frames);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_CreateFramebuffers (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
|
||||
plitem_t *item = qfv_load_renderpass (ctx, "images");
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
__auto_type images = QFV_ParseImageSet (ctx, item, ctx->renderpassDef);
|
||||
ctx->attachment_images = images;
|
||||
size_t memSize = 0;
|
||||
for (size_t i = 0; i < images->size; i++) {
|
||||
memSize += get_image_size (images->a[i], device);
|
||||
}
|
||||
VkDeviceMemory mem;
|
||||
mem = QFV_AllocImageMemory (device, images->a[0],
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
memSize, 0);
|
||||
ctx->attachmentMemory = mem;
|
||||
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY,
|
||||
mem, "memory:framebuffers");
|
||||
size_t offset = 0;
|
||||
for (size_t i = 0; i < images->size; i++) {
|
||||
QFV_BindImageMemory (device, images->a[i], mem, offset);
|
||||
offset += get_image_size (images->a[i], device);
|
||||
}
|
||||
|
||||
item = qfv_load_renderpass (ctx, "imageViews");
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
__auto_type views = QFV_ParseImageViewSet (ctx, item, ctx->renderpassDef);
|
||||
ctx->attachment_views = views;
|
||||
|
||||
item = qfv_load_renderpass (ctx, "framebuffer");
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->framebuffers = QFV_AllocFrameBuffers (ctx->swapchain->numImages,
|
||||
malloc);
|
||||
for (size_t i = 0; i < ctx->framebuffers->size; i++) {
|
||||
ctx->swapImageIndex = i;
|
||||
ctx->framebuffers->a[i] = QFV_ParseFramebuffer (ctx, item,
|
||||
ctx->renderpassDef);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_DestroyFramebuffers (vulkan_ctx_t *ctx)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue