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; VkFormat format;
VkDescriptorSet descriptorSet; VkDescriptorSet descriptorSet;
uint32_t mipLevels; uint32_t mipLevels;
qboolean clampToEdge;
} qvktexture_t; } qvktexture_t;
#define QVVKTEXTURE_INIT { \ #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); 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_CreateDepthBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *depthBuffer);
void QVk_CreateColorBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *colorBuffer, int extraFlags); 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); 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); void QVk_ReadPixels(uint8_t *dstBuffer, uint32_t width, uint32_t height);
VkResult QVk_BeginCommand(const VkCommandBuffer *commandBuffer); VkResult QVk_BeginCommand(const VkCommandBuffer *commandBuffer);
void QVk_SubmitCommand(const VkCommandBuffer *commandBuffer, const VkQueue *queue); 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; qvkpipeline_t vk_postprocessPipeline = QVKPIPELINE_INIT;
// samplers // samplers
static VkSampler vk_samplers[S_SAMPLER_CNT]; static VkSampler vk_samplers[S_SAMPLER_CNT * 2];
// Vulkan function pointers // Vulkan function pointers
PFN_vkCreateDebugUtilsMessengerEXT qvkCreateDebugUtilsMessengerEXT; PFN_vkCreateDebugUtilsMessengerEXT qvkCreateDebugUtilsMessengerEXT;
@ -427,12 +427,14 @@ static VkResult CreateRenderpasses()
.flags = 0, .flags = 0,
.format = vk_swapchain.format, .format = vk_swapchain.format,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = msaaEnabled ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : vk_renderpasses[RP_WORLD].colorLoadOp, // The color attachment is loaded from the previous frame and stored
// if MSAA is enabled, we don't need to preserve rendered texture data since it's kept by MSAA resolve attachment // after the frame is drawn to mask geometry errors in the skybox
.storeOp = msaaEnabled ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE, // 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, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_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 .finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
}, },
// depth attachment // depth attachment
@ -503,7 +505,7 @@ static VkResult CreateRenderpasses()
.format = vk_swapchain.format, .format = vk_swapchain.format,
.samples = VK_SAMPLE_COUNT_1_BIT, .samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, .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, .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, .initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
@ -711,7 +713,7 @@ static void CreateDrawBuffers()
if (vk_renderpasses[RP_WORLD].sampleCount > 1) if (vk_renderpasses[RP_WORLD].sampleCount > 1)
{ {
QVk_CreateColorBuffer(vk_renderpasses[RP_WORLD].sampleCount, &vk_msaaColorbuffer, 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", R_Printf(PRINT_ALL, "...created MSAAx%d color buffer\n",
vk_renderpasses[RP_WORLD].sampleCount); vk_renderpasses[RP_WORLD].sampleCount);
} }
@ -811,7 +813,7 @@ static void CreateDescriptorSetLayouts()
} }
// internal helper // internal helper
static void CreateSamplers() static void CreateSamplersHelper(VkSampler *samplers, VkSamplerAddressMode addressMode)
{ {
VkSamplerCreateInfo samplerInfo = { VkSamplerCreateInfo samplerInfo = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
@ -820,9 +822,9 @@ static void CreateSamplers()
.magFilter = VK_FILTER_NEAREST, .magFilter = VK_FILTER_NEAREST,
.minFilter = VK_FILTER_NEAREST, .minFilter = VK_FILTER_NEAREST,
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT, .addressModeU = addressMode,
.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT, .addressModeV = addressMode,
.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, .addressModeW = addressMode,
.mipLodBias = 0.f, .mipLodBias = 0.f,
.anisotropyEnable = VK_FALSE, .anisotropyEnable = VK_FALSE,
.maxAnisotropy = 1.f, .maxAnisotropy = 1.f,
@ -834,22 +836,22 @@ static void CreateSamplers()
.unnormalizedCoordinates = VK_FALSE .unnormalizedCoordinates = VK_FALSE
}; };
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_NEAREST])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_NEAREST"); QVk_DebugSetObjectName((uint64_t)samplers[S_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_NEAREST");
samplerInfo.maxLod = FLT_MAX; samplerInfo.maxLod = FLT_MAX;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_MIPMAP_NEAREST])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_MIPMAP_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_MIPMAP_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: 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.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR; samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_MIPMAP_LINEAR])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_MIPMAP_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_MIPMAP_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_MIPMAP_LINEAR"); QVk_DebugSetObjectName((uint64_t)samplers[S_MIPMAP_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_MIPMAP_LINEAR");
samplerInfo.maxLod = 1.f; samplerInfo.maxLod = 1.f;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_LINEAR])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_LINEAR"); QVk_DebugSetObjectName((uint64_t)samplers[S_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_LINEAR");
// aniso samplers // aniso samplers
assert((vk_device.properties.limits.maxSamplerAnisotropy > 1.f) && "maxSamplerAnisotropy is 1"); assert((vk_device.properties.limits.maxSamplerAnisotropy > 1.f) && "maxSamplerAnisotropy is 1");
@ -864,29 +866,36 @@ static void CreateSamplers()
} }
samplerInfo.maxLod = 1.f; samplerInfo.maxLod = 1.f;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_NEAREST])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_NEAREST"); QVk_DebugSetObjectName((uint64_t)samplers[S_ANISO_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: S_ANISO_NEAREST");
samplerInfo.maxLod = FLT_MAX; samplerInfo.maxLod = FLT_MAX;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_MIPMAP_NEAREST])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_MIPMAP_NEAREST]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_MIPMAP_NEAREST], VK_OBJECT_TYPE_SAMPLER, "Sampler: 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.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR; samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_MIPMAP_LINEAR])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_MIPMAP_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_MIPMAP_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: 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; samplerInfo.maxLod = 1.f;
VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &vk_samplers[S_ANISO_LINEAR])); VK_VERIFY(vkCreateSampler(vk_device.logical, &samplerInfo, NULL, &samplers[S_ANISO_LINEAR]));
QVk_DebugSetObjectName((uint64_t)vk_samplers[S_ANISO_LINEAR], VK_OBJECT_TYPE_SAMPLER, "Sampler: 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 // internal helper
static void DestroySamplers() static void DestroySamplers()
{ {
int i; 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) if (vk_samplers[i] != VK_NULL_HANDLE)
vkDestroySampler(vk_device.logical, vk_samplers[i], NULL); 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)); 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)); 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, QVk_DebugSetObjectName((uint64_t)vk_colorbuffer.descriptorSet,
VK_OBJECT_TYPE_DESCRIPTOR_SET, "Descriptor Set: World Color Buffer"); 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 = { VkDescriptorImageInfo dImgInfo = {
.sampler = vk_samplers[samplerType], .sampler = vk_samplers[samplerIndex],
.imageView = texture->imageView, .imageView = texture->imageView,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL .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); 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) 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); QVVKTEXTURE_CLEAR(vk_rawTexture);
QVk_CreateTexture(&vk_rawTexture, (unsigned char*)raw_image32, scaled_size, scaled_size, 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, QVk_DebugSetObjectName((uint64_t)vk_rawTexture.resource.image,
VK_OBJECT_TYPE_IMAGE, "Image: raw texture"); VK_OBJECT_TYPE_IMAGE, "Image: raw texture");
QVk_DebugSetObjectName((uint64_t)vk_rawTexture.imageView, 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)); 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) void QVk_CreateColorBuffer(VkSampleCountFlagBits sampleCount, qvktexture_t *colorBuffer, int extraFlags)
{ {
colorBuffer->format = vk_swapchain.format; 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_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)); 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); createTextureImage(texture, data, width, height);
VK_VERIFY(QVk_CreateImageView(&texture->resource.image, VK_IMAGE_ASPECT_COLOR_BIT, &texture->imageView, texture->format, texture->mipLevels)); 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)); VK_VERIFY(vkAllocateDescriptorSets(vk_device.logical, &dsAllocInfo, &texture->descriptorSet));
// attach sampler // 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) 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 // 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")) 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) 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++) for (j = 0; j < MAX_LIGHTMAPS*2; j++)
{ {
if (vk_state.lightmap_textures[j].resource.image != VK_NULL_HANDLE) 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, QVk_CreateTexture(&image->vk_texture, (unsigned char*)texBuffer,
image->upload_width, image->upload_height, 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, QVk_DebugSetObjectName((uint64_t)image->vk_texture.resource.image,
VK_OBJECT_TYPE_IMAGE, va("Image: %s", name)); VK_OBJECT_TYPE_IMAGE, va("Image: %s", name));
QVk_DebugSetObjectName((uint64_t)image->vk_texture.imageView, 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]); QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[texture]);
QVk_CreateTexture(&vk_state.lightmap_textures[texture], vk_lms.lightmap_buffer, 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, QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].resource.image,
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", texture)); VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", texture));
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[texture].imageView, 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]); QVVKTEXTURE_CLEAR(vk_state.lightmap_textures[i]);
QVk_CreateTexture(&vk_state.lightmap_textures[i], (unsigned char*)dummy, 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, QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].resource.image,
VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", i)); VK_OBJECT_TYPE_IMAGE, va("Image: dynamic lightmap #%d", i));
QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].imageView, QVk_DebugSetObjectName((uint64_t)vk_state.lightmap_textures[i].imageView,