mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 13:10:34 +00:00
[vulkan] Get IQM rendering working
The bones aren't animated yet (and I realized I made the mistake of thinking the bone buffer was per-model when it's really per-instance (I think this mistake is in the rest of QF, too)), skin rendering is a mess, need to default vertex attributes that aren't in the model... Still, it's quite satisfying seeing Mr Fixit on screen again :) I wound up moving the pipeline spec in with the rest of the pipelines as the system isn't really ready for separating them.
This commit is contained in:
parent
3f7cbae4d0
commit
8795b8eb91
10 changed files with 274 additions and 303 deletions
|
@ -65,6 +65,8 @@ typedef struct qfv_iqm_s {
|
||||||
qfv_iqm_skin_t *skins;
|
qfv_iqm_skin_t *skins;
|
||||||
struct qfv_resource_s *mesh;
|
struct qfv_resource_s *mesh;
|
||||||
struct qfv_resource_s *bones;
|
struct qfv_resource_s *bones;
|
||||||
|
VkBuffer bones_buffer;
|
||||||
|
VkDescriptorSet *bones_descriptors; // one per frame FIXME per instance!!!
|
||||||
} qfv_iqm_t;
|
} qfv_iqm_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -91,15 +93,21 @@ typedef struct iqmctx_s {
|
||||||
VkPipeline gbuf;
|
VkPipeline gbuf;
|
||||||
VkPipelineLayout layout;
|
VkPipelineLayout layout;
|
||||||
VkSampler sampler;
|
VkSampler sampler;
|
||||||
|
VkDescriptorPool bones_pool;
|
||||||
|
VkDescriptorSetLayout bones_setLayout;
|
||||||
} iqmctx_t;
|
} iqmctx_t;
|
||||||
|
|
||||||
struct vulkan_ctx_s;
|
struct vulkan_ctx_s;
|
||||||
struct qfv_renderframe_s;
|
struct qfv_renderframe_s;
|
||||||
struct entity_s;
|
struct entity_s;
|
||||||
struct mod_iqm_ctx_s;
|
struct mod_iqm_ctx_s;
|
||||||
|
struct iqm_s;
|
||||||
|
|
||||||
void Vulkan_Mod_IQMFinish (struct model_s *mod, struct vulkan_ctx_s *ctx);
|
void Vulkan_Mod_IQMFinish (struct model_s *mod, struct vulkan_ctx_s *ctx);
|
||||||
|
|
||||||
|
void Vulkan_IQMAddBones (struct vulkan_ctx_s *ctx, struct iqm_s *iqm);
|
||||||
|
void Vulkan_IQMRemoveBones (struct vulkan_ctx_s *ctx, struct iqm_s *iqm);
|
||||||
|
|
||||||
void Vulkan_IQMAddSkin (struct vulkan_ctx_s *ctx, qfv_iqm_skin_t *skin);
|
void Vulkan_IQMAddSkin (struct vulkan_ctx_s *ctx, qfv_iqm_skin_t *skin);
|
||||||
void Vulkan_IQMRemoveSkin (struct vulkan_ctx_s *ctx, qfv_iqm_skin_t *skin);
|
void Vulkan_IQMRemoveSkin (struct vulkan_ctx_s *ctx, qfv_iqm_skin_t *skin);
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ typedef struct {
|
||||||
byte weights[4];
|
byte weights[4];
|
||||||
} iqmblend_t;
|
} iqmblend_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct iqm_s {
|
||||||
char *text;
|
char *text;
|
||||||
int num_meshes;
|
int num_meshes;
|
||||||
iqmmesh *meshes;
|
iqmmesh *meshes;
|
||||||
|
|
|
@ -81,6 +81,11 @@ vulkan_iqm_clear (model_t *mod, void *data)
|
||||||
|
|
||||||
mod->needload = true;
|
mod->needload = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < iqm->num_meshes; i++) {
|
||||||
|
Vulkan_IQMRemoveSkin (ctx, &mesh->skins[i]);
|
||||||
|
}
|
||||||
|
Vulkan_IQMRemoveBones (ctx, iqm);//FIXME doesn't belong here (per-instance)
|
||||||
|
|
||||||
QFV_DestroyResource (device, mesh->bones);
|
QFV_DestroyResource (device, mesh->bones);
|
||||||
QFV_DestroyResource (device, mesh->mesh);
|
QFV_DestroyResource (device, mesh->mesh);
|
||||||
free (mesh);
|
free (mesh);
|
||||||
|
@ -162,6 +167,14 @@ iqm_transfer_texture (tex_t *tex, VkImage image, qfv_stagebuf_t *stage,
|
||||||
0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0,
|
||||||
1, &ib.barrier);
|
1, &ib.barrier);
|
||||||
memcpy (dst, tex->data, layer_size);
|
memcpy (dst, tex->data, layer_size);
|
||||||
|
VkBufferImageCopy copy = {
|
||||||
|
packet->offset, 0, 0,
|
||||||
|
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
|
||||||
|
{0, 0, 0}, {tex->width, tex->height, 1},
|
||||||
|
};
|
||||||
|
dfunc->vkCmdCopyBufferToImage (packet->cmd, packet->stage->buffer,
|
||||||
|
image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
1, ©);
|
||||||
|
|
||||||
int mipLevels = QFV_MipLevels (tex->width, tex->height);
|
int mipLevels = QFV_MipLevels (tex->width, tex->height);
|
||||||
if (mipLevels == 1) {
|
if (mipLevels == 1) {
|
||||||
|
@ -225,6 +238,7 @@ vulkan_iqm_load_textures (model_t *mod, iqm_t *iqm, qfv_iqm_t *mesh,
|
||||||
tex = &null_tex;
|
tex = &null_tex;
|
||||||
}
|
}
|
||||||
iqm_transfer_texture (tex, image->image, stage, device);
|
iqm_transfer_texture (tex, image->image, stage, device);
|
||||||
|
Vulkan_IQMAddSkin (ctx, skin);
|
||||||
}
|
}
|
||||||
dstring_delete (str);
|
dstring_delete (str);
|
||||||
QFV_DestroyStagingBuffer (stage);
|
QFV_DestroyStagingBuffer (stage);
|
||||||
|
@ -236,6 +250,8 @@ vulkan_iqm_load_arrays (model_t *mod, iqm_t *iqm, qfv_iqm_t *mesh,
|
||||||
{
|
{
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
qfv_devfuncs_t *dfunc = device->funcs;
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
iqmctx_t *ictx = ctx->iqm_context;
|
||||||
|
|
||||||
size_t geom_size = iqm->num_verts * sizeof (iqmgvert_t);
|
size_t geom_size = iqm->num_verts * sizeof (iqmgvert_t);
|
||||||
size_t rend_size = iqm->num_verts * sizeof (iqmrvert_t);
|
size_t rend_size = iqm->num_verts * sizeof (iqmrvert_t);
|
||||||
size_t elem_size = iqm->num_elements * sizeof (uint16_t);
|
size_t elem_size = iqm->num_elements * sizeof (uint16_t);
|
||||||
|
@ -350,7 +366,7 @@ vulkan_iqm_load_arrays (model_t *mod, iqm_t *iqm, qfv_iqm_t *mesh,
|
||||||
vec4f_t *bone_data;
|
vec4f_t *bone_data;
|
||||||
dfunc->vkMapMemory (device->dev, mesh->bones->memory, 0, VK_WHOLE_SIZE,
|
dfunc->vkMapMemory (device->dev, mesh->bones->memory, 0, VK_WHOLE_SIZE,
|
||||||
0, (void **)&bone_data);
|
0, (void **)&bone_data);
|
||||||
for (int i = 0; i < 3 * iqm->num_joints; i++) {
|
for (size_t i = 0; i < ictx->frames.size * iqm->num_joints; i++) {
|
||||||
vec4f_t *bone = bone_data + i * 3;
|
vec4f_t *bone = bone_data + i * 3;
|
||||||
bone[0] = (vec4f_t) {1, 0, 0, 0};
|
bone[0] = (vec4f_t) {1, 0, 0, 0};
|
||||||
bone[1] = (vec4f_t) {0, 1, 0, 0};
|
bone[1] = (vec4f_t) {0, 1, 0, 0};
|
||||||
|
@ -363,12 +379,15 @@ vulkan_iqm_load_arrays (model_t *mod, iqm_t *iqm, qfv_iqm_t *mesh,
|
||||||
dfunc->vkFlushMappedMemoryRanges (device->dev, 1, &range);
|
dfunc->vkFlushMappedMemoryRanges (device->dev, 1, &range);
|
||||||
|
|
||||||
dfunc->vkUnmapMemory (device->dev, mesh->bones->memory);
|
dfunc->vkUnmapMemory (device->dev, mesh->bones->memory);
|
||||||
|
|
||||||
|
Vulkan_IQMAddBones (ctx, iqm); //FIXME doesn't belong here (per-instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Vulkan_Mod_IQMFinish (model_t *mod, vulkan_ctx_t *ctx)
|
Vulkan_Mod_IQMFinish (model_t *mod, vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
|
iqmctx_t *ictx = ctx->iqm_context;
|
||||||
iqm_t *iqm = (iqm_t *) mod->aliashdr;
|
iqm_t *iqm = (iqm_t *) mod->aliashdr;
|
||||||
mod->clear = vulkan_iqm_clear;
|
mod->clear = vulkan_iqm_clear;
|
||||||
mod->data = ctx;
|
mod->data = ctx;
|
||||||
|
@ -378,10 +397,12 @@ Vulkan_Mod_IQMFinish (model_t *mod, vulkan_ctx_t *ctx)
|
||||||
// 2 is for image + image view
|
// 2 is for image + image view
|
||||||
int num_objects = 4 + 2 * iqm->num_meshes;
|
int num_objects = 4 + 2 * iqm->num_meshes;
|
||||||
qfv_iqm_t *mesh = calloc (1, sizeof (qfv_iqm_t)
|
qfv_iqm_t *mesh = calloc (1, sizeof (qfv_iqm_t)
|
||||||
|
+ ictx->frames.size * sizeof (VkDescriptorSet)
|
||||||
+ 2 * sizeof (qfv_resource_t)
|
+ 2 * sizeof (qfv_resource_t)
|
||||||
+ num_objects * sizeof (qfv_resobj_t)
|
+ num_objects * sizeof (qfv_resobj_t)
|
||||||
+ iqm->num_meshes * sizeof (qfv_iqm_skin_t));
|
+ iqm->num_meshes * sizeof (qfv_iqm_skin_t));
|
||||||
mesh->bones = (qfv_resource_t *) &mesh[1];
|
mesh->bones_descriptors = (VkDescriptorSet *) &mesh[1];
|
||||||
|
mesh->bones = (qfv_resource_t *)&mesh->bones_descriptors[ictx->frames.size];
|
||||||
mesh->mesh = &mesh->bones[1];
|
mesh->mesh = &mesh->bones[1];
|
||||||
|
|
||||||
mesh->bones[0] = (qfv_resource_t) {
|
mesh->bones[0] = (qfv_resource_t) {
|
||||||
|
@ -395,9 +416,9 @@ Vulkan_Mod_IQMFinish (model_t *mod, vulkan_ctx_t *ctx)
|
||||||
.name = "bones",
|
.name = "bones",
|
||||||
.type = qfv_res_buffer,
|
.type = qfv_res_buffer,
|
||||||
.buffer = {
|
.buffer = {
|
||||||
.size = 3 * iqm->num_joints * 3 * sizeof (vec4f_t),
|
.size = ictx->frames.size * iqm->num_joints * 3 * sizeof (vec4f_t),
|
||||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||||
| VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -460,9 +481,10 @@ Vulkan_Mod_IQMFinish (model_t *mod, vulkan_ctx_t *ctx)
|
||||||
mesh->geom_buffer = mesh->mesh->objects[0].buffer.buffer;
|
mesh->geom_buffer = mesh->mesh->objects[0].buffer.buffer;
|
||||||
mesh->rend_buffer = mesh->mesh->objects[1].buffer.buffer;
|
mesh->rend_buffer = mesh->mesh->objects[1].buffer.buffer;
|
||||||
mesh->index_buffer = mesh->mesh->objects[2].buffer.buffer;
|
mesh->index_buffer = mesh->mesh->objects[2].buffer.buffer;
|
||||||
|
mesh->bones_buffer = mesh->bones->objects[0].buffer.buffer;
|
||||||
|
|
||||||
|
iqm->extra_data = mesh;
|
||||||
|
|
||||||
vulkan_iqm_load_textures (mod, iqm, mesh, ctx);
|
vulkan_iqm_load_textures (mod, iqm, mesh, ctx);
|
||||||
vulkan_iqm_load_arrays (mod, iqm, mesh, ctx);
|
vulkan_iqm_load_arrays (mod, iqm, mesh, ctx);
|
||||||
|
|
||||||
iqm->extra_data = mesh;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ vulkan_R_Init (void)
|
||||||
Vulkan_Matrix_Init (vulkan_ctx);
|
Vulkan_Matrix_Init (vulkan_ctx);
|
||||||
Vulkan_Alias_Init (vulkan_ctx);
|
Vulkan_Alias_Init (vulkan_ctx);
|
||||||
Vulkan_Bsp_Init (vulkan_ctx);
|
Vulkan_Bsp_Init (vulkan_ctx);
|
||||||
|
Vulkan_IQM_Init (vulkan_ctx);
|
||||||
Vulkan_Particles_Init (vulkan_ctx);
|
Vulkan_Particles_Init (vulkan_ctx);
|
||||||
Vulkan_Sprite_Init (vulkan_ctx);
|
Vulkan_Sprite_Init (vulkan_ctx);
|
||||||
Vulkan_Draw_Init (vulkan_ctx);
|
Vulkan_Draw_Init (vulkan_ctx);
|
||||||
|
@ -686,16 +687,18 @@ vulkan_vid_render_shutdown (void)
|
||||||
df->vkDestroyFence (dev, vulkan_ctx->fence, 0);
|
df->vkDestroyFence (dev, vulkan_ctx->fence, 0);
|
||||||
df->vkDestroyCommandPool (dev, vulkan_ctx->cmdpool, 0);
|
df->vkDestroyCommandPool (dev, vulkan_ctx->cmdpool, 0);
|
||||||
|
|
||||||
|
Mod_ClearAll ();
|
||||||
|
|
||||||
Vulkan_Compose_Shutdown (vulkan_ctx);
|
Vulkan_Compose_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Lighting_Shutdown (vulkan_ctx);
|
Vulkan_Lighting_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Draw_Shutdown (vulkan_ctx);
|
Vulkan_Draw_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Sprite_Shutdown (vulkan_ctx);
|
Vulkan_Sprite_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Particles_Shutdown (vulkan_ctx);
|
Vulkan_Particles_Shutdown (vulkan_ctx);
|
||||||
|
Vulkan_IQM_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Bsp_Shutdown (vulkan_ctx);
|
Vulkan_Bsp_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Alias_Shutdown (vulkan_ctx);
|
Vulkan_Alias_Shutdown (vulkan_ctx);
|
||||||
Vulkan_Matrix_Shutdown (vulkan_ctx);
|
Vulkan_Matrix_Shutdown (vulkan_ctx);
|
||||||
|
|
||||||
Mod_ClearAll ();
|
|
||||||
Vulkan_Texture_Shutdown (vulkan_ctx);
|
Vulkan_Texture_Shutdown (vulkan_ctx);
|
||||||
Vulkan_DestroyRenderPasses (vulkan_ctx);
|
Vulkan_DestroyRenderPasses (vulkan_ctx);
|
||||||
Vulkan_Shutdown_Common (vulkan_ctx);
|
Vulkan_Shutdown_Common (vulkan_ctx);
|
||||||
|
|
|
@ -1,254 +0,0 @@
|
||||||
{
|
|
||||||
setLayouts = {
|
|
||||||
texture_set = {
|
|
||||||
bindings = (
|
|
||||||
{
|
|
||||||
binding = 0;
|
|
||||||
descriptorType = combined_image_sampler;
|
|
||||||
descriptorCount = 1;
|
|
||||||
stageFlags = fragment;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
pipelineLayouts = {
|
|
||||||
iqm_layout = {
|
|
||||||
setLayouts = (matrix_set, texture_set);
|
|
||||||
pushConstantRanges = (
|
|
||||||
{
|
|
||||||
stageFlags = vertex;
|
|
||||||
offset = 0;
|
|
||||||
size = "16 * 4 + 4";
|
|
||||||
},
|
|
||||||
{
|
|
||||||
stageFlags = fragment;
|
|
||||||
offset = 68;
|
|
||||||
size = "3 * 4 + 2 * 4 * 4 + 4";
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
depthStencil = {
|
|
||||||
test_and_write = {
|
|
||||||
depthTestEnable = true;
|
|
||||||
depthWriteEnable = true;
|
|
||||||
depthCompareOp = less_or_equal;
|
|
||||||
depthBoundsTestEnable = false;
|
|
||||||
stencilTestEnable = false;
|
|
||||||
};
|
|
||||||
test_only = {
|
|
||||||
depthTestEnable = true;
|
|
||||||
depthWriteEnable = false;
|
|
||||||
depthCompareOp = less_or_equal;
|
|
||||||
depthBoundsTestEnable = false;
|
|
||||||
stencilTestEnable = false;
|
|
||||||
};
|
|
||||||
disable = {
|
|
||||||
depthTestEnable = false;
|
|
||||||
depthWriteEnable = false;
|
|
||||||
depthCompareOp = less_or_equal;
|
|
||||||
depthBoundsTestEnable = false;
|
|
||||||
stencilTestEnable = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
inputAssembly = {
|
|
||||||
iqm = {
|
|
||||||
topology = triangle_list;
|
|
||||||
primitiveRestartEnable = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
vertexInput = {
|
|
||||||
iqm = {
|
|
||||||
bindings = (
|
|
||||||
{ binding = 0; stride = 20; inputRate = vertex; },
|
|
||||||
{ binding = 1; stride = 40; inputRate = vertex; },
|
|
||||||
);
|
|
||||||
attributes = (
|
|
||||||
{ location = 0; binding = 0; format = r32g32b32_sfloat; offset = 0; }, // position
|
|
||||||
{ location = 1; binding = 0; format = r8g8b8a8_uint; offset = 0; }, // bonindices
|
|
||||||
{ location = 2; binding = 0; format = r8g8b8a8_unorm; offset = 4; }, // boneweights
|
|
||||||
|
|
||||||
{ location = 3; binding = 1; format = r32g32_sfloat; offset = 0; }, // texcoord
|
|
||||||
{ location = 4; binding = 1; format = r32g32b32_sfloat; offset = 8; }, // normal
|
|
||||||
{ location = 5; binding = 1; format = r32g32b32a32_sfloat; offset = 20; }, // tangent
|
|
||||||
{ location = 6; binding = 1; format = r8g8b8a8_unorm; offset = 36; }, // color
|
|
||||||
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
rasterization = {
|
|
||||||
cw_cull_back = {
|
|
||||||
depthClampEnable = false;
|
|
||||||
rasterizerDiscardEnable = false;
|
|
||||||
polygonMode = fill;
|
|
||||||
cullMode = back;
|
|
||||||
frontFace = clockwise;
|
|
||||||
depthBiasEnable = false;
|
|
||||||
lineWidth = 1;
|
|
||||||
};
|
|
||||||
counter_cw_cull_back = {
|
|
||||||
depthClampEnable = false;
|
|
||||||
rasterizerDiscardEnable = false;
|
|
||||||
polygonMode = fill;
|
|
||||||
cullMode = back;
|
|
||||||
frontFace = counter_clockwise;
|
|
||||||
depthBiasEnable = false;
|
|
||||||
lineWidth = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
multisample = {
|
|
||||||
rasterizationSamples = $msaaSamples;
|
|
||||||
sampleShadingEnable = false;
|
|
||||||
minSampleShading = 0.5f;
|
|
||||||
alphaToCoverageEnable = false;
|
|
||||||
alphaToOneEnable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
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; };
|
|
||||||
},
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
attachmentBlendOp = {
|
|
||||||
disabled = {
|
|
||||||
blendEnable = false;
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
alpha_blend = {
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pipelines = {
|
|
||||||
iqm_shadow = {
|
|
||||||
subpass = 0;
|
|
||||||
stages = (
|
|
||||||
{
|
|
||||||
stage = vertex;
|
|
||||||
name = main;
|
|
||||||
module = $builtin/iqm_shadow.vert;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
vertexInput = {
|
|
||||||
bindings = (
|
|
||||||
"$properties.vertexInput.iqm.bindings[0]",
|
|
||||||
"$properties.vertexInput.iqm.bindings[1]",
|
|
||||||
);
|
|
||||||
attributes = (
|
|
||||||
"$properties.vertexInput.iqm.attributes[0]",
|
|
||||||
"$properties.vertexInput.iqm.attributes[1]",
|
|
||||||
"$properties.vertexInput.iqm.attributes[2]",
|
|
||||||
"$properties.vertexInput.iqm.attributes[3]",
|
|
||||||
);
|
|
||||||
};
|
|
||||||
inputAssembly = $properties.inputAssembly.iqm;
|
|
||||||
viewport = $properties.viewport;
|
|
||||||
rasterization = $properties.rasterization.cw_cull_back;
|
|
||||||
multisample = $properties.multisample;
|
|
||||||
depthStencil = $properties.depthStencil.test_and_write;
|
|
||||||
colorBlend = $properties.pipelines.iqm_gbuf.colorBlend;
|
|
||||||
dynamic = {
|
|
||||||
dynamicState = ( viewport, scissor );
|
|
||||||
};
|
|
||||||
layout = iqm_layout;
|
|
||||||
};
|
|
||||||
iqm_depth = {
|
|
||||||
subpass = 0;
|
|
||||||
stages = (
|
|
||||||
{
|
|
||||||
stage = vertex;
|
|
||||||
name = main;
|
|
||||||
module = $builtin/iqm_depth.vert;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
vertexInput = {
|
|
||||||
// depth pass doesn't use UVs
|
|
||||||
bindings = (
|
|
||||||
"$properties.vertexInput.iqm.bindings[0]",
|
|
||||||
"$properties.vertexInput.iqm.bindings[1]",
|
|
||||||
);
|
|
||||||
attributes = (
|
|
||||||
"$properties.vertexInput.iqm.attributes[0]",
|
|
||||||
"$properties.vertexInput.iqm.attributes[1]",
|
|
||||||
"$properties.vertexInput.iqm.attributes[2]",
|
|
||||||
"$properties.vertexInput.iqm.attributes[3]",
|
|
||||||
);
|
|
||||||
};
|
|
||||||
inputAssembly = $properties.inputAssembly.iqm;
|
|
||||||
viewport = $properties.viewport;
|
|
||||||
rasterization = $properties.rasterization.cw_cull_back;
|
|
||||||
multisample = $properties.multisample;
|
|
||||||
depthStencil = $properties.depthStencil.test_and_write;
|
|
||||||
colorBlend = $properties.pipelines.iqm_gbuf.colorBlend;
|
|
||||||
dynamic = {
|
|
||||||
dynamicState = ( viewport, scissor );
|
|
||||||
};
|
|
||||||
layout = iqm_layout;
|
|
||||||
renderPass = renderpass;
|
|
||||||
};
|
|
||||||
iqm_gbuf = {
|
|
||||||
subpass = 2;
|
|
||||||
stages = (
|
|
||||||
{
|
|
||||||
stage = vertex;
|
|
||||||
name = main;
|
|
||||||
module = $builtin/iqm.vert;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
stage = fragment;
|
|
||||||
name = main;
|
|
||||||
module = $builtin/iqm_gbuf.frag;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
vertexInput = $properties.vertexInput.iqm;
|
|
||||||
inputAssembly = $properties.inputAssembly.iqm;
|
|
||||||
viewport = $properties.viewport;
|
|
||||||
rasterization = $properties.rasterization.cw_cull_back;
|
|
||||||
multisample = $properties.multisample;
|
|
||||||
depthStencil = $properties.depthStencil.test_only;
|
|
||||||
colorBlend = {
|
|
||||||
logicOpEnable = false;
|
|
||||||
attachments = (
|
|
||||||
$properties.attachmentBlendOp.disabled,
|
|
||||||
$properties.attachmentBlendOp.disabled,
|
|
||||||
$properties.attachmentBlendOp.disabled,
|
|
||||||
$properties.attachmentBlendOp.disabled,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
dynamic = {
|
|
||||||
dynamicState = ( viewport, scissor, blend_constants );
|
|
||||||
};
|
|
||||||
layout = iqm_layout;
|
|
||||||
renderPass = renderpass;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -97,6 +97,16 @@
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
bone_pool = {
|
||||||
|
flags = free_descriptor_set;
|
||||||
|
maxSets = 512;
|
||||||
|
bindings = (
|
||||||
|
{
|
||||||
|
type = storage_buffer;
|
||||||
|
descriptorCount = $properties.descriptorPools.bone_pool.maxSets;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
texture_pool = {
|
texture_pool = {
|
||||||
flags = free_descriptor_set;
|
flags = free_descriptor_set;
|
||||||
maxSets = 512;
|
maxSets = 512;
|
||||||
|
@ -206,6 +216,16 @@
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
bone_set = {
|
||||||
|
bindings = (
|
||||||
|
{
|
||||||
|
binding = 0;
|
||||||
|
descriptorType = storage_buffer;
|
||||||
|
descriptorCount = 1;
|
||||||
|
stageFlags = vertex;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
sprite_set = {
|
sprite_set = {
|
||||||
bindings = (
|
bindings = (
|
||||||
{
|
{
|
||||||
|
@ -349,6 +369,21 @@
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
iqm_layout = {
|
||||||
|
setLayouts = (matrix_set, texture_set, bone_set);
|
||||||
|
pushConstantRanges = (
|
||||||
|
{
|
||||||
|
stageFlags = vertex;
|
||||||
|
offset = 0;
|
||||||
|
size = "16 * 4 + 4";
|
||||||
|
},
|
||||||
|
{
|
||||||
|
stageFlags = fragment;
|
||||||
|
offset = 68;
|
||||||
|
size = "3 * 4 + 2 * 4 * 4 + 4";
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
sprite_layout = {
|
sprite_layout = {
|
||||||
setLayouts = (matrix_set, sprite_set);
|
setLayouts = (matrix_set, sprite_set);
|
||||||
pushConstantRanges = (
|
pushConstantRanges = (
|
||||||
|
@ -428,6 +463,10 @@
|
||||||
topology = triangle_fan;
|
topology = triangle_fan;
|
||||||
primitiveRestartEnable = true;
|
primitiveRestartEnable = true;
|
||||||
};
|
};
|
||||||
|
iqm = {
|
||||||
|
topology = triangle_list;
|
||||||
|
primitiveRestartEnable = false;
|
||||||
|
};
|
||||||
twod = {
|
twod = {
|
||||||
topology = triangle_strip;
|
topology = triangle_strip;
|
||||||
primitiveRestartEnable = true;
|
primitiveRestartEnable = true;
|
||||||
|
@ -466,6 +505,23 @@
|
||||||
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
{ location = 1; binding = 0; format = r32g32b32a32_sfloat; offset = 16; },
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
iqm = {
|
||||||
|
bindings = (
|
||||||
|
{ binding = 0; stride = 20; inputRate = vertex; },
|
||||||
|
{ binding = 1; stride = 40; inputRate = vertex; },
|
||||||
|
);
|
||||||
|
attributes = (
|
||||||
|
{ location = 0; binding = 0; format = r32g32b32_sfloat; offset = 0; }, // position
|
||||||
|
{ location = 1; binding = 0; format = r8g8b8a8_uint; offset = 12; }, // bonindices
|
||||||
|
{ location = 2; binding = 0; format = r8g8b8a8_unorm; offset = 16; }, // boneweights
|
||||||
|
|
||||||
|
{ location = 3; binding = 1; format = r32g32_sfloat; offset = 0; }, // texcoord
|
||||||
|
{ location = 4; binding = 1; format = r32g32b32_sfloat; offset = 8; }, // normal
|
||||||
|
{ location = 5; binding = 1; format = r32g32b32a32_sfloat; offset = 20; }, // tangent
|
||||||
|
{ location = 6; binding = 1; format = r8g8b8a8_unorm; offset = 36; }, // color
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
particle = {
|
particle = {
|
||||||
bindings = (
|
bindings = (
|
||||||
{ binding = 0; stride = "4 * 4 * 4"; inputRate = vertex; },
|
{ binding = 0; stride = "4 * 4 * 4"; inputRate = vertex; },
|
||||||
|
@ -833,6 +889,61 @@
|
||||||
inputAssembly = $properties.inputAssembly.brush;
|
inputAssembly = $properties.inputAssembly.brush;
|
||||||
layout = quakebsp_layout;
|
layout = quakebsp_layout;
|
||||||
};
|
};
|
||||||
|
iqm_depth = {
|
||||||
|
@inherit = $properties.pipelines.depth_base;
|
||||||
|
stages = (
|
||||||
|
{
|
||||||
|
stage = vertex;
|
||||||
|
name = main;
|
||||||
|
module = $builtin/iqm.vert;
|
||||||
|
specializationInfo = {
|
||||||
|
mapEntries = (
|
||||||
|
// IQMDepthOnly
|
||||||
|
{ size = 4; offset = 0; constantID = 0; },
|
||||||
|
);
|
||||||
|
data = "array(1)";
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
vertexInput = $properties.vertexInput.iqm;
|
||||||
|
/*vertexInput = {
|
||||||
|
bindings = (
|
||||||
|
"$properties.vertexInput.iqm.bindings[0]",
|
||||||
|
);
|
||||||
|
attributes = (
|
||||||
|
"$properties.vertexInput.iqm.attributes[0]",
|
||||||
|
"$properties.vertexInput.iqm.attributes[1]",
|
||||||
|
"$properties.vertexInput.iqm.attributes[2]",
|
||||||
|
);
|
||||||
|
};*/
|
||||||
|
inputAssembly = $properties.inputAssembly.iqm;
|
||||||
|
layout = iqm_layout;
|
||||||
|
};
|
||||||
|
iqm_gbuf = {
|
||||||
|
@inherit = $properties.pipelines.gbuf_base;
|
||||||
|
stages = (
|
||||||
|
{
|
||||||
|
stage = vertex;
|
||||||
|
name = main;
|
||||||
|
module = $builtin/iqm.vert;
|
||||||
|
specializationInfo = {
|
||||||
|
mapEntries = (
|
||||||
|
// !IQMDepthOnly
|
||||||
|
{ size = 4; offset = 0; constantID = 0; },
|
||||||
|
);
|
||||||
|
data = "array(0)";
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
stage = fragment;
|
||||||
|
name = main;
|
||||||
|
module = $builtin/iqm.frag;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
vertexInput = $properties.vertexInput.iqm;
|
||||||
|
inputAssembly = $properties.inputAssembly.iqm;
|
||||||
|
layout = iqm_layout;
|
||||||
|
};
|
||||||
partdraw = {
|
partdraw = {
|
||||||
@inherit = $properties.pipelines.trans_base;
|
@inherit = $properties.pipelines.trans_base;
|
||||||
stages = (
|
stages = (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout (set = 1, binding = 0) uniform sampler2DArray Skin;
|
layout (set = 1, binding = 0) uniform sampler2D Skin;
|
||||||
|
|
||||||
layout (push_constant) uniform PushConstants {
|
layout (push_constant) uniform PushConstants {
|
||||||
layout (offset = 68)
|
layout (offset = 68)
|
||||||
|
@ -15,7 +15,7 @@ layout (location = 1) in vec4 position;
|
||||||
layout (location = 2) in vec3 normal;
|
layout (location = 2) in vec3 normal;
|
||||||
layout (location = 3) in vec3 tangent;
|
layout (location = 3) in vec3 tangent;
|
||||||
layout (location = 4) in vec3 bitangent;
|
layout (location = 4) in vec3 bitangent;
|
||||||
layout (location = 5) in vec3 color;
|
layout (location = 5) in vec4 color;
|
||||||
|
|
||||||
layout (location = 0) out vec4 frag_color;
|
layout (location = 0) out vec4 frag_color;
|
||||||
layout (location = 1) out vec4 frag_emission;
|
layout (location = 1) out vec4 frag_emission;
|
||||||
|
@ -27,18 +27,19 @@ main (void)
|
||||||
{
|
{
|
||||||
vec4 c;
|
vec4 c;
|
||||||
vec4 e;
|
vec4 e;
|
||||||
vec3 n;
|
//vec3 n;
|
||||||
int i;
|
int i;
|
||||||
mat3 tbn = mat3 (tangent, bitangent, normal);
|
//mat3 tbn = mat3 (tangent, bitangent, normal);
|
||||||
|
|
||||||
c = texture (Skin, vec3 (texcoord, 0)) * base_color;
|
c = texture (Skin, texcoord);// * color;
|
||||||
c += texture (Skin, vec3 (texcoord, 1)) * unpackUnorm4x8(colorA);
|
//c = texture (Skin, vec3 (texcoord, 0)) * color;
|
||||||
c += texture (Skin, vec3 (texcoord, 2)) * unpackUnorm4x8(colorB);
|
//c += texture (Skin, vec3 (texcoord, 1)) * unpackUnorm4x8(colorA);
|
||||||
e = texture (Skin, vec3 (texcoord, 3));
|
//c += texture (Skin, vec3 (texcoord, 2)) * unpackUnorm4x8(colorB);
|
||||||
n = texture (Skin, vec3 (texcoord, 4)).xyz * 2 - 1;
|
//e = texture (Skin, vec3 (texcoord, 3));
|
||||||
|
//n = texture (Skin, vec3 (texcoord, 4)).xyz * 2 - 1;
|
||||||
|
|
||||||
frag_color = c;
|
frag_color = c;
|
||||||
frag_emission = e;
|
frag_emission = vec4(0,0,0,1);//e;
|
||||||
frag_normal = vec4(tbn * n, 1);
|
frag_normal = vec4(normal,1);//vec4(tbn * n, 1);
|
||||||
frag_position = position;
|
frag_position = position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
layout (constant_id = 0) const bool IQMDepthOnly = false;
|
||||||
|
|
||||||
layout (set = 0, binding = 0) uniform Matrices {
|
layout (set = 0, binding = 0) uniform Matrices {
|
||||||
mat4 Projection3d;
|
mat4 Projection3d;
|
||||||
mat4 View;
|
mat4 View;
|
||||||
|
@ -7,7 +9,7 @@ layout (set = 0, binding = 0) uniform Matrices {
|
||||||
mat4 Projection2d;
|
mat4 Projection2d;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (set = 3, binding = 0) buffer Bones {
|
layout (set = 2, binding = 0) buffer Bones {
|
||||||
// NOTE these are transposed, so v * m
|
// NOTE these are transposed, so v * m
|
||||||
mat3x4 bones[];
|
mat3x4 bones[];
|
||||||
};
|
};
|
||||||
|
@ -18,7 +20,7 @@ layout (push_constant) uniform PushConstants {
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (location = 0) in vec3 vposition;
|
layout (location = 0) in vec3 vposition;
|
||||||
layout (location = 1) in ivec4 vbones;
|
layout (location = 1) in uvec4 vbones;
|
||||||
layout (location = 2) in vec4 vweights;
|
layout (location = 2) in vec4 vweights;
|
||||||
layout (location = 3) in vec2 vtexcoord;
|
layout (location = 3) in vec2 vtexcoord;
|
||||||
layout (location = 4) in vec3 vnormal;
|
layout (location = 4) in vec3 vnormal;
|
||||||
|
@ -41,12 +43,16 @@ main (void)
|
||||||
m += bones[vbones.w] * vweights.w;
|
m += bones[vbones.w] * vweights.w;
|
||||||
vec4 pos = vec4 (Model * vec4(vposition, 1) * m, 1);
|
vec4 pos = vec4 (Model * vec4(vposition, 1) * m, 1);
|
||||||
gl_Position = Projection3d * (View * pos);
|
gl_Position = Projection3d * (View * pos);
|
||||||
position = pos;
|
|
||||||
mat3 adjTrans = mat3 (cross(m[1].xyz, m[2].xyz), cross(m[2].xyz, m[0].xyz),
|
if (!IQMDepthOnly) {
|
||||||
cross(m[0].xyz, m[1].xyz));
|
position = pos;
|
||||||
normal = mat3 (Model) * vnormal * adjTrans;
|
mat3 adjTrans = mat3 (cross(m[1].xyz, m[2].xyz),
|
||||||
tangent = mat3 (Model) * vtangent.xyz * adjTrans;
|
cross(m[2].xyz, m[0].xyz),
|
||||||
bitangent = cross (normal, tangent) * vtangent.w;
|
cross(m[0].xyz, m[1].xyz));
|
||||||
texcoord = vtexcoord;
|
normal = mat3 (Model) * vnormal * adjTrans;
|
||||||
color = vcolor;
|
tangent = mat3 (Model) * vtangent.xyz * adjTrans;
|
||||||
|
bitangent = cross (normal, tangent) * vtangent.w;
|
||||||
|
texcoord = vtexcoord;
|
||||||
|
color = vcolor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
|
#include "QF/iqm.h"
|
||||||
#include "QF/va.h"
|
#include "QF/va.h"
|
||||||
|
|
||||||
#include "QF/scene/entity.h"
|
#include "QF/scene/entity.h"
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
#include "QF/Vulkan/qf_matrices.h"
|
#include "QF/Vulkan/qf_matrices.h"
|
||||||
#include "QF/Vulkan/qf_texture.h"
|
#include "QF/Vulkan/qf_texture.h"
|
||||||
#include "QF/Vulkan/debug.h"
|
#include "QF/Vulkan/debug.h"
|
||||||
|
#include "QF/Vulkan/descriptor.h"
|
||||||
#include "QF/Vulkan/device.h"
|
#include "QF/Vulkan/device.h"
|
||||||
#include "QF/Vulkan/instance.h"
|
#include "QF/Vulkan/instance.h"
|
||||||
#include "QF/Vulkan/renderpass.h"
|
#include "QF/Vulkan/renderpass.h"
|
||||||
|
@ -72,7 +74,7 @@ static QFV_Subpass subpass_map[] = {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
||||||
qfv_iqm_skin_t **skins,
|
qfv_iqm_skin_t *skins,
|
||||||
uint32_t numPC, qfv_push_constants_t *constants,
|
uint32_t numPC, qfv_push_constants_t *constants,
|
||||||
iqm_t *iqm, qfv_renderframe_t *rFrame)
|
iqm_t *iqm, qfv_renderframe_t *rFrame)
|
||||||
{
|
{
|
||||||
|
@ -88,20 +90,28 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
||||||
mesh->geom_buffer,
|
mesh->geom_buffer,
|
||||||
mesh->rend_buffer,
|
mesh->rend_buffer,
|
||||||
};
|
};
|
||||||
int bindingCount = skins ? 2 : 1;
|
int bindingCount = 2;//skins ? 2 : 1;
|
||||||
|
|
||||||
dfunc->vkCmdBindVertexBuffers (cmd, 0, bindingCount, buffers, offsets);
|
dfunc->vkCmdBindVertexBuffers (cmd, 0, bindingCount, buffers, offsets);
|
||||||
dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0,
|
dfunc->vkCmdBindIndexBuffer (cmd, mesh->index_buffer, 0,
|
||||||
VK_INDEX_TYPE_UINT32);
|
VK_INDEX_TYPE_UINT16);
|
||||||
QFV_PushConstants (device, cmd, ictx->layout, numPC, constants);
|
QFV_PushConstants (device, cmd, ictx->layout, numPC, constants);
|
||||||
for (int i = 0; i < iqm->num_meshes; i++) {
|
for (int i = 0; i < iqm->num_meshes; i++) {
|
||||||
if (skins) {
|
if (skins) {
|
||||||
VkDescriptorSet sets[] = {
|
VkDescriptorSet sets[] = {
|
||||||
skins[i]->descriptor,
|
skins[i].descriptor,
|
||||||
|
mesh->bones_descriptors[ctx->curFrame],
|
||||||
};
|
};
|
||||||
dfunc->vkCmdBindDescriptorSets (cmd,
|
dfunc->vkCmdBindDescriptorSets (cmd,
|
||||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
ictx->layout, 1, 1, sets, 0, 0);
|
ictx->layout, 1, 2, sets, 0, 0);
|
||||||
|
} else {
|
||||||
|
VkDescriptorSet sets[] = {
|
||||||
|
mesh->bones_descriptors[ctx->curFrame],
|
||||||
|
};
|
||||||
|
dfunc->vkCmdBindDescriptorSets (cmd,
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
ictx->layout, 2, 1, sets, 0, 0);
|
||||||
}
|
}
|
||||||
dfunc->vkCmdDrawIndexed (cmd, 3 * iqm->meshes[i].num_triangles, 1,
|
dfunc->vkCmdDrawIndexed (cmd, 3 * iqm->meshes[i].num_triangles, 1,
|
||||||
3 * iqm->meshes[i].first_triangle, 0, 0);
|
3 * iqm->meshes[i].first_triangle, 0, 0);
|
||||||
|
@ -117,7 +127,7 @@ Vulkan_DrawIQM (entity_t *ent, qfv_renderframe_t *rFrame)
|
||||||
model_t *model = ent->renderer.model;
|
model_t *model = ent->renderer.model;
|
||||||
iqm_t *iqm = (iqm_t *) model->aliashdr;
|
iqm_t *iqm = (iqm_t *) model->aliashdr;
|
||||||
qfv_iqm_t *mesh = iqm->extra_data;
|
qfv_iqm_t *mesh = iqm->extra_data;
|
||||||
qfv_iqm_skin_t **skins = &mesh->skins;
|
qfv_iqm_skin_t *skins = mesh->skins;
|
||||||
iqm_push_constants_t constants = {};
|
iqm_push_constants_t constants = {};
|
||||||
|
|
||||||
constants.blend = R_IQMGetLerpedFrames (ent, iqm);
|
constants.blend = R_IQMGetLerpedFrames (ent, iqm);
|
||||||
|
@ -144,8 +154,8 @@ Vulkan_DrawIQM (entity_t *ent, qfv_renderframe_t *rFrame)
|
||||||
};
|
};
|
||||||
|
|
||||||
QuatCopy (ent->renderer.colormod, constants.base_color);
|
QuatCopy (ent->renderer.colormod, constants.base_color);
|
||||||
QuatCopy (skins[0]->colora, constants.colorA);
|
QuatCopy (skins[0].colora, constants.colorA);
|
||||||
QuatCopy (skins[0]->colorb, constants.colorB);
|
QuatCopy (skins[0].colorb, constants.colorB);
|
||||||
QuatZero (constants.fog);
|
QuatZero (constants.fog);
|
||||||
|
|
||||||
emit_commands (aframe->cmdSet.a[QFV_iqmDepth],
|
emit_commands (aframe->cmdSet.a[QFV_iqmDepth],
|
||||||
|
@ -157,8 +167,8 @@ Vulkan_DrawIQM (entity_t *ent, qfv_renderframe_t *rFrame)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
alias_begin_subpass (QFV_IQMSubpass subpass, VkPipeline pipeline,
|
iqm_begin_subpass (QFV_IQMSubpass subpass, VkPipeline pipeline,
|
||||||
qfv_renderframe_t *rFrame)
|
qfv_renderframe_t *rFrame)
|
||||||
{
|
{
|
||||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||||
qfv_device_t *device = ctx->device;
|
qfv_device_t *device = ctx->device;
|
||||||
|
@ -200,7 +210,7 @@ alias_begin_subpass (QFV_IQMSubpass subpass, VkPipeline pipeline,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
alias_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
iqm_end_subpass (VkCommandBuffer cmd, 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;
|
||||||
|
@ -222,8 +232,8 @@ Vulkan_IQMBegin (qfv_renderframe_t *rFrame)
|
||||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer],
|
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer],
|
||||||
aframe->cmdSet.a[QFV_iqmGBuffer]);
|
aframe->cmdSet.a[QFV_iqmGBuffer]);
|
||||||
|
|
||||||
alias_begin_subpass (QFV_iqmDepth, ictx->depth, rFrame);
|
iqm_begin_subpass (QFV_iqmDepth, ictx->depth, rFrame);
|
||||||
alias_begin_subpass (QFV_iqmGBuffer, ictx->gbuf, rFrame);
|
iqm_begin_subpass (QFV_iqmGBuffer, ictx->gbuf, rFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -233,8 +243,69 @@ Vulkan_IQMEnd (qfv_renderframe_t *rFrame)
|
||||||
iqmctx_t *ictx = ctx->iqm_context;
|
iqmctx_t *ictx = ctx->iqm_context;
|
||||||
iqm_frame_t *aframe = &ictx->frames.a[ctx->curFrame];
|
iqm_frame_t *aframe = &ictx->frames.a[ctx->curFrame];
|
||||||
|
|
||||||
alias_end_subpass (aframe->cmdSet.a[QFV_iqmDepth], ctx);
|
iqm_end_subpass (aframe->cmdSet.a[QFV_iqmDepth], ctx);
|
||||||
alias_end_subpass (aframe->cmdSet.a[QFV_iqmGBuffer], ctx);
|
iqm_end_subpass (aframe->cmdSet.a[QFV_iqmGBuffer], ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkWriteDescriptorSet base_buffer_write = {
|
||||||
|
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0, 0,
|
||||||
|
0, 0, 1,
|
||||||
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
Vulkan_IQMAddBones (vulkan_ctx_t *ctx, iqm_t *iqm)
|
||||||
|
{
|
||||||
|
qfvPushDebug (ctx, "Vulkan_IQMAddBones");
|
||||||
|
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
iqmctx_t *ictx = ctx->iqm_context;
|
||||||
|
__auto_type mesh = (qfv_iqm_t *) iqm->extra_data;
|
||||||
|
int num_sets = ictx->frames.size;
|
||||||
|
|
||||||
|
//FIXME kinda dumb
|
||||||
|
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (num_sets, alloca);
|
||||||
|
for (size_t i = 0; i < layouts->size; i++) {
|
||||||
|
layouts->a[i] = ictx->bones_setLayout;
|
||||||
|
}
|
||||||
|
__auto_type sets = QFV_AllocateDescriptorSet (device, ictx->bones_pool,
|
||||||
|
layouts);
|
||||||
|
for (size_t i = 0; i < sets->size; i++) {
|
||||||
|
mesh->bones_descriptors[i] = sets->a[i];
|
||||||
|
}
|
||||||
|
free (sets);
|
||||||
|
|
||||||
|
VkDescriptorBufferInfo bufferInfo[num_sets];
|
||||||
|
size_t bones_size = iqm->num_joints * 3 * sizeof (vec4f_t);
|
||||||
|
for (int i = 0; i < num_sets; i++) {
|
||||||
|
bufferInfo[i].buffer = mesh->bones_buffer;
|
||||||
|
bufferInfo[i].offset = i * bones_size;
|
||||||
|
bufferInfo[i].range = bones_size;
|
||||||
|
};
|
||||||
|
VkWriteDescriptorSet write[num_sets];
|
||||||
|
for (int i = 0; i < num_sets; i++) {
|
||||||
|
write[i] = base_buffer_write;
|
||||||
|
write[i].dstSet = mesh->bones_descriptors[i];
|
||||||
|
write[i].pBufferInfo = &bufferInfo[i];
|
||||||
|
}
|
||||||
|
dfunc->vkUpdateDescriptorSets (device->dev, num_sets, write, 0, 0);
|
||||||
|
|
||||||
|
qfvPopDebug (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vulkan_IQMRemoveBones (vulkan_ctx_t *ctx, iqm_t *iqm)
|
||||||
|
{
|
||||||
|
qfv_device_t *device = ctx->device;
|
||||||
|
qfv_devfuncs_t *dfunc = device->funcs;
|
||||||
|
iqmctx_t *ictx = ctx->iqm_context;
|
||||||
|
__auto_type mesh = (qfv_iqm_t *) iqm->extra_data;
|
||||||
|
int num_sets = ictx->frames.size;
|
||||||
|
|
||||||
|
dfunc->vkFreeDescriptorSets (device->dev, ictx->bones_pool, num_sets,
|
||||||
|
mesh->bones_descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -267,11 +338,14 @@ Vulkan_IQM_Init (vulkan_ctx_t *ctx)
|
||||||
DARRAY_RESIZE (&ictx->frames, frames);
|
DARRAY_RESIZE (&ictx->frames, frames);
|
||||||
ictx->frames.grow = 0;
|
ictx->frames.grow = 0;
|
||||||
|
|
||||||
ictx->depth = Vulkan_CreateGraphicsPipeline (ctx, "alias_depth");
|
ictx->depth = Vulkan_CreateGraphicsPipeline (ctx, "iqm_depth");
|
||||||
ictx->gbuf = Vulkan_CreateGraphicsPipeline (ctx, "alias_gbuf");
|
ictx->gbuf = Vulkan_CreateGraphicsPipeline (ctx, "iqm_gbuf");
|
||||||
ictx->layout = Vulkan_CreatePipelineLayout (ctx, "alias_layout");
|
ictx->layout = Vulkan_CreatePipelineLayout (ctx, "iqm_layout");
|
||||||
ictx->sampler = Vulkan_CreateSampler (ctx, "alias_sampler");
|
ictx->sampler = Vulkan_CreateSampler (ctx, "alias_sampler");
|
||||||
|
|
||||||
|
ictx->bones_pool = Vulkan_CreateDescriptorPool (ctx, "bone_pool");
|
||||||
|
ictx->bones_setLayout = Vulkan_CreateDescriptorSetLayout (ctx, "bone_set");
|
||||||
|
|
||||||
for (size_t i = 0; i < frames; i++) {
|
for (size_t i = 0; i < frames; i++) {
|
||||||
__auto_type aframe = &ictx->frames.a[i];
|
__auto_type aframe = &ictx->frames.a[i];
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "QF/Vulkan/qf_vid.h"
|
#include "QF/Vulkan/qf_vid.h"
|
||||||
#include "QF/Vulkan/qf_alias.h"
|
#include "QF/Vulkan/qf_alias.h"
|
||||||
#include "QF/Vulkan/qf_bsp.h"
|
#include "QF/Vulkan/qf_bsp.h"
|
||||||
//#include "QF/Vulkan/qf_iqm.h"
|
#include "QF/Vulkan/qf_iqm.h"
|
||||||
#include "QF/Vulkan/qf_lighting.h"
|
#include "QF/Vulkan/qf_lighting.h"
|
||||||
#include "QF/Vulkan/qf_lightmap.h"
|
#include "QF/Vulkan/qf_lightmap.h"
|
||||||
#include "QF/Vulkan/qf_main.h"
|
#include "QF/Vulkan/qf_main.h"
|
||||||
|
@ -95,7 +95,7 @@ Vulkan_RenderEntities (entqueue_t *queue, qfv_renderframe_t *rFrame)
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
RE_LOOP (alias, Alias);
|
RE_LOOP (alias, Alias);
|
||||||
//RE_LOOP (iqm, IQM);
|
RE_LOOP (iqm, IQM);
|
||||||
RE_LOOP (sprite, Sprite);
|
RE_LOOP (sprite, Sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue