mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
[vulkan] Abandon bindless rendering
At least for now, it is more trouble than it is worth as it (or my implementation of it) breaks lavapipe and renderdoc.
This commit is contained in:
parent
8228146ac0
commit
db6c76d583
16 changed files with 183 additions and 285 deletions
|
@ -60,7 +60,7 @@ typedef struct qfv_alias_skin_s {
|
|||
VkImageView view;
|
||||
byte colora[4];
|
||||
byte colorb[4];
|
||||
int texind;
|
||||
VkDescriptorSet descriptor;
|
||||
} qfv_alias_skin_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -85,13 +85,8 @@ typedef struct aliasctx_s {
|
|||
aliasframeset_t frames;
|
||||
VkPipeline depth;
|
||||
VkPipeline gbuf;
|
||||
VkDescriptorSet descriptors;
|
||||
VkDescriptorPool pool;
|
||||
VkDescriptorSetLayout setLayout;
|
||||
VkPipelineLayout layout;
|
||||
unsigned maxImages;
|
||||
VkSampler sampler;
|
||||
aliasindset_t texindices;
|
||||
} aliasctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
|
|
@ -46,7 +46,7 @@ typedef struct vulktex_s {
|
|||
struct elechain_s *elechain;
|
||||
struct elechain_s **elechain_tail;
|
||||
struct qfv_tex_s *tex;
|
||||
int texind;
|
||||
VkDescriptorSet descriptor;
|
||||
} vulktex_t;
|
||||
|
||||
typedef struct bspvert_s {
|
||||
|
@ -96,7 +96,6 @@ typedef struct bspframe_s {
|
|||
typedef struct fragconst_s {
|
||||
quat_t fog;
|
||||
float time;
|
||||
int texind;
|
||||
} fragconst_t;
|
||||
|
||||
typedef struct bspframeset_s
|
||||
|
@ -138,6 +137,7 @@ typedef struct bspctx_s {
|
|||
|
||||
struct qfv_tex_s *default_skybox;
|
||||
struct qfv_tex_s *skybox_tex;
|
||||
VkDescriptorSet skybox_descriptor;
|
||||
vec4f_t sky_rotation[2];
|
||||
vec4f_t sky_velocity;
|
||||
vec4f_t sky_fix;
|
||||
|
@ -152,11 +152,7 @@ typedef struct bspctx_s {
|
|||
struct bsppoly_s *polys;
|
||||
|
||||
VkSampler sampler;
|
||||
VkDescriptorSet descriptors;
|
||||
VkDescriptorPool pool;
|
||||
VkDescriptorSetLayout setLayout;
|
||||
VkPipelineLayout layout;
|
||||
unsigned maxImages;
|
||||
|
||||
VkDeviceMemory texture_memory;
|
||||
VkPipeline depth;
|
||||
|
|
|
@ -10,6 +10,11 @@ typedef struct qfv_tex_s {
|
|||
VkImageView view;
|
||||
} qfv_tex_t;
|
||||
|
||||
typedef struct texturectx_s {
|
||||
VkDescriptorPool pool;
|
||||
VkDescriptorSetLayout setLayout;
|
||||
} texturectx_t;
|
||||
|
||||
void Vulkan_ExpandPalette (byte *dst, const byte *src, const byte *palette,
|
||||
int alpha, int count);
|
||||
qfv_tex_t *Vulkan_LoadTex (struct vulkan_ctx_s *ctx, tex_t *tex, int mip,
|
||||
|
@ -22,5 +27,12 @@ VkImageView Vulkan_TexImageView (qfv_tex_t *tex) __attribute__((pure));
|
|||
void Vulkan_UnloadTex (struct vulkan_ctx_s *ctx, qfv_tex_t *tex);
|
||||
void Vulkan_Texture_Init (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Texture_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
VkDescriptorSet Vulkan_CreateCombinedImageSampler (struct vulkan_ctx_s *ctx,
|
||||
VkImageView view,
|
||||
VkSampler sampler);
|
||||
VkDescriptorSet Vulkan_CreateTextureDescriptor (struct vulkan_ctx_s *ctx,
|
||||
qfv_tex_t *tex,
|
||||
VkSampler sampler);
|
||||
void Vulkan_FreeTexture (struct vulkan_ctx_s *ctx, VkDescriptorSet texture);
|
||||
|
||||
#endif//__QF_Vulkan_qf_texture_h
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct vulkan_ctx_s {
|
|||
struct hashtab_s *imageViews;
|
||||
struct hashtab_s *renderpasses;
|
||||
|
||||
struct texturectx_s *texture_context;
|
||||
struct matrixctx_s *matrix_context;
|
||||
struct aliasctx_s *alias_context;
|
||||
struct bspctx_s *bsp_context;
|
||||
|
|
|
@ -83,6 +83,10 @@ vulkan_brush_clear (model_t *mod, void *data)
|
|||
vulktex_t *tex = tx->render;
|
||||
dfunc->vkDestroyImage (device->dev, tex->tex->image, 0);
|
||||
dfunc->vkDestroyImageView (device->dev, tex->tex->view, 0);
|
||||
if (tex->descriptor) {
|
||||
Vulkan_FreeTexture (ctx, tex->descriptor);
|
||||
tex->descriptor = 0;
|
||||
}
|
||||
}
|
||||
dfunc->vkFreeMemory (device->dev, mctx->texture_memory, 0);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
//needs to agree on the size, so it might as well set maxSamplers
|
||||
//directly (and any other such variable)
|
||||
maxSamplers = "min (256u, $physDevLimits.maxPerStageDescriptorSamplers)";
|
||||
maxImages = "min (256u, $physDevLimits.maxPerStageDescriptorSampledImages - 8u)";
|
||||
};
|
||||
samplers = {
|
||||
quakepic = {
|
||||
|
@ -99,16 +98,12 @@
|
|||
);
|
||||
};
|
||||
texture_pool = {
|
||||
flags = 0;
|
||||
maxSets = 1;
|
||||
flags = free_descriptor_set;
|
||||
maxSets = 512;
|
||||
bindings = (
|
||||
{
|
||||
type = sampler;
|
||||
descriptorCount = 1;
|
||||
},
|
||||
{
|
||||
type = sampled_image;
|
||||
descriptorCount = $properties.limits.maxImages;
|
||||
type = combined_image_sampler;
|
||||
descriptorCount = $properties.descriptorPools.texture_pool.maxSets;
|
||||
},
|
||||
);
|
||||
};
|
||||
|
@ -205,16 +200,10 @@
|
|||
bindings = (
|
||||
{
|
||||
binding = 0;
|
||||
descriptorType = sampler;
|
||||
descriptorType = combined_image_sampler;
|
||||
descriptorCount = 1;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
{
|
||||
binding = 1;
|
||||
descriptorType = sampled_image;
|
||||
descriptorCount = $properties.limits.maxImages;
|
||||
stageFlags = fragment;
|
||||
},
|
||||
);
|
||||
};
|
||||
quakebsp_set = $properties.setLayouts.texture_set;
|
||||
|
@ -333,7 +322,7 @@
|
|||
setLayouts = (matrix_set, twod_set);
|
||||
};
|
||||
quakebsp_layout = {
|
||||
setLayouts = (matrix_set, quakebsp_set);
|
||||
setLayouts = (matrix_set, texture_set, texture_set);
|
||||
pushConstantRanges = (
|
||||
{
|
||||
stageFlags = vertex;
|
||||
|
@ -343,7 +332,7 @@
|
|||
{
|
||||
stageFlags = fragment;
|
||||
offset = 64;
|
||||
size = 32;
|
||||
size = "4 * 4 + 4";
|
||||
},
|
||||
);
|
||||
};
|
||||
|
@ -697,13 +686,6 @@
|
|||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/alias_gbuf.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
);
|
||||
data = "array(uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
vertexInput = $properties.vertexInput.alias;
|
||||
|
@ -773,13 +755,6 @@
|
|||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/bsp_gbuf.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
);
|
||||
data = "array(uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
vertexInput = $properties.vertexInput.brush;
|
||||
|
@ -817,14 +792,12 @@
|
|||
module = $builtin/bsp_sky.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 8; constantID = 0; },
|
||||
// doSkyBox
|
||||
{ size = 4; offset = 4; constantID = 1; },
|
||||
{ size = 4; offset = 4; constantID = 0; },
|
||||
// doSkySheet
|
||||
{ size = 4; offset = 0; constantID = 2; },
|
||||
{ size = 4; offset = 0; constantID = 1; },
|
||||
);
|
||||
data = "array(0, 1, uint($properties.limits.maxImages))";
|
||||
data = "array(0, 1)";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -858,14 +831,12 @@
|
|||
module = $builtin/bsp_sky.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 8; constantID = 0; },
|
||||
// doSkyBox
|
||||
{ size = 4; offset = 0; constantID = 1; },
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
// doSkySheet
|
||||
{ size = 4; offset = 4; constantID = 2; },
|
||||
{ size = 4; offset = 4; constantID = 1; },
|
||||
);
|
||||
data = "array(0, 1, uint($properties.limits.maxImages))";
|
||||
data = "array(0, 1)";
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -897,13 +868,6 @@
|
|||
stage = fragment;
|
||||
name = main;
|
||||
module = $builtin/bsp_turb.frag;
|
||||
specializationInfo = {
|
||||
mapEntries = (
|
||||
// MaxTextures
|
||||
{ size = 4; offset = 0; constantID = 0; },
|
||||
);
|
||||
data = "array(uint($properties.limits.maxImages))";
|
||||
};
|
||||
},
|
||||
);
|
||||
vertexInput = $properties.vertexInput.brush;
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 1, binding = 0) uniform sampler samp;
|
||||
layout (set = 1, binding = 1) uniform texture2DArray skins[MaxTextures];
|
||||
layout (set = 1, binding = 0) uniform sampler2DArray Skin;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 68)
|
||||
uint texind;
|
||||
uint colorA;
|
||||
uint colorB;
|
||||
vec4 base_color;
|
||||
|
@ -30,10 +26,10 @@ main (void)
|
|||
vec4 e;
|
||||
int i;
|
||||
vec3 light = vec3 (0);
|
||||
c = texture (sampler2DArray(skins[texind], samp), vec3 (st, 0)) * base_color;
|
||||
c += texture (sampler2DArray(skins[texind], samp), vec3 (st, 1)) * unpackUnorm4x8(colorA);
|
||||
c += texture (sampler2DArray(skins[texind], samp), vec3 (st, 2)) * unpackUnorm4x8(colorB);
|
||||
e = texture (sampler2DArray(skins[texind], samp), vec3 (st, 3));
|
||||
c = texture (Skin, vec3 (st, 0)) * base_color;
|
||||
c += texture (Skin, vec3 (st, 1)) * unpackUnorm4x8(colorA);
|
||||
c += texture (Skin, vec3 (st, 2)) * unpackUnorm4x8(colorB);
|
||||
e = texture (Skin, vec3 (st, 3));
|
||||
|
||||
frag_color = c;
|
||||
frag_emission = e;
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 1, binding = 0) uniform sampler samp;
|
||||
layout (set = 1, binding = 1) uniform texture2DArray textures[MaxTextures];
|
||||
layout (set = 1, binding = 0) uniform sampler2DArray Texture;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 64)
|
||||
vec4 fog;
|
||||
float time;
|
||||
int texind;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 tl_st;
|
||||
|
@ -41,8 +37,8 @@ main (void)
|
|||
vec3 e_st = vec3 (tl_st.xy, 1);
|
||||
vec2 l_st = vec2 (tl_st.zw);
|
||||
|
||||
c = texture (sampler2DArray (textures[texind], samp), t_st);
|
||||
e = texture (sampler2DArray (textures[texind], samp), e_st);
|
||||
c = texture (Texture, t_st);
|
||||
e = texture (Texture, e_st);
|
||||
frag_color = c;//fogBlend (c);
|
||||
frag_emission = e;
|
||||
frag_normal = vec4 (normal, 0);
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
layout (constant_id = 1) const bool doSkyBox = false;
|
||||
layout (constant_id = 2) const bool doSkySheet = false;
|
||||
|
||||
layout (set = 1, binding = 0) uniform sampler samp;
|
||||
layout (set = 1, binding = 1) uniform texture2DArray sheet_tex[MaxTextures];
|
||||
layout (set = 1, binding = 1) uniform textureCube cube_tex[MaxTextures];
|
||||
layout (set = 1, binding = 0) uniform sampler2DArray SkySheet;
|
||||
layout (set = 2, binding = 0) uniform samplerCube SkyBox;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 64)
|
||||
vec4 fog;
|
||||
float time;
|
||||
int sheet_ind;
|
||||
int cube_ind;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 tl_st;
|
||||
|
@ -34,7 +30,7 @@ fogBlend (vec4 color)
|
|||
}
|
||||
|
||||
vec4
|
||||
sky_sheet (vec3 dir, float time, texture2DArray tex)
|
||||
sky_sheet (vec3 dir, float time)
|
||||
{
|
||||
float len;
|
||||
vec2 flow = vec2 (1.0, 1.0);
|
||||
|
@ -50,8 +46,8 @@ sky_sheet (vec3 dir, float time, texture2DArray tex)
|
|||
st1 = vec3 (base + flow * time / 8.0, 0);
|
||||
st2 = vec3 (base + flow * time / 16.0, 1);
|
||||
|
||||
c1 = texture (sampler2DArray(tex, samp), st1);
|
||||
c2 = texture (sampler2DArray(tex, samp), st2);
|
||||
c1 = texture (SkySheet, st1);
|
||||
c2 = texture (SkySheet, st2);
|
||||
|
||||
c = vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
|
||||
|
@ -59,7 +55,7 @@ sky_sheet (vec3 dir, float time, texture2DArray tex)
|
|||
}
|
||||
|
||||
vec4
|
||||
sky_box (vec3 dir, float time, textureCube tex)
|
||||
sky_box (vec3 dir, float time)
|
||||
{
|
||||
// NOTE: quake's world is right-handed with Z up and X forward, but
|
||||
// Vulkan's cube maps are left-handed with Y up and Z forward. The
|
||||
|
@ -67,21 +63,21 @@ sky_box (vec3 dir, float time, textureCube tex)
|
|||
// to do here is swizzle the Y and Z coordinates
|
||||
dir = normalize(dir);
|
||||
//return vec4(dir.xyz, 1) * 0.5 + vec4(0.5);
|
||||
return texture (samplerCube (tex, samp), dir.xzy);
|
||||
return texture (SkyBox, dir.xzy);
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_color (vec3 dir, float time)
|
||||
{
|
||||
if (!doSkySheet) {
|
||||
return sky_box (dir, time, cube_tex[cube_ind]);
|
||||
return sky_box (dir, time);
|
||||
} if (!doSkyBox) {
|
||||
return sky_sheet (dir, time, sheet_tex[sheet_ind]);
|
||||
return sky_sheet (dir, time);
|
||||
} else {
|
||||
// can see through the sheet (may look funny when looking down)
|
||||
// maybe have 4 sheet layers instead of 2?
|
||||
vec4 c1 = sky_sheet (dir, time, sheet_tex[sheet_ind]);
|
||||
vec4 c2 = sky_box (dir, time, cube_tex[cube_ind]);
|
||||
vec4 c1 = sky_sheet (dir, time);
|
||||
vec4 c2 = sky_box (dir, time);
|
||||
return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
return vec4 (1, 0, 1, 1);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 1, binding = 0) uniform sampler samp;
|
||||
layout (set = 1, binding = 1) uniform texture2DArray textures[MaxTextures];
|
||||
layout (set = 1, binding = 0) uniform sampler2DArray Texture;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
layout (offset = 64)
|
||||
vec4 fog;
|
||||
float time;
|
||||
int texind;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 tl_st;
|
||||
|
@ -50,7 +46,7 @@ main (void)
|
|||
vec3 t_st = vec3 (warp_st (tl_st.xy, time), 0);
|
||||
vec3 e_st = vec3 (warp_st (tl_st.xy, time), 1);
|
||||
|
||||
c = texture (sampler2DArray (textures[texind], samp), t_st);
|
||||
e = texture (sampler2DArray (textures[texind], samp), e_st);
|
||||
c = texture (Texture, t_st);
|
||||
e = texture (Texture, e_st);
|
||||
frag_color = c + e;//fogBlend (c);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (location = 0) in vec4 uv_tr;
|
||||
layout (location = 1) in vec4 color;
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 1, binding = 1) uniform sampler2DArray Texture;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#version 450
|
||||
|
||||
layout (constant_id = 0) const int MaxTextures = 256;
|
||||
|
||||
layout (set = 1, binding = 1) uniform sampler2DArray Texture;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
|
|
|
@ -114,6 +114,11 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
|
|||
dfunc->vkCmdPushConstants (cmd, actx->layout,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
68, frag_size, frag_constants);
|
||||
VkDescriptorSet sets[] = {
|
||||
skin->descriptor,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
actx->layout, 1, 1, sets, 0, 0);
|
||||
}
|
||||
dfunc->vkCmdDrawIndexed (cmd, 3 * hdr->mdl.numtris, 1, 0, 0, 0);
|
||||
}
|
||||
|
@ -133,9 +138,9 @@ Vulkan_DrawAlias (entity_t *ent, qfv_renderframe_t *rFrame)
|
|||
float blend;
|
||||
} vertex_constants;
|
||||
struct {
|
||||
uint32_t texind;
|
||||
byte colorA[4];
|
||||
byte colorB[4];
|
||||
float pad;
|
||||
float base_color[4];
|
||||
float fog[4];
|
||||
} fragment_constants;
|
||||
|
@ -154,7 +159,7 @@ Vulkan_DrawAlias (entity_t *ent, qfv_renderframe_t *rFrame)
|
|||
skindesc = R_AliasGetSkindesc (animation, ent->renderer.skinnum, hdr);
|
||||
skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin);
|
||||
}
|
||||
fragment_constants.texind = skin->texind;
|
||||
fragment_constants.pad = 0;
|
||||
QuatCopy (ent->renderer.colormod, fragment_constants.base_color);
|
||||
QuatCopy (skin->colora, fragment_constants.colorA);
|
||||
QuatCopy (skin->colorb, fragment_constants.colorB);
|
||||
|
@ -205,10 +210,9 @@ alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline,
|
|||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
VkDescriptorSet sets[] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
actx->descriptors,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
actx->layout, 0, 2, sets, 0, 0);
|
||||
actx->layout, 0, 1, sets, 0, 0);
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &ctx->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &ctx->scissor);
|
||||
|
||||
|
@ -274,74 +278,25 @@ Vulkan_AliasDepthRange (qfv_renderframe_t *rFrame,
|
|||
&viewport);
|
||||
}
|
||||
|
||||
static VkDescriptorImageInfo base_sampler_info = { };
|
||||
static VkDescriptorImageInfo base_image_info = {
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
};
|
||||
static VkWriteDescriptorSet base_sampler_write = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
};
|
||||
static VkWriteDescriptorSet base_image_write = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
};
|
||||
|
||||
void
|
||||
Vulkan_AliasAddSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
|
||||
if (!actx->texindices.size) {
|
||||
Sys_Error ("ran out of skins (smart texture handling not implemented)");
|
||||
}
|
||||
skin->texind = DARRAY_REMOVE (&actx->texindices);
|
||||
|
||||
VkDescriptorImageInfo imageInfo[1];
|
||||
imageInfo[0] = base_image_info;
|
||||
imageInfo[0].imageView = skin->view;
|
||||
|
||||
VkWriteDescriptorSet write[2];
|
||||
write[0] = base_image_write;
|
||||
write[0].dstSet = actx->descriptors;
|
||||
write[0].dstArrayElement = skin->texind;
|
||||
write[0].descriptorCount = 1;
|
||||
write[0].pImageInfo = imageInfo;
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0);
|
||||
skin->descriptor = Vulkan_CreateCombinedImageSampler (ctx, skin->view,
|
||||
actx->sampler);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_AliasRemoveSkin (vulkan_ctx_t *ctx, qfv_alias_skin_t *skin)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
aliasctx_t *actx = ctx->alias_context;
|
||||
|
||||
DARRAY_APPEND (&actx->texindices, skin->texind);
|
||||
|
||||
VkDescriptorImageInfo imageInfo[1];
|
||||
imageInfo[0] = base_image_info;
|
||||
imageInfo[0].imageView = ctx->default_magenta_array->view;
|
||||
|
||||
VkWriteDescriptorSet write[2];
|
||||
write[0] = base_image_write;
|
||||
write[0].dstSet = actx->descriptors;
|
||||
write[0].dstArrayElement = skin->texind;
|
||||
write[0].descriptorCount = 1;
|
||||
write[0].pImageInfo = imageInfo;
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0);
|
||||
Vulkan_FreeTexture (ctx, skin->descriptor);
|
||||
skin->descriptor = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Alias_Init (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
|
||||
qfvPushDebug (ctx, "alias init");
|
||||
|
||||
|
@ -358,49 +313,6 @@ Vulkan_Alias_Init (vulkan_ctx_t *ctx)
|
|||
actx->layout = Vulkan_CreatePipelineLayout (ctx, "alias_layout");
|
||||
actx->sampler = Vulkan_CreateSampler (ctx, "alias_sampler");
|
||||
|
||||
//FIXME too many places
|
||||
__auto_type limits = device->physDev->properties.limits;
|
||||
actx->maxImages = min (256, limits.maxPerStageDescriptorSampledImages - 8);
|
||||
actx->pool = Vulkan_CreateDescriptorPool (ctx, "alias_pool");
|
||||
actx->setLayout = Vulkan_CreateDescriptorSetLayout (ctx, "alias_set");
|
||||
//FIXME kinda dumb
|
||||
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (1, alloca);
|
||||
for (size_t i = 0; i < layouts->size; i++) {
|
||||
layouts->a[i] = actx->setLayout;
|
||||
}
|
||||
__auto_type sets = QFV_AllocateDescriptorSet (device, actx->pool, layouts);
|
||||
actx->descriptors = sets->a[0];
|
||||
free (sets);
|
||||
|
||||
DARRAY_INIT (&actx->texindices, actx->maxImages);
|
||||
DARRAY_RESIZE (&actx->texindices, actx->maxImages);
|
||||
actx->texindices.grow = 0;
|
||||
actx->texindices.maxSize = actx->maxImages;
|
||||
for (unsigned i = 0; i < actx->maxImages; i++) {
|
||||
actx->texindices.a[i] = i;
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo samplerInfo[1];
|
||||
samplerInfo[0] = base_sampler_info;
|
||||
samplerInfo[0].sampler = actx->sampler;
|
||||
|
||||
VkDescriptorImageInfo imageInfo[actx->maxImages];
|
||||
for (unsigned i = 0; i < actx->maxImages; i++) {
|
||||
imageInfo[i] = base_image_info;
|
||||
imageInfo[i].imageView = ctx->default_magenta_array->view;
|
||||
}
|
||||
VkWriteDescriptorSet write[2];
|
||||
write[0] = base_sampler_write;
|
||||
write[0].dstSet = actx->descriptors;
|
||||
write[0].pImageInfo = samplerInfo;
|
||||
write[1] = base_image_write;
|
||||
write[1].dstSet = actx->descriptors;
|
||||
write[1].descriptorCount = actx->maxImages;
|
||||
write[1].pImageInfo = imageInfo;
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 2, write, 0, 0);
|
||||
|
||||
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
__auto_type aframe = &actx->frames.a[i];
|
||||
|
||||
|
|
|
@ -162,8 +162,11 @@ add_texture (texture_t *tx, vulkan_ctx_t *ctx)
|
|||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
vulktex_t *tex = tx->render;
|
||||
tex->texind = bctx->texture_chains.size;
|
||||
DARRAY_APPEND (&bctx->texture_chains, tex);
|
||||
if (tex->tex) {
|
||||
DARRAY_APPEND (&bctx->texture_chains, tex);
|
||||
tex->descriptor = Vulkan_CreateTextureDescriptor (ctx, tex->tex,
|
||||
bctx->sampler);
|
||||
}
|
||||
tex->tex_chain = 0;
|
||||
tex->tex_chain_tail = &tex->tex_chain;
|
||||
tex->elechain = 0;
|
||||
|
@ -261,29 +264,9 @@ clear_textures (vulkan_ctx_t *ctx)
|
|||
bctx->texture_chains.size = 0;
|
||||
}
|
||||
|
||||
static VkDescriptorImageInfo base_sampler_info = { };
|
||||
static VkDescriptorImageInfo base_image_info = {
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
||||
};
|
||||
static VkWriteDescriptorSet base_sampler_write = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
};
|
||||
static VkWriteDescriptorSet base_image_write = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
};
|
||||
|
||||
void
|
||||
Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
bspctx_t *bctx = ctx->bsp_context;
|
||||
|
||||
int i;
|
||||
model_t *m;
|
||||
mod_brush_t *brush = &r_worldentity.renderer.model->brush;
|
||||
|
@ -306,33 +289,6 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
|
|||
brush->numsubmodels = 1; // no support for submodels in non-world model
|
||||
register_textures (brush, ctx);
|
||||
}
|
||||
if (bctx->texture_chains.size > bctx->maxImages) {
|
||||
Sys_Error ("smart texture handling not implemented, want %zd textures,"
|
||||
"can support %d.",
|
||||
bctx->texture_chains.size, bctx->maxImages);
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo samplerInfo[1];
|
||||
samplerInfo[0] = base_sampler_info;
|
||||
samplerInfo[0].sampler = bctx->sampler;
|
||||
|
||||
VkDescriptorImageInfo imageInfo[bctx->maxImages];
|
||||
for (unsigned i = 0; i < bctx->maxImages; i++) {
|
||||
imageInfo[i] = base_image_info;
|
||||
imageInfo[i].imageView = ctx->default_magenta_array->view;
|
||||
if (i && i < bctx->texture_chains.size) {
|
||||
imageInfo[i].imageView = bctx->texture_chains.a[i]->tex->view;
|
||||
}
|
||||
}
|
||||
VkWriteDescriptorSet write[2];
|
||||
write[0] = base_sampler_write;
|
||||
write[0].dstSet = bctx->descriptors;
|
||||
write[0].pImageInfo = samplerInfo;
|
||||
write[1] = base_image_write;
|
||||
write[1].dstSet = bctx->descriptors;
|
||||
write[1].descriptorCount = bctx->maxImages;
|
||||
write[1].pImageInfo = imageInfo;
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 2, write, 0, 0);
|
||||
}
|
||||
|
||||
static elechain_t *
|
||||
|
@ -803,12 +759,14 @@ push_transform (vec_t *transform, VkPipelineLayout layout,
|
|||
}
|
||||
|
||||
static void
|
||||
push_texind (int32_t texind, VkPipelineLayout layout,
|
||||
qfv_devfuncs_t *dfunc, VkCommandBuffer cmd)
|
||||
bind_texture (vulktex_t *tex, uint32_t setnum, VkPipelineLayout layout,
|
||||
qfv_devfuncs_t *dfunc, VkCommandBuffer cmd)
|
||||
{
|
||||
dfunc->vkCmdPushConstants (cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
/*FIXME 64*/ 64 + field_offset (fragconst_t, texind),
|
||||
sizeof (int32_t), &texind);
|
||||
VkDescriptorSet sets[] = {
|
||||
tex->descriptor,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout, setnum, 1, sets, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -892,10 +850,9 @@ bsp_begin_subpass (QFV_BspSubpass subpass, VkPipeline pipeline,
|
|||
|
||||
VkDescriptorSet sets[] = {
|
||||
Vulkan_Matrix_Descriptors (ctx, ctx->curFrame),
|
||||
bctx->descriptors,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
layout, 0, 2, sets, 0, 0);
|
||||
layout, 0, 1, sets, 0, 0);
|
||||
|
||||
//XXX glsl_Fog_GetColor (fog);
|
||||
//XXX fog[3] = glsl_Fog_GetDensity () / 64.0;
|
||||
|
@ -928,8 +885,10 @@ bsp_begin (qfv_renderframe_t *rFrame)
|
|||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer],
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
|
||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||
bsp_begin_subpass (QFV_bspDepth, bctx->depth, bctx->layout, rFrame);
|
||||
bsp_begin_subpass (QFV_bspGBuffer, bctx->gbuf, bctx->layout, rFrame);
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -957,7 +916,9 @@ turb_begin (qfv_renderframe_t *rFrame)
|
|||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
|
||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||
bsp_begin_subpass (QFV_bspTurb, bctx->turb, bctx->layout, rFrame);
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1008,11 +969,13 @@ sky_begin (qfv_renderframe_t *rFrame)
|
|||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
|
||||
qfvPushDebug (ctx, "bsp_begin_subpass");
|
||||
if (bctx->skybox_tex) {
|
||||
bsp_begin_subpass (QFV_bspSky, bctx->skybox, bctx->layout, rFrame);
|
||||
} else {
|
||||
bsp_begin_subpass (QFV_bspSky, bctx->skysheet, bctx->layout, rFrame);
|
||||
}
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1114,8 +1077,8 @@ Vulkan_DrawWorld (qfv_renderframe_t *rFrame)
|
|||
|
||||
build_tex_elechain (tex, bctx, bframe);
|
||||
|
||||
push_texind (tex->texind, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
bind_texture (tex, 1, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspGBuffer]);
|
||||
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc,
|
||||
|
@ -1171,8 +1134,8 @@ Vulkan_DrawWaterSurfaces (qfv_renderframe_t *rFrame)
|
|||
msurface_t *surf = is->surface;
|
||||
if (tex != surf->texinfo->texture->render) {
|
||||
if (tex) {
|
||||
push_texind (tex->texind, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
bind_texture (tex, 1, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
|
@ -1188,8 +1151,8 @@ Vulkan_DrawWaterSurfaces (qfv_renderframe_t *rFrame)
|
|||
add_surf_elements (tex, is, &ec, &el, bctx, bframe);
|
||||
}
|
||||
if (tex) {
|
||||
push_texind (tex->texind, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
bind_texture (tex, 1, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspTurb]);
|
||||
|
@ -1221,6 +1184,9 @@ Vulkan_DrawSky (qfv_renderframe_t *rFrame)
|
|||
return;
|
||||
|
||||
sky_begin (rFrame);
|
||||
vulktex_t skybox = { .descriptor = bctx->skybox_descriptor };
|
||||
bind_texture (&skybox, 2, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
push_transform (identity, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
fragconst_t frag_constants = { time: vr_data.realtime };
|
||||
|
@ -1230,8 +1196,8 @@ Vulkan_DrawSky (qfv_renderframe_t *rFrame)
|
|||
msurface_t *surf = is->surface;
|
||||
if (tex != surf->texinfo->texture->render) {
|
||||
if (tex) {
|
||||
push_texind (tex->texind, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
bind_texture (tex, 1, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
|
@ -1247,8 +1213,8 @@ Vulkan_DrawSky (qfv_renderframe_t *rFrame)
|
|||
add_surf_elements (tex, is, &ec, &el, bctx, bframe);
|
||||
}
|
||||
if (tex) {
|
||||
push_texind (tex->texind, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
bind_texture (tex, 1, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
for (ec = tex->elechain; ec; ec = ec->next) {
|
||||
draw_elechain (ec, bctx->layout, dfunc,
|
||||
bframe->cmdSet.a[QFV_bspSky]);
|
||||
|
@ -1410,20 +1376,6 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx)
|
|||
bctx->layout = Vulkan_CreatePipelineLayout (ctx, "quakebsp_layout");
|
||||
bctx->sampler = Vulkan_CreateSampler (ctx, "quakebsp_sampler");
|
||||
|
||||
//FIXME too many places
|
||||
__auto_type limits = device->physDev->properties.limits;
|
||||
bctx->maxImages = min (256, limits.maxPerStageDescriptorSampledImages - 8);
|
||||
bctx->pool = Vulkan_CreateDescriptorPool (ctx, "quakebsp_pool");
|
||||
bctx->setLayout = Vulkan_CreateDescriptorSetLayout (ctx, "quakebsp_set");
|
||||
//FIXME kinda dumb
|
||||
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (1, alloca);
|
||||
for (size_t i = 0; i < layouts->size; i++) {
|
||||
layouts->a[i] = bctx->setLayout;
|
||||
}
|
||||
__auto_type sets = QFV_AllocateDescriptorSet (device, bctx->pool, layouts);
|
||||
bctx->descriptors = sets->a[0];
|
||||
free (sets);
|
||||
|
||||
for (size_t i = 0; i < frames; i++) {
|
||||
__auto_type bframe = &bctx->frames.a[i];
|
||||
|
||||
|
@ -1440,6 +1392,11 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx)
|
|||
bsp_pass_names[j]));
|
||||
}
|
||||
}
|
||||
|
||||
bctx->skybox_descriptor
|
||||
= Vulkan_CreateTextureDescriptor (ctx, bctx->default_skybox,
|
||||
bctx->sampler);
|
||||
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
|
@ -1509,6 +1466,7 @@ Vulkan_LoadSkys (const char *sky, vulkan_ctx_t *ctx)
|
|||
|
||||
if (bctx->skybox_tex) {
|
||||
Vulkan_UnloadTex (ctx, bctx->skybox_tex);
|
||||
Vulkan_FreeTexture (ctx, bctx->skybox_descriptor);
|
||||
}
|
||||
bctx->skybox_tex = 0;
|
||||
|
||||
|
@ -1518,6 +1476,9 @@ Vulkan_LoadSkys (const char *sky, vulkan_ctx_t *ctx)
|
|||
|
||||
if (!*sky || !strcasecmp (sky, "none")) {
|
||||
Sys_MaskPrintf (SYS_vulkan, "Skybox unloaded\n");
|
||||
bctx->skybox_descriptor
|
||||
= Vulkan_CreateTextureDescriptor (ctx, bctx->default_skybox,
|
||||
bctx->sampler);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1558,6 +1519,9 @@ Vulkan_LoadSkys (const char *sky, vulkan_ctx_t *ctx)
|
|||
}
|
||||
}
|
||||
if (bctx->skybox_tex) {
|
||||
bctx->skybox_descriptor
|
||||
= Vulkan_CreateTextureDescriptor (ctx, bctx->default_skybox,
|
||||
bctx->sampler);
|
||||
Sys_MaskPrintf (SYS_vulkan, "Skybox %s loaded\n", sky);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "QF/Vulkan/buffer.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
#include "QF/Vulkan/debug.h"
|
||||
#include "QF/Vulkan/descriptor.h"
|
||||
#include "QF/Vulkan/device.h"
|
||||
#include "QF/Vulkan/image.h"
|
||||
#include "QF/Vulkan/instance.h"
|
||||
|
@ -426,6 +427,14 @@ static tex_t default_magenta_tex = {1, 1, tex_rgba, 1, 0, magenta_data};
|
|||
void
|
||||
Vulkan_Texture_Init (vulkan_ctx_t *ctx)
|
||||
{
|
||||
qfvPushDebug (ctx, "texture init");
|
||||
|
||||
texturectx_t *tctx = calloc (1, sizeof (texturectx_t));
|
||||
ctx->texture_context = tctx;
|
||||
|
||||
tctx->pool = Vulkan_CreateDescriptorPool (ctx, "texture_pool");
|
||||
tctx->setLayout = Vulkan_CreateDescriptorSetLayout (ctx, "texture_set");
|
||||
|
||||
ctx->default_black = Vulkan_LoadTex (ctx, &default_black_tex, 1,
|
||||
"default_black");
|
||||
ctx->default_white = Vulkan_LoadTex (ctx, &default_white_tex, 1,
|
||||
|
@ -440,6 +449,7 @@ Vulkan_Texture_Init (vulkan_ctx_t *ctx)
|
|||
VK_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
qfvPopDebug (ctx);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -450,3 +460,65 @@ Vulkan_Texture_Shutdown (vulkan_ctx_t *ctx)
|
|||
Vulkan_UnloadTex (ctx, ctx->default_magenta);
|
||||
Vulkan_UnloadTex (ctx, ctx->default_magenta_array);
|
||||
}
|
||||
|
||||
static VkDescriptorImageInfo base_image_info = {
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
};
|
||||
static VkWriteDescriptorSet base_image_write = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
};
|
||||
|
||||
VkDescriptorSet
|
||||
Vulkan_CreateCombinedImageSampler (vulkan_ctx_t *ctx, VkImageView view,
|
||||
VkSampler sampler)
|
||||
{
|
||||
qfvPushDebug (ctx, "Vulkan_CreateCombinedImageSampler");
|
||||
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
texturectx_t *tctx = ctx->texture_context;
|
||||
|
||||
//FIXME kinda dumb
|
||||
__auto_type layouts = QFV_AllocDescriptorSetLayoutSet (1, alloca);
|
||||
for (size_t i = 0; i < layouts->size; i++) {
|
||||
layouts->a[i] = tctx->setLayout;
|
||||
}
|
||||
__auto_type sets = QFV_AllocateDescriptorSet (device, tctx->pool, layouts);
|
||||
VkDescriptorSet descriptor = sets->a[0];
|
||||
free (sets);
|
||||
|
||||
VkDescriptorImageInfo imageInfo[1];
|
||||
imageInfo[0] = base_image_info;
|
||||
imageInfo[0].sampler = sampler;
|
||||
imageInfo[0].imageView = view;
|
||||
|
||||
VkWriteDescriptorSet write[1];
|
||||
write[0] = base_image_write;
|
||||
write[0].dstSet = descriptor;
|
||||
write[0].pImageInfo = imageInfo;
|
||||
dfunc->vkUpdateDescriptorSets (device->dev, 1, write, 0, 0);
|
||||
|
||||
qfvPopDebug (ctx);
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
VkDescriptorSet
|
||||
Vulkan_CreateTextureDescriptor (vulkan_ctx_t *ctx, qfv_tex_t *tex,
|
||||
VkSampler sampler)
|
||||
{
|
||||
return Vulkan_CreateCombinedImageSampler (ctx, tex->view, sampler);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_FreeTexture (vulkan_ctx_t *ctx, VkDescriptorSet texture)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
texturectx_t *tctx = ctx->texture_context;
|
||||
|
||||
dfunc->vkFreeDescriptorSets (device->dev, tctx->pool, 1, &texture);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue