vk: consolidate and simplify texture uploading
This commit is contained in:
parent
8ba7b3649e
commit
0a5f061ba3
|
@ -639,20 +639,64 @@ static VkSampler pickSamplerForFlags( texFlags_t flags ) {
|
|||
return tglob.default_sampler_fixme;
|
||||
}
|
||||
|
||||
static qboolean loadKtx2Raw( vk_texture_t *tex, const rgbdata_t* pic );
|
||||
static void prepDestriptorSets(vk_texture_t* const tex, colorspace_hint_e colorspace_hint) {
|
||||
// TODO how should we approach this:
|
||||
// - per-texture desc sets can be inconvenient if texture is used in different incompatible contexts
|
||||
// - update descriptor sets in batch?
|
||||
if (vk_desc.next_free < MAX_TEXTURES-2) {
|
||||
const int index = tex - vk_textures;
|
||||
const VkDescriptorSet ds = vk_desc.sets[vk_desc.next_free++];
|
||||
const VkDescriptorSet ds_unorm =
|
||||
(colorspace_hint == kColorspaceGamma && tex->vk.image.view_unorm != VK_NULL_HANDLE)
|
||||
? vk_desc.sets[vk_desc.next_free++] : VK_NULL_HANDLE;
|
||||
|
||||
static qboolean uploadTexture(vk_texture_t *tex, rgbdata_t *const *const layers, int num_layers, qboolean cubemap, colorspace_hint_e colorspace_hint) {
|
||||
const VkDescriptorImageInfo dii = {
|
||||
.imageView = tex->vk.image.view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
.sampler = pickSamplerForFlags( tex->flags ),
|
||||
};
|
||||
|
||||
if (num_layers == 1 && layers[0]->type == PF_KTX2_RAW)
|
||||
return loadKtx2Raw(tex, layers[0]);
|
||||
const VkDescriptorImageInfo dii_unorm = {
|
||||
.imageView = tex->vk.image.view_unorm,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
.sampler = dii.sampler,
|
||||
};
|
||||
|
||||
const VkFormat format = VK_GetFormat(layers[0]->type, colorspace_hint);
|
||||
int mipCount = 0;
|
||||
VkWriteDescriptorSet wds[2] = { {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &dii,
|
||||
.dstSet = ds,
|
||||
}, {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &dii_unorm,
|
||||
.dstSet = ds_unorm,
|
||||
}};
|
||||
vkUpdateDescriptorSets(vk_core.device, ds_unorm != VK_NULL_HANDLE ? 2 : 1 , wds, 0, NULL);
|
||||
|
||||
tex->total_size = 0;
|
||||
// FIXME detect skybox some other way
|
||||
if (tex->vk.image.layers == 1) {
|
||||
tglob.dii_all_textures[index] = dii;
|
||||
}
|
||||
|
||||
// TODO non-rbga textures
|
||||
tex->vk.descriptor_unorm = ds_unorm != VK_NULL_HANDLE ? ds_unorm : ds;
|
||||
}
|
||||
else
|
||||
{
|
||||
tex->vk.descriptor_unorm = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean uploadRawKtx2( vk_texture_t *tex, const rgbdata_t* pic );
|
||||
|
||||
static qboolean validatePicLayers(const vk_texture_t* const tex, rgbdata_t *const *const layers, int num_layers) {
|
||||
for (int i = 0; i < num_layers; ++i) {
|
||||
// FIXME create empty black texture if there's no buffer
|
||||
if (!layers[i]->buffer) {
|
||||
|
@ -682,18 +726,31 @@ static qboolean uploadTexture(vk_texture_t *tex, rgbdata_t *const *const layers,
|
|||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean uploadTexture(vk_texture_t *tex, rgbdata_t *const *const layers, int num_layers, qboolean cubemap, colorspace_hint_e colorspace_hint) {
|
||||
tex->total_size = 0;
|
||||
|
||||
if (num_layers == 1 && layers[0]->type == PF_KTX2_RAW) {
|
||||
if (!uploadRawKtx2(tex, layers[0]))
|
||||
return false;
|
||||
} else {
|
||||
const VkFormat format = VK_GetFormat(layers[0]->type, colorspace_hint);
|
||||
int mipCount = 0;
|
||||
|
||||
// TODO non-rbga textures
|
||||
|
||||
if (!validatePicLayers(tex, layers, num_layers))
|
||||
return false;
|
||||
|
||||
tex->width = layers[0]->width;
|
||||
tex->height = layers[0]->height;
|
||||
mipCount = CalcMipmapCount( tex, true);
|
||||
|
||||
DEBUG("Uploading texture[%d] %s, mips=%d, layers=%d", (int)(tex-vk_textures), tex->name, mipCount, num_layers);
|
||||
|
||||
// TODO this vvv
|
||||
// // NOTE: only single uncompressed textures can be resamples, no mips, no layers, no sides
|
||||
// if(( tex->depth == 1 ) && (( layers->width != tex->width ) || ( layers->height != tex->height )))
|
||||
// data = GL_ResampleTexture( buf, layers->width, layers->height, tex->width, tex->height, normalMap );
|
||||
// else data = buf;
|
||||
|
||||
// TODO (not sure why, but GL does this)
|
||||
// if( !ImageDXT( layers->type ) && !FBitSet( tex->flags, TF_NOMIPMAP ) && FBitSet( layers->flags, IMAGE_ONEBIT_ALPHA ))
|
||||
// data = GL_ApplyFilter( data, tex->width, tex->height );
|
||||
|
||||
|
@ -737,59 +794,9 @@ static qboolean uploadTexture(vk_texture_t *tex, rgbdata_t *const *const layers,
|
|||
|
||||
R_VkImageUploadEnd(&tex->vk.image);
|
||||
}
|
||||
|
||||
// TODO how should we approach this:
|
||||
// - per-texture desc sets can be inconvenient if texture is used in different incompatible contexts
|
||||
// - update descriptor sets in batch?
|
||||
if (vk_desc.next_free < MAX_TEXTURES-2) {
|
||||
const int index = tex - vk_textures;
|
||||
const VkDescriptorSet ds = vk_desc.sets[vk_desc.next_free++];
|
||||
const VkDescriptorSet ds_unorm =
|
||||
(colorspace_hint == kColorspaceGamma && tex->vk.image.view_unorm != VK_NULL_HANDLE)
|
||||
? vk_desc.sets[vk_desc.next_free++] : VK_NULL_HANDLE;
|
||||
|
||||
const VkDescriptorImageInfo dii = {
|
||||
.imageView = tex->vk.image.view,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
.sampler = pickSamplerForFlags( tex->flags ),
|
||||
};
|
||||
|
||||
const VkDescriptorImageInfo dii_unorm = {
|
||||
.imageView = tex->vk.image.view_unorm,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
.sampler = dii.sampler,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet wds[2] = { {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &dii,
|
||||
.dstSet = ds,
|
||||
}, {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.pImageInfo = &dii_unorm,
|
||||
.dstSet = ds_unorm,
|
||||
}};
|
||||
vkUpdateDescriptorSets(vk_core.device, ds_unorm != VK_NULL_HANDLE ? 2 : 1 , wds, 0, NULL);
|
||||
|
||||
// FIXME handle cubemaps properly w/o this garbage. they should be the same as regular textures.
|
||||
if (num_layers == 1) {
|
||||
tglob.dii_all_textures[index] = dii;
|
||||
}
|
||||
|
||||
tex->vk.descriptor_unorm = ds_unorm != VK_NULL_HANDLE ? ds_unorm : ds;
|
||||
}
|
||||
else
|
||||
{
|
||||
tex->vk.descriptor_unorm = VK_NULL_HANDLE;
|
||||
}
|
||||
prepDestriptorSets(tex, colorspace_hint);
|
||||
|
||||
g_textures.stats.size_total += tex->total_size;
|
||||
g_textures.stats.count++;
|
||||
|
@ -826,7 +833,9 @@ const byte* VK_TextureData( unsigned int texnum )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static qboolean loadKtx2Raw( vk_texture_t *tex, const rgbdata_t* pic ) {
|
||||
static qboolean uploadRawKtx2( vk_texture_t *tex, const rgbdata_t* pic ) {
|
||||
DEBUG("Uploading raw KTX2 texture[%d] %s", (int)(tex-vk_textures), tex->name);
|
||||
|
||||
const byte *const data = pic->buffer;
|
||||
const int size = pic->size;
|
||||
|
||||
|
|
Loading…
Reference in New Issue