mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-21 19:21:47 +00:00
[vulkan] Get some subsystems passing validation
This is with the new render job scheme. I very much doubt it actually works (can't start testing until everything passes, and it's disabled for the moment (define in vid_render_vulkan.c)), but it's helping iron out what more is needed in the render system.
This commit is contained in:
parent
97f9fd81d6
commit
3c65f1494b
7 changed files with 221 additions and 13 deletions
|
@ -263,7 +263,7 @@ typedef struct qfv_bar_s {
|
||||||
typedef struct qfv_pipeline_s {
|
typedef struct qfv_pipeline_s {
|
||||||
qfv_label_t label;
|
qfv_label_t label;
|
||||||
VkPipelineBindPoint bindPoint;
|
VkPipelineBindPoint bindPoint;
|
||||||
uint32_t dispatch[3];
|
vec4u_t dispatch;
|
||||||
VkPipeline pipeline;
|
VkPipeline pipeline;
|
||||||
VkPipelineLayout layout;
|
VkPipelineLayout layout;
|
||||||
|
|
||||||
|
@ -360,6 +360,9 @@ typedef struct qfv_taskctx_s {
|
||||||
qfv_pipeline_t *pipeline;
|
qfv_pipeline_t *pipeline;
|
||||||
} qfv_taskctx_t;
|
} qfv_taskctx_t;
|
||||||
|
|
||||||
|
VkCommandBuffer QFV_GetCmdBufffer (struct vulkan_ctx_s *ctx, bool secondary);
|
||||||
|
void QFV_AppendCmdBuffer (struct vulkan_ctx_s *ctx, VkCommandBuffer cmd);
|
||||||
|
|
||||||
void QFV_RunRenderJob (struct vulkan_ctx_s *ctx);
|
void QFV_RunRenderJob (struct vulkan_ctx_s *ctx);
|
||||||
void QFV_LoadRenderInfo (struct vulkan_ctx_s *ctx);
|
void QFV_LoadRenderInfo (struct vulkan_ctx_s *ctx);
|
||||||
void QFV_BuildRender (struct vulkan_ctx_s *ctx);
|
void QFV_BuildRender (struct vulkan_ctx_s *ctx);
|
||||||
|
|
|
@ -308,7 +308,8 @@ vulkan_Draw_Glyph (int x, int y, int fontid, int glyphid, int c)
|
||||||
{
|
{
|
||||||
Vulkan_Draw_Glyph (x, y, fontid, glyphid, c, vulkan_ctx);
|
Vulkan_Draw_Glyph (x, y, fontid, glyphid, c, vulkan_ctx);
|
||||||
}
|
}
|
||||||
|
//#define TEST_RENDER
|
||||||
|
#ifndef TEST_RENDER
|
||||||
static void
|
static void
|
||||||
vulkan_begin_frame (void)
|
vulkan_begin_frame (void)
|
||||||
{
|
{
|
||||||
|
@ -479,10 +480,17 @@ vulkan_end_frame (void)
|
||||||
vulkan_ctx->curFrame++;
|
vulkan_ctx->curFrame++;
|
||||||
vulkan_ctx->curFrame %= vulkan_ctx->frames.size;
|
vulkan_ctx->curFrame %= vulkan_ctx->frames.size;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
static void
|
static void
|
||||||
vulkan_UpdateScreen (transform_t camera, double realtime, SCR_Func *scr_funcs)
|
vulkan_UpdateScreen (transform_t camera, double realtime, SCR_Func *scr_funcs)
|
||||||
{
|
{
|
||||||
|
#ifdef TEST_RENDER
|
||||||
|
while (*scr_funcs) {
|
||||||
|
(*scr_funcs) ();
|
||||||
|
scr_funcs++;
|
||||||
|
}
|
||||||
|
QFV_RunRenderJob (vulkan_ctx);
|
||||||
|
#else
|
||||||
EntQueue_Clear (r_ent_queue);
|
EntQueue_Clear (r_ent_queue);
|
||||||
vulkan_begin_frame ();
|
vulkan_begin_frame ();
|
||||||
vulkan_set_2d (1);
|
vulkan_set_2d (1);
|
||||||
|
@ -492,6 +500,7 @@ vulkan_UpdateScreen (transform_t camera, double realtime, SCR_Func *scr_funcs)
|
||||||
}
|
}
|
||||||
vulkan_render_view ();
|
vulkan_render_view ();
|
||||||
vulkan_end_frame ();
|
vulkan_end_frame ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -51,8 +51,8 @@
|
||||||
|
|
||||||
#include "vkparse.h"
|
#include "vkparse.h"
|
||||||
|
|
||||||
static VkCommandBuffer
|
VkCommandBuffer
|
||||||
get_cmd_buffer (vulkan_ctx_t *ctx, int secondary)
|
QFV_GetCmdBufffer (vulkan_ctx_t *ctx, bool secondary)
|
||||||
{
|
{
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
@ -71,11 +71,19 @@ get_cmd_buffer (vulkan_ctx_t *ctx, int secondary)
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QFV_AppendCmdBuffer (vulkan_ctx_t *ctx, VkCommandBuffer cmd)
|
||||||
|
{
|
||||||
|
__auto_type rctx = ctx->render_context;
|
||||||
|
__auto_type job = rctx->job;
|
||||||
|
DARRAY_APPEND (&job->commands, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
run_tasks (uint32_t task_count, qfv_taskinfo_t *tasks, void *ctx)
|
run_tasks (uint32_t task_count, qfv_taskinfo_t *tasks, qfv_taskctx_t *ctx)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < task_count; i++) {
|
for (uint32_t i = 0; i < task_count; i++) {
|
||||||
tasks[i].func->func (tasks[i].params, 0, ctx);
|
tasks[i].func->func (tasks[i].params, 0, (exprctx_t *) ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,19 +144,20 @@ run_renderpass (qfv_renderpass_t *rp, vulkan_ctx_t *ctx)
|
||||||
|
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
__auto_type rctx = ctx->render_context;
|
||||||
|
__auto_type job = rctx->job;
|
||||||
|
|
||||||
VkCommandBuffer cmd = get_cmd_buffer (ctx, 1);
|
VkCommandBuffer cmd = QFV_GetCmdBufffer (ctx, false);
|
||||||
VkCommandBufferBeginInfo beginInfo = {
|
VkCommandBufferBeginInfo beginInfo = {
|
||||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
};
|
};
|
||||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
|
||||||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||||
QFV_duCmdBeginLabel (device, cmd, rp->label.name,
|
QFV_duCmdBeginLabel (device, cmd, rp->label.name,
|
||||||
{VEC4_EXP (rp->label.color)});
|
{VEC4_EXP (rp->label.color)});
|
||||||
dfunc->vkCmdBeginRenderPass (cmd, &rp->beginInfo, rp->subpassContents);
|
dfunc->vkCmdBeginRenderPass (cmd, &rp->beginInfo, rp->subpassContents);
|
||||||
for (uint32_t i = 0; i < rp->subpass_count; i++) {
|
for (uint32_t i = 0; i < rp->subpass_count; i++) {
|
||||||
__auto_type sp = &rp->subpasses[i];
|
__auto_type sp = &rp->subpasses[i];
|
||||||
VkCommandBuffer subcmd = get_cmd_buffer (ctx, 1);
|
VkCommandBuffer subcmd = QFV_GetCmdBufffer (ctx, true);
|
||||||
run_subpass (sp, subcmd, ctx);
|
run_subpass (sp, subcmd, ctx);
|
||||||
dfunc->vkCmdExecuteCommands (cmd, 1, &subcmd);
|
dfunc->vkCmdExecuteCommands (cmd, 1, &subcmd);
|
||||||
//FIXME comment is a bit off as exactly one buffer is always submitted
|
//FIXME comment is a bit off as exactly one buffer is always submitted
|
||||||
|
@ -162,6 +171,7 @@ run_renderpass (qfv_renderpass_t *rp, vulkan_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QFV_CmdEndLabel (device, cmd);
|
QFV_CmdEndLabel (device, cmd);
|
||||||
|
DARRAY_APPEND (&job->commands, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -193,7 +203,7 @@ run_compute_pipeline (qfv_pipeline_t *pipeline, VkCommandBuffer cmd,
|
||||||
pipeline->num_push_constants,
|
pipeline->num_push_constants,
|
||||||
pipeline->push_constants);
|
pipeline->push_constants);
|
||||||
}
|
}
|
||||||
uint32_t *d = pipeline->dispatch;
|
vec4u_t d = pipeline->dispatch;
|
||||||
dfunc->vkCmdDispatch (cmd, d[0], d[1], d[2]);
|
dfunc->vkCmdDispatch (cmd, d[0], d[1], d[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +215,7 @@ run_compute (qfv_compute_t *comp, vulkan_ctx_t *ctx)
|
||||||
__auto_type rctx = ctx->render_context;
|
__auto_type rctx = ctx->render_context;
|
||||||
__auto_type job = rctx->job;
|
__auto_type job = rctx->job;
|
||||||
|
|
||||||
VkCommandBuffer cmd = get_cmd_buffer (ctx, 0);
|
VkCommandBuffer cmd = QFV_GetCmdBufffer (ctx, false);
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo = {
|
VkCommandBufferBeginInfo beginInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
|
|
|
@ -1310,7 +1310,15 @@ renderpasses = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
steps = {
|
steps = {
|
||||||
|
wait_on_fence = {
|
||||||
|
process = {
|
||||||
|
tasks = (
|
||||||
|
{ func = "wait_on_fence"; },
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
particles = {
|
particles = {
|
||||||
|
dependencies = (wait_on_fence);
|
||||||
compute = {
|
compute = {
|
||||||
pipelines = {
|
pipelines = {
|
||||||
part:update = {
|
part:update = {
|
||||||
|
@ -1339,9 +1347,11 @@ steps = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
shadow = {
|
shadow = {
|
||||||
|
dependencies = (wait_on_fence);
|
||||||
//currently empty
|
//currently empty
|
||||||
};
|
};
|
||||||
translucent = {
|
translucent = {
|
||||||
|
dependencies = (wait_on_fence);
|
||||||
process = {
|
process = {
|
||||||
tasks = (
|
tasks = (
|
||||||
{ func = "clear_translucent"; },
|
{ func = "clear_translucent"; },
|
||||||
|
@ -1358,6 +1368,7 @@ steps = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
preoutput = {
|
preoutput = {
|
||||||
|
dependencies = (wait_on_fence);
|
||||||
process = {
|
process = {
|
||||||
tasks = (
|
tasks = (
|
||||||
{ func = "acquire_output"; },
|
{ func = "acquire_output"; },
|
||||||
|
|
|
@ -259,6 +259,20 @@ _output_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wait_on_fence (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
|
{
|
||||||
|
__auto_type taskctx = (qfv_taskctx_t *) ectx;
|
||||||
|
vulkan_ctx_t *ctx = taskctx->ctx;
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
VkDevice dev = device->dev;
|
||||||
|
|
||||||
|
__auto_type frame = &ctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
|
dfunc->vkWaitForFences (dev, 1, &frame->fence, VK_TRUE, 2000000000);
|
||||||
|
}
|
||||||
|
|
||||||
static exprfunc_t acquire_output_func[] = {
|
static exprfunc_t acquire_output_func[] = {
|
||||||
{ .func = acquire_output },
|
{ .func = acquire_output },
|
||||||
{}
|
{}
|
||||||
|
@ -271,10 +285,15 @@ static exprfunc_t output_draw_func[] = {
|
||||||
{ .func = _output_draw },
|
{ .func = _output_draw },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
static exprfunc_t wait_on_fence_func[] = {
|
||||||
|
{ .func = wait_on_fence },
|
||||||
|
{}
|
||||||
|
};
|
||||||
static exprsym_t output_task_syms[] = {
|
static exprsym_t output_task_syms[] = {
|
||||||
{ "acquire_output", &cexpr_function, acquire_output_func },
|
{ "acquire_output", &cexpr_function, acquire_output_func },
|
||||||
{ "update_input", &cexpr_function, update_input_func },
|
{ "update_input", &cexpr_function, update_input_func },
|
||||||
{ "output_draw", &cexpr_function, output_draw_func },
|
{ "output_draw", &cexpr_function, output_draw_func },
|
||||||
|
{ "wait_on_fence", &cexpr_function, wait_on_fence_func },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -276,16 +276,121 @@ create_buffers (vulkan_ctx_t *ctx)
|
||||||
static void
|
static void
|
||||||
particles_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
particles_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
{
|
{
|
||||||
|
puts ("particles_draw");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_particles (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
update_particles (const exprval_t **_params, exprval_t *result, exprctx_t *ectx)
|
||||||
{
|
{
|
||||||
|
__auto_type taskctx = (qfv_taskctx_t *) ectx;
|
||||||
|
vulkan_ctx_t *ctx = taskctx->ctx;
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
// VkDevice dev = device->dev;
|
||||||
|
|
||||||
|
particlectx_t *pctx = ctx->particle_context;
|
||||||
|
__auto_type pframe = &pctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
|
qfv_packet_t *packet = QFV_PacketAcquire (pctx->stage);
|
||||||
|
|
||||||
|
__auto_type limits = &device->physDev->properties->limits;
|
||||||
|
VkMemoryRequirements req = {
|
||||||
|
.alignment = limits->minStorageBufferOffsetAlignment
|
||||||
|
};
|
||||||
|
uint32_t numParticles = min (MaxParticles, pctx->psystem->numparticles);
|
||||||
|
size_t syssize = sizeof (qfv_particle_system_t);
|
||||||
|
size_t partoffs = QFV_NextOffset (syssize, &req);
|
||||||
|
size_t partsize = sizeof (qfv_particle_t) * numParticles;
|
||||||
|
size_t paramoffs = QFV_NextOffset (partoffs + partsize, &req);
|
||||||
|
size_t paramsize = sizeof (qfv_parameters_t) * numParticles;
|
||||||
|
size_t size = paramoffs + paramsize;
|
||||||
|
|
||||||
|
qfv_particle_system_t *system = QFV_PacketExtend (packet, size);
|
||||||
|
*system = (qfv_particle_system_t) {
|
||||||
|
.vertexCount = 1,
|
||||||
|
.particleCount = numParticles,
|
||||||
|
};
|
||||||
|
__auto_type particles = (qfv_particle_t *) ((byte *)system + partoffs);
|
||||||
|
memcpy (particles, pctx->psystem->particles, partsize);
|
||||||
|
qfv_parameters_t *params = (qfv_parameters_t *)((byte *)system + paramoffs);
|
||||||
|
memcpy (params, pctx->psystem->partparams, paramsize);
|
||||||
|
|
||||||
|
if (!numParticles) {
|
||||||
|
// if there are no particles, then no space for the particle states or
|
||||||
|
// parameters has been allocated in the staging buffer, so map the
|
||||||
|
// two buffers over the system buffer. This avoids either buffer being
|
||||||
|
// just past the end of the staging buffer (which the validation layers
|
||||||
|
// (correctly) do not like).
|
||||||
|
// This is fine because the two buffers are only read by the compute
|
||||||
|
// shader.
|
||||||
|
partsize = paramsize = syssize;
|
||||||
|
partoffs = paramoffs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sysoffs = packet->offset;
|
||||||
|
VkDescriptorBufferInfo bufferInfo[] = {
|
||||||
|
{ packet->stage->buffer, sysoffs + partoffs, partsize},
|
||||||
|
{ packet->stage->buffer, sysoffs + paramoffs, paramsize},
|
||||||
|
{ packet->stage->buffer, sysoffs, syssize },
|
||||||
|
};
|
||||||
|
VkWriteDescriptorSet write[] = {
|
||||||
|
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0,
|
||||||
|
pframe->newDescriptors, 0, 0, 3,
|
||||||
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.pBufferInfo = bufferInfo
|
||||||
|
},
|
||||||
|
};
|
||||||
|
dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0);
|
||||||
|
|
||||||
|
__auto_type pipeline = taskctx->pipeline;
|
||||||
|
pipeline->dispatch = (vec4u_t) {1, 1, 1};
|
||||||
|
pipeline->num_descriptorsets = 3;
|
||||||
|
pipeline->descriptorsets[0] = pframe->curDescriptors;
|
||||||
|
pipeline->descriptorsets[1] = pframe->inDescriptors;
|
||||||
|
pipeline->descriptorsets[2] = pframe->newDescriptors;
|
||||||
|
|
||||||
|
QFV_PacketSubmit (packet);
|
||||||
|
|
||||||
|
pctx->psystem->numparticles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
particle_physics (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
particle_physics (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
{
|
{
|
||||||
|
__auto_type taskctx = (qfv_taskctx_t *) ectx;
|
||||||
|
vulkan_ctx_t *ctx = taskctx->ctx;
|
||||||
|
|
||||||
|
particlectx_t *pctx = ctx->particle_context;
|
||||||
|
__auto_type pframe = &pctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
|
__auto_type pipeline = taskctx->pipeline;
|
||||||
|
pipeline->dispatch = (vec4u_t) {MaxParticles, 1, 1};
|
||||||
|
pipeline->num_descriptorsets = 1;
|
||||||
|
pipeline->descriptorsets[0] = pframe->curDescriptors;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
qfv_push_constants_t push_constants[2];
|
||||||
|
particle_push_constants_t constants;
|
||||||
|
} push = {
|
||||||
|
.push_constants = {
|
||||||
|
{ VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
|
field_offset (particle_push_constants_t, gravity),
|
||||||
|
sizeof (vec4f_t), &push.constants.gravity },
|
||||||
|
{ VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
|
field_offset (particle_push_constants_t, dT),
|
||||||
|
sizeof (float), &push.constants.dT },
|
||||||
|
},
|
||||||
|
.constants = {
|
||||||
|
.gravity = pctx->psystem->gravity,
|
||||||
|
.dT = vr_data.frametime,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (!pipeline->push_constants) {
|
||||||
|
//FIXME figure out something better for managing push constants
|
||||||
|
pipeline->push_constants = malloc (sizeof (push));
|
||||||
|
}
|
||||||
|
memcpy (pipeline->push_constants, &push, sizeof (push));
|
||||||
|
pipeline->num_push_constants = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static exprfunc_t particles_draw_func[] = {
|
static exprfunc_t particles_draw_func[] = {
|
||||||
|
|
|
@ -67,6 +67,57 @@ static const char * __attribute__((used)) translucent_pass_names[] = {
|
||||||
static void
|
static void
|
||||||
clear_translucent (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
clear_translucent (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||||
{
|
{
|
||||||
|
__auto_type taskctx = (qfv_taskctx_t *) ectx;
|
||||||
|
vulkan_ctx_t *ctx = taskctx->ctx;
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
translucentctx_t *tctx = ctx->translucent_context;
|
||||||
|
__auto_type tframe = &tctx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
|
VkCommandBuffer cmd = QFV_GetCmdBufffer (ctx, false);
|
||||||
|
|
||||||
|
VkCommandBufferInheritanceInfo inherit = {
|
||||||
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
};
|
||||||
|
VkCommandBufferBeginInfo beginInfo = {
|
||||||
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
|
||||||
|
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &inherit,
|
||||||
|
};
|
||||||
|
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||||
|
|
||||||
|
qfv_imagebarrier_t ib = imageBarriers[qfv_LT_Undefined_to_TransferDst];
|
||||||
|
ib.barrier.image = tframe->heads;
|
||||||
|
ib.barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
dfunc->vkCmdPipelineBarrier (cmd, ib.srcStages, ib.dstStages,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
1, &ib.barrier);
|
||||||
|
VkClearColorValue clear_color[] = {
|
||||||
|
{ .int32 = {-1, -1, -1, -1} },
|
||||||
|
};
|
||||||
|
VkImageSubresourceRange ranges[] = {
|
||||||
|
{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, VK_REMAINING_ARRAY_LAYERS },
|
||||||
|
};
|
||||||
|
dfunc->vkCmdClearColorImage (cmd, tframe->heads,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
clear_color, 1, ranges);
|
||||||
|
ib = imageBarriers[qfv_LT_TransferDst_to_General];
|
||||||
|
ib.barrier.image = tframe->heads;
|
||||||
|
ib.barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
dfunc->vkCmdPipelineBarrier (cmd, ib.srcStages, ib.dstStages,
|
||||||
|
0, 0, 0, 0, 0,
|
||||||
|
1, &ib.barrier);
|
||||||
|
|
||||||
|
dfunc->vkEndCommandBuffer (cmd);
|
||||||
|
QFV_AppendCmdBuffer (ctx, cmd);
|
||||||
|
|
||||||
|
qfv_packet_t *packet = QFV_PacketAcquire (ctx->staging);
|
||||||
|
qfv_transtate_t *state = QFV_PacketExtend (packet, 2 * sizeof (*state));
|
||||||
|
*state = (qfv_transtate_t) { 0, tctx->maxFragments };
|
||||||
|
__auto_type bb = &bufferBarriers[qfv_BB_TransferWrite_to_ShaderRW];
|
||||||
|
QFV_PacketCopyBuffer (packet, tframe->state, 0, bb);
|
||||||
|
QFV_PacketSubmit (packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static exprfunc_t clear_translucent_func[] = {
|
static exprfunc_t clear_translucent_func[] = {
|
||||||
|
|
Loading…
Reference in a new issue