Merge pull request #644 from rg3/skybox-fixes

Skybox fixes
This commit is contained in:
Yamagi 2021-01-13 18:22:44 +01:00 committed by GitHub
commit 61766edbe1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 45 deletions

View file

@ -86,6 +86,7 @@ typedef struct
VkFormat format;
VkDescriptorSet descriptorSet;
uint32_t mipLevels;
qboolean clampToEdge;
} qvktexture_t;
#define QVVKTEXTURE_INIT { \
@ -280,9 +281,9 @@ VkResult QVk_CreateImageView(const VkImage *image, VkImageAspectFlags aspectFlag
VkResult QVk_CreateImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, qvktexture_t *texture);
void QVk_CreateDepthBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *depthBuffer);
void QVk_CreateColorBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *colorBuffer, int extraFlags);
void QVk_CreateTexture(qvktexture_t *texture, const unsigned char *data, uint32_t width, uint32_t height, qvksampler_t samplerType);
void QVk_CreateTexture(qvktexture_t *texture, const unsigned char *data, uint32_t width, uint32_t height, qvksampler_t samplerType, qboolean clampToEdge);
void QVk_UpdateTextureData(qvktexture_t *texture, const unsigned char *data, uint32_t offset_x, uint32_t offset_y, uint32_t width, uint32_t height);
VkSampler QVk_UpdateTextureSampler(qvktexture_t *texture, qvksampler_t samplerType);
VkSampler QVk_UpdateTextureSampler(qvktexture_t *texture, qvksampler_t samplerType, qboolean clampToEdge);
void QVk_ReadPixels(uint8_t *dstBuffer, uint32_t width, uint32_t height);
VkResult QVk_BeginCommand(const VkCommandBuffer *commandBuffer);
void QVk_SubmitCommand(const VkCommandBuffer *commandBuffer, const VkQueue *queue);

View file

@ -148,7 +148,7 @@ qvkpipeline_t vk_worldWarpPipeline = QVKPIPELINE_INIT;
qvkpipeline_t vk_postprocessPipeline = QVKPIPELINE_INIT;
// samplers
static VkSampler vk_samplers[S_SAMPLER_CNT];
static VkSampler vk_samplers[S_SAMPLER_CNT * 2];
// Vulkan function pointers
PFN_vkCreateDebugUtilsMessengerEXT qvkCreateDebugUtilsMessengerEXT;
@ -427,12 +427,14 @@ static VkResult CreateRenderpasses()
.flags = 0,
.format = vk_swapchain.format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = msaaEnabled ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : vk_renderpasses[RP_WORLD].colorLoadOp,
// if MSAA is enabled, we don't need to preserve rendered texture data since it's kept by MSAA resolve attachment
.storeOp = msaaEnabled ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE,
// The color attachment is loaded from the previous frame and stored
// after the frame is drawn to mask geometry errors in the skybox
// that may leave some pixels without coverage.
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
},
// depth attachment
@ -503,7 +505,7 @@ static VkResult CreateRenderpasses()
.format = vk_swapchain.format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
@ -711,7 +713,7 @@ static void CreateDrawBuffers()
if (vk_renderpasses[RP_WORLD].sampleCount > 1)
{
QVk_CreateColorBuffer(vk_renderpasses[RP_WORLD].sampleCount, &vk_msaaColorbuffer,
0);
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
R_Printf(PRINT_ALL, "...created MSAAx%d color buffer\n",
vk_renderpasses[RP_WORLD].sampleCount);
}
@ -811,7 +813,7 @@ static void CreateDescriptorSetLayouts()
}
// internal helper
static void CreateSamplers()
static void CreateSamplersHelper(VkSampler *samplers, VkSamplerAddressMode addressMode)
{
VkSamplerCreateInfo samplerInfo = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
@ -820,9 +822,9 @@ static void CreateSamplers()
.magFilter = VK_FILTER_NEAREST,
.minFilter = VK_FILTER_NEAREST,
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
.addressModeU = addressMode,
.addressModeV = addressMode,
.addressModeW = addressMode,
.mipLodBias = 0.f,
.anisotropyEnable = VK_FALSE,
.maxAnisotropy = 1.f,
@ -834,22 +836,22 @@ static void CreateSamplers()
.unnormalizedCoordinates = VK_FALSE
};
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_NEAREST");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_NEAREST]));
QVk_DebugSetObjectName((uint64_t)samplers[S_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_NEAREST");
samplerInfo.maxLod = FLT_MAX;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_MIPMAP_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_MIPMAP_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_MIPMAP_NEAREST");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_MIPMAP_NEAREST]));
QVk_DebugSetObjectName((uint64_t)samplers[S_MIPMAP_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_MIPMAP_NEAREST");
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_MIPMAP_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_MIPMAP_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_MIPMAP_LINEAR");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_MIPMAP_LINEAR]));
QVk_DebugSetObjectName((uint64_t)samplers[S_MIPMAP_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_MIPMAP_LINEAR");
samplerInfo.maxLod = 1.f;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_LINEAR");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_LINEAR]));
QVk_DebugSetObjectName((uint64_t)samplers[S_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_LINEAR");
// aniso samplers
assert((vk_device.properties.limits.maxSamplerAnisotropy > 1.f) && "maxSamplerAnisotropy is 1");
@ -864,29 +866,36 @@ static void CreateSamplers()
}
samplerInfo.maxLod = 1.f;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_NEAREST");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_NEAREST]));
QVk_DebugSetObjectName((uint64_t)samplers[S_ANISO_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_NEAREST");
samplerInfo.maxLod = FLT_MAX;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_MIPMAP_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_MIPMAP_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_MIPMAP_NEAREST");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_MIPMAP_NEAREST]));
QVk_DebugSetObjectName((uint64_t)samplers[S_ANISO_MIPMAP_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_MIPMAP_NEAREST");
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_MIPMAP_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_MIPMAP_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_MIPMAP_LINEAR");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_MIPMAP_LINEAR]));
QVk_DebugSetObjectName((uint64_t)samplers[S_ANISO_MIPMAP_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_MIPMAP_LINEAR");
samplerInfo.maxLod = 1.f;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_LINEAR");
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_LINEAR]));
QVk_DebugSetObjectName((uint64_t)samplers[S_ANISO_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_LINEAR");
}
// internal helper
static void CreateSamplers()
{
CreateSamplersHelper(vk_samplers, VK_SAMPLER_ADDRESS_MODE_REPEAT);
CreateSamplersHelper(vk_samplers + S_SAMPLER_CNT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
}
// internal helper
static void DestroySamplers()
{
int i;
for (i = 0; i < S_SAMPLER_CNT; ++i)
for (i = 0; i < S_SAMPLER_CNT * 2; ++i)
{
if (vk_samplers[i] != VK_NULL_HANDLE)
vkDestroySampler(vk_device.logical, vk_samplers[i], NULL);
@ -1923,9 +1932,9 @@ qboolean QVk_Init(SDL_Window *window)
};
VK_VERIFY(vkAllocateDescriptorSets(vk_device.logical, &dsAllocInfo, &vk_colorbuffer.descriptorSet));
QVk_UpdateTextureSampler(&vk_colorbuffer, S_NEAREST);
QVk_UpdateTextureSampler(&vk_colorbuffer, S_NEAREST, false);
VK_VERIFY(vkAllocateDescriptorSets(vk_device.logical, &dsAllocInfo, &vk_colorbufferWarp.descriptorSet));
QVk_UpdateTextureSampler(&vk_colorbufferWarp, S_NEAREST);
QVk_UpdateTextureSampler(&vk_colorbufferWarp, S_NEAREST, false);
QVk_DebugSetObjectName((uint64_t)vk_colorbuffer.descriptorSet,
VK_OBJECT_TYPE_DESCRIPTOR_SET, "Descriptor Set: World Color Buffer");
@ -2364,12 +2373,16 @@ void QVk_SubmitStagingBuffers()
}
}
VkSampler QVk_UpdateTextureSampler(qvktexture_t *texture, qvksampler_t samplerType)
VkSampler QVk_UpdateTextureSampler(qvktexture_t *texture, qvksampler_t samplerType, qboolean clampToEdge)
{
assert((vk_samplers[samplerType] != VK_NULL_HANDLE) && "Sampler is VK_NULL_HANDLE!");
const int samplerIndex = samplerType + (clampToEdge ? S_SAMPLER_CNT : 0);
assert((vk_samplers[samplerIndex] != VK_NULL_HANDLE) && "Sampler is VK_NULL_HANDLE!");
texture->clampToEdge = clampToEdge;
VkDescriptorImageInfo dImgInfo = {
.sampler = vk_samplers[samplerType],
.sampler = vk_samplers[samplerIndex],
.imageView = texture->imageView,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
};
@ -2389,7 +2402,7 @@ VkSampler QVk_UpdateTextureSampler(qvktexture_t *texture, qvksampler_t samplerTy
vkUpdateDescriptorSets(vk_device.logical, 1, &writeSet, 0, NULL);
return vk_samplers[samplerType];
return vk_samplers[samplerIndex];
}
void QVk_DrawColorRect(float *ubo, VkDeviceSize uboSize, qvkrenderpasstype_t rpType)

View file

@ -317,7 +317,7 @@ void RE_Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *d
{
QVVKTEXTURE_CLEAR(vk_rawTexture);
QVk_CreateTexture(&vk_rawTexture, (unsigned char*)raw_image32, scaled_size, scaled_size,
vk_current_sampler);
vk_current_sampler, false);
QVk_DebugSetObjectName((uint64_t)vk_rawTexture.resource.image,
VK_OBJECT_TYPE_IMAGE, "Image: raw texture");
QVk_DebugSetObjectName((uint64_t)vk_rawTexture.imageView,

View file

@ -357,6 +357,38 @@ void QVk_CreateDepthBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *dept
VK_VERIFY(QVk_CreateImageView(&depthBuffer->resource.image, getDepthStencilAspect(depthBuffer->format), &depthBuffer->imageView, depthBuffer->format, depthBuffer->mipLevels));
}
static void ChangeColorBufferLayout(VkImage image, VkImageLayout fromLayout, VkImageLayout toLayout)
{
VkCommandBuffer commandBuffer = QVk_CreateCommandBuffer(&vk_transferCommandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
QVk_BeginCommand(&commandBuffer);
const VkImageSubresourceRange subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0u,
.levelCount = 1u,
.baseArrayLayer = 0u,
.layerCount = 1u,
};
const VkImageMemoryBarrier imageBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = NULL,
.srcAccessMask = 0u,
.dstAccessMask = 0u,
.oldLayout = fromLayout,
.newLayout = toLayout,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange = subresourceRange,
};
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0u, 0u, NULL, 0u, NULL, 1u, &imageBarrier);
QVk_SubmitCommand(&commandBuffer, &vk_device.transferQueue);
vkFreeCommandBuffers(vk_device.logical, vk_transferCommandPool, 1, &commandBuffer);
}
void QVk_CreateColorBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *colorBuffer, int extraFlags)
{
colorBuffer->format = vk_swapchain.format;
@ -364,9 +396,11 @@ void QVk_CreateColorBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *colo
VK_VERIFY(QVk_CreateImage(vk_swapchain.extent.width, vk_swapchain.extent.height, colorBuffer->format, VK_IMAGE_TILING_OPTIMAL, extraFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, colorBuffer));
VK_VERIFY(QVk_CreateImageView(&colorBuffer->resource.image, VK_IMAGE_ASPECT_COLOR_BIT, &colorBuffer->imageView, colorBuffer->format, colorBuffer->mipLevels));
ChangeColorBufferLayout(colorBuffer->resource.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
void QVk_CreateTexture(qvktexture_t *texture, const unsigned char *data, uint32_t width, uint32_t height, qvksampler_t samplerType)
void QVk_CreateTexture(qvktexture_t *texture, const unsigned char *data, uint32_t width, uint32_t height, qvksampler_t samplerType, qboolean clampToEdge)
{
createTextureImage(texture, data, width, height);
VK_VERIFY(QVk_CreateImageView(&texture->resource.image, VK_IMAGE_ASPECT_COLOR_BIT, &texture->imageView, texture->format, texture->mipLevels));
@ -383,7 +417,7 @@ void QVk_CreateTexture(qvktexture_t *texture, const unsigned char *data, uint32_
VK_VERIFY(vkAllocateDescriptorSets(vk_device.logical, &dsAllocInfo, &texture->descriptorSet));
// attach sampler
QVk_UpdateTextureSampler(texture, samplerType);
QVk_UpdateTextureSampler(texture, samplerType, clampToEdge);
}
void QVk_UpdateTextureData(qvktexture_t *texture, const unsigned char *data, uint32_t offset_x, uint32_t offset_y, uint32_t width, uint32_t height)
@ -633,11 +667,11 @@ void Vk_TextureMode( char *string )
{
// skip console characters - we want them unfiltered at all times
if (image->vk_texture.resource.image != VK_NULL_HANDLE && Q_stricmp(image->name, "pics/conchars.pcx"))
QVk_UpdateTextureSampler(&image->vk_texture, i);
QVk_UpdateTextureSampler(&image->vk_texture, i, image->vk_texture.clampToEdge);
}
if (vk_rawTexture.resource.image != VK_NULL_HANDLE)
QVk_UpdateTextureSampler(&vk_rawTexture, i);
QVk_UpdateTextureSampler(&vk_rawTexture, i, vk_rawTexture.clampToEdge);
}
/*
@ -673,7 +707,7 @@ void Vk_LmapTextureMode( char *string )
for (j = 0; j < MAX_LIGHTMAPS*2; j++)
{
if (vk_state.lightmap_textures[j].resource.image != VK_NULL_HANDLE)
QVk_UpdateTextureSampler(&vk_state.lightmap_textures[j], i);
QVk_UpdateTextureSampler(&vk_state.lightmap_textures[j], i, vk_state.lightmap_textures[j].clampToEdge);
}
}
@ -1026,7 +1060,7 @@ Vk_LoadPic(char *name, byte *pic, int width, int realwidth,
QVk_CreateTexture(&image->vk_texture, (unsigned char*)texBuffer,
image->upload_width, image->upload_height,
nolerp ? S_NEAREST : vk_current_sampler);
nolerp ? S_NEAREST : vk_current_sampler, (type == it_sky));
QVk_DebugSetObjectName((uint64_t)image->vk_texture.resource.image,
VK_OBJECT_TYPE_IMAGE, va("Image: %s", name));
QVk_DebugSetObjectName((uint64_t)image->vk_texture.imageView,

View file

@ -1098,7 +1098,7 @@ static void LM_UploadBlock( qboolean dynamic )
{
QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[texture]);
QVk_CreateTexture(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer,
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler);
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler, false);
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].resource.image,
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", texture));
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].imageView,
@ -1304,7 +1304,7 @@ void Vk_BeginBuildingLightmaps (model_t *m)
QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[i]);
QVk_CreateTexture(&vk_state.lightmap_textures[i], (unsigned char*)dummy,
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler);
BLOCK_WIDTH, BLOCK_HEIGHT, vk_current_lmap_sampler, false);
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].resource.image,
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", i));
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].imageView,