diff --git a/src/engine/renderer/tr_backend.c b/src/engine/renderer/tr_backend.c index 5aed818..5b33808 100644 --- a/src/engine/renderer/tr_backend.c +++ b/src/engine/renderer/tr_backend.c @@ -716,8 +716,8 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int vkDestroyImage(vk.device, image.handle, nullptr); vkDestroyImageView(vk.device, image.view, nullptr); vkFreeDescriptorSets(vk.device, vk.descriptor_pool, 1, &image.descriptor_set); - image = vk_create_image(cols, rows, 1, false); - vk_upload_image_data(image.handle, cols, rows, false, data); + image = vk_create_image(cols, rows, VK_FORMAT_R8G8B8A8_UNORM, 1, false); + vk_upload_image_data(image.handle, cols, rows, false, data, 4); } } else { if (dirty) { @@ -728,7 +728,7 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int // VULKAN if (vk.active) { const Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index]; - vk_upload_image_data(image.handle, cols, rows, false, data); + vk_upload_image_data(image.handle, cols, rows, false, data, 4); } } } diff --git a/src/engine/renderer/tr_image.c b/src/engine/renderer/tr_image.c index d8f51aa..1590c20 100644 --- a/src/engine/renderer/tr_image.c +++ b/src/engine/renderer/tr_image.c @@ -511,37 +511,23 @@ byte mipBlendColors[16][4] = { {0,0,255,128}, }; +struct Image_Upload_Data { + byte* buffer; + int buffer_size; + int mip_levels; + int base_level_width; + int base_level_height; +}; -/* -=============== -Upload32 - -=============== -*/ -static void Upload32( unsigned *data, - int width, int height, - qboolean mipmap, - qboolean picmip, - qboolean lightMap, - int *format, - int *pUploadWidth, int *pUploadHeight, - // VULKAN - Vk_Image& image, - bool repeat_texture - ) -{ - int samples; - unsigned *scaledBuffer = NULL; - unsigned *resampledBuffer = NULL; - int scaled_width, scaled_height; - int i, c; - byte *scan; - GLenum internalFormat = GL_RGB; - int miplevel = 0; +static Image_Upload_Data generate_image_upload_data(const byte* data, int width, int height, qboolean mipmap, qboolean picmip) { + Image_Upload_Data upload_data; + upload_data.buffer = (byte*) ri.Hunk_AllocateTempMemory(2 * 4 * width * height); // // convert to exact power of 2 sizes // + int scaled_width, scaled_height; + for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1) ; for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1) @@ -551,10 +537,11 @@ static void Upload32( unsigned *data, if ( r_roundImagesDown->integer && scaled_height > height ) scaled_height >>= 1; + byte* resampled_buffer = nullptr; if ( scaled_width != width || scaled_height != height ) { - resampledBuffer = (unsigned int*) ri.Hunk_AllocateTempMemory( scaled_width * scaled_height * 4 ); - ResampleTexture (data, width, height, resampledBuffer, scaled_width, scaled_height); - data = resampledBuffer; + resampled_buffer = (byte*) ri.Hunk_AllocateTempMemory( scaled_width * scaled_height * 4 ); + ResampleTexture ((unsigned*)data, width, height, (unsigned*)resampled_buffer, scaled_width, scaled_height); + data = resampled_buffer; width = scaled_width; height = scaled_height; } @@ -589,166 +576,168 @@ static void Upload32( unsigned *data, scaled_height >>= 1; } - scaledBuffer = (unsigned int*) ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height ); + upload_data.base_level_width = scaled_width; + upload_data.base_level_height = scaled_height; - // - // scan the texture for each channel's max values - // and verify if the alpha channel is being used or not - // - c = width*height; - scan = ((byte *)data); - samples = 3; - if (!lightMap) { - for ( i = 0; i < c; i++ ) - { - if ( scan[i*4 + 3] != 255 ) - { - samples = 4; - break; - } - } - // select proper internal format - if ( samples == 3 ) - { - if ( glConfig.textureCompression == TC_S3TC ) - { - internalFormat = GL_RGB4_S3TC; - } - else if ( r_texturebits->integer == 16 ) - { - internalFormat = GL_RGB5; - } - else if ( r_texturebits->integer == 32 ) - { - internalFormat = GL_RGB8; - } - else - { - internalFormat = 3; - } - } - else if ( samples == 4 ) - { - if ( r_texturebits->integer == 16 ) - { - internalFormat = GL_RGBA4; - } - else if ( r_texturebits->integer == 32 ) - { - internalFormat = GL_RGBA8; - } - else - { - internalFormat = 4; - } - } - } else { - internalFormat = 3; + if (scaled_width == width && scaled_height == height && !mipmap) { + upload_data.mip_levels = 1; + upload_data.buffer_size = scaled_width * scaled_height * 4; + Com_Memcpy(upload_data.buffer, data, upload_data.buffer_size); + if (resampled_buffer != nullptr) + ri.Hunk_FreeTempMemory(resampled_buffer); + return upload_data; } - // VULKAN - auto mipmap_buffer = (byte*) ri.Hunk_AllocateTempMemory(int(2.0 * 4 * scaled_width * scaled_height)); + // Use the normal mip-mapping to go down from [width, height] to [scaled_width, scaled_height] dimensions. + while (width > scaled_width || height > scaled_height) { + R_MipMap((byte *)data, width, height); - // copy or resample data as appropriate for first MIP level - if ( ( scaled_width == width ) && - ( scaled_height == height ) ) { - if (!mipmap) - { - qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - *pUploadWidth = scaled_width; - *pUploadHeight = scaled_height; - *format = internalFormat; + width >>= 1; + if (width < 1) width = 1; - // VULKAN - Com_Memcpy(mipmap_buffer, data, width * height * 4); - - goto done; - } - Com_Memcpy (scaledBuffer, data, width*height*4); - } - else - { - // use the normal mip-mapping function to go down from here - while ( width > scaled_width || height > scaled_height ) { - R_MipMap( (byte *)data, width, height ); - width >>= 1; - height >>= 1; - if ( width < 1 ) { - width = 1; - } - if ( height < 1 ) { - height = 1; - } - } - Com_Memcpy( scaledBuffer, data, width * height * 4 ); + height >>= 1; + if (height < 1) height = 1; } - R_LightScaleTexture (scaledBuffer, scaled_width, scaled_height, (qboolean) !mipmap ); + // At this point width == scaled_width and height == scaled_height. - *pUploadWidth = scaled_width; - *pUploadHeight = scaled_height; - *format = internalFormat; + unsigned* scaled_buffer = (unsigned int*) ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height ); + Com_Memcpy(scaled_buffer, data, scaled_width * scaled_height * 4); + R_LightScaleTexture(scaled_buffer, scaled_width, scaled_height, (qboolean) !mipmap); - qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer ); + int miplevel = 0; + int mip_level_size = scaled_width * scaled_height * 4; - // VULKAN - Com_Memcpy(mipmap_buffer, scaledBuffer, scaled_width * scaled_height * 4); - int mipmap_buffer_size = scaled_width * scaled_height * 4; + Com_Memcpy(upload_data.buffer, scaled_buffer, mip_level_size); + upload_data.buffer_size = mip_level_size; + + if (mipmap) { + while (scaled_width > 1 || scaled_height > 1) { + R_MipMap((byte *)scaled_buffer, scaled_width, scaled_height); - if (mipmap) - { - while (scaled_width > 1 || scaled_height > 1) - { - R_MipMap( (byte *)scaledBuffer, scaled_width, scaled_height ); scaled_width >>= 1; + if (scaled_width < 1) scaled_width = 1; + scaled_height >>= 1; - if (scaled_width < 1) - scaled_width = 1; - if (scaled_height < 1) - scaled_height = 1; + if (scaled_height < 1) scaled_height = 1; + miplevel++; + mip_level_size = scaled_width * scaled_height * 4; if ( r_colorMipLevels->integer ) { - R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] ); + R_BlendOverTexture( (byte *)scaled_buffer, scaled_width * scaled_height, mipBlendColors[miplevel] ); } - qglTexImage2D (GL_TEXTURE_2D, miplevel, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer ); - - // VULKAN - Com_Memcpy(&mipmap_buffer[mipmap_buffer_size], scaledBuffer, scaled_width * scaled_height * 4); - mipmap_buffer_size += scaled_width * scaled_height * 4; + Com_Memcpy(&upload_data.buffer[upload_data.buffer_size], scaled_buffer, mip_level_size); + upload_data.buffer_size += mip_level_size; } } + upload_data.mip_levels = miplevel + 1; -done: + ri.Hunk_FreeTempMemory(scaled_buffer); + if (resampled_buffer != nullptr) + ri.Hunk_FreeTempMemory(resampled_buffer); - // VULKAN - if (vk.active) { - image = vk_create_image(*pUploadWidth, *pUploadHeight, miplevel + 1, repeat_texture); - vk_upload_image_data(image.handle, *pUploadWidth, *pUploadHeight, mipmap == qtrue, mipmap_buffer); - } - if (mipmap_buffer != nullptr) - ri.Hunk_FreeTempMemory(mipmap_buffer); + return upload_data; +} - if (mipmap) - { +static int upload_gl_image(const Image_Upload_Data& upload_data, int texture_address_mode) { + int w = upload_data.base_level_width; + int h = upload_data.base_level_height; + + bool has_alpha = false; + for (int i = 0; i < w * h; i++) { + if (upload_data.buffer[i*4 + 3] != 255) { + has_alpha = true; + break; + } + } + int internal_format = GL_RGBA8; + if (glConfig.textureCompression && !has_alpha) { + internal_format = GL_RGB4_S3TC; + } else if (r_texturebits->integer <= 16) { + internal_format = has_alpha ? GL_RGBA4 : GL_RGB5; + } + + auto buffer = upload_data.buffer; + for (int i = 0; i < upload_data.mip_levels; i++) { + qglTexImage2D(GL_TEXTURE_2D, i, internal_format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + buffer += w * h * 4; + + w >>= 1; + if (w < 1) w = 1; + + h >>= 1; + if (h < 1) h = 1; + } + + if (upload_data.mip_levels > 1) { qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - else - { + } else { qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); } - GL_CheckErrors(); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture_address_mode); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture_address_mode); - if ( scaledBuffer != 0 ) - ri.Hunk_FreeTempMemory( scaledBuffer ); - if ( resampledBuffer != 0 ) - ri.Hunk_FreeTempMemory( resampledBuffer ); + GL_CheckErrors(); + return internal_format; } +// VULKAN +static Vk_Image upload_vk_image(const Image_Upload_Data& upload_data, bool repeat_texture) { + int w = upload_data.base_level_width; + int h = upload_data.base_level_height; + + bool has_alpha = false; + for (int i = 0; i < w * h; i++) { + if (upload_data.buffer[i*4 + 3] != 255) { + has_alpha = true; + break; + } + } + VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + if (r_texturebits->integer <= 16) { + format = has_alpha ? VK_FORMAT_B4G4R4A4_UNORM_PACK16 : VK_FORMAT_A1R5G5B5_UNORM_PACK16; + } + + int bytes_per_pixel = 4; + + if (format == VK_FORMAT_A1R5G5B5_UNORM_PACK16) { + bytes_per_pixel = 2; + auto p = (uint16_t*)upload_data.buffer; + for (int i = 0; i < upload_data.buffer_size; i += 4, p++) { + byte r = upload_data.buffer[i+0]; + byte g = upload_data.buffer[i+1]; + byte b = upload_data.buffer[i+2]; + + *p = uint32_t((b/255.0) * 31.0 + 0.5) | + (uint32_t((g/255.0) * 31.0 + 0.5) << 5) | + (uint32_t((r/255.0) * 31.0 + 0.5) << 10) | + (1 << 15); + } + } else if (format == VK_FORMAT_B4G4R4A4_UNORM_PACK16) { + bytes_per_pixel = 2; + auto p = (uint16_t*)upload_data.buffer; + for (int i = 0; i < upload_data.buffer_size; i += 4, p++) { + byte r = upload_data.buffer[i+0]; + byte g = upload_data.buffer[i+1]; + byte b = upload_data.buffer[i+2]; + byte a = upload_data.buffer[i+3]; + + *p = uint32_t((a/255.0) * 15.0 + 0.5) | + (uint32_t((r/255.0) * 15.0 + 0.5) << 4) | + (uint32_t((g/255.0) * 15.0 + 0.5) << 8) | + (uint32_t((b/255.0) * 15.0 + 0.5) << 12); + } + } + + Vk_Image image = vk_create_image(w, h, format, upload_data.mip_levels, repeat_texture); + vk_upload_image_data(image.handle, w, h, upload_data.mip_levels > 1, upload_data.buffer, bytes_per_pixel); + return image; +} /* ================ @@ -759,62 +748,51 @@ This is the only way any image_t are created */ image_t *R_CreateImage( const char *name, const byte *pic, int width, int height, qboolean mipmap, qboolean allowPicmip, int glWrapClampMode ) { - image_t *image; - qboolean isLightmap = qfalse; - long hash; if (strlen(name) >= MAX_QPATH ) { ri.Error (ERR_DROP, "R_CreateImage: \"%s\" is too long\n", name); } - if ( !strncmp( name, "*lightmap", 9 ) ) { - isLightmap = qtrue; - } if ( tr.numImages == MAX_DRAWIMAGES ) { ri.Error( ERR_DROP, "R_CreateImage: MAX_DRAWIMAGES hit\n"); } - image = tr.images[tr.numImages] = (image_t*) ri.Hunk_Alloc( sizeof( image_t ), h_low ); + // Create image_t object. + auto image = tr.images[tr.numImages] = (image_t*) ri.Hunk_Alloc( sizeof( image_t ), h_low ); image->index = tr.numImages; image->texnum = 1024 + tr.numImages; - tr.numImages++; - image->mipmap = mipmap; image->allowPicmip = allowPicmip; - strcpy (image->imgName, name); - image->width = width; image->height = height; image->wrapClampMode = glWrapClampMode; + long hash = generateHashValue(name); + image->next = hashTable[hash]; + hashTable[hash] = image; + + tr.numImages++; + + // Create corresponding GPU resource. + bool isLightmap = (strncmp(name, "*lightmap", 9) == 0); GL_SelectTexture(isLightmap ? 1 : 0); GL_Bind(image); + + Image_Upload_Data upload_data = generate_image_upload_data(pic, width, height, mipmap, allowPicmip); - Upload32( (unsigned *)pic, image->width, image->height, - image->mipmap, - allowPicmip, - isLightmap, - &image->internalFormat, - &image->uploadWidth, - &image->uploadHeight, - vk_resources.images[image->index], - glWrapClampMode == GL_REPEAT - ); - - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); - - qglBindTexture( GL_TEXTURE_2D, 0 ); + if (glActive) { + image->internalFormat = upload_gl_image(upload_data, glWrapClampMode); + } + // VULKAN + if (vk.active) { + vk_resources.images[image->index] = upload_vk_image(upload_data, glWrapClampMode == GL_REPEAT); + } if (isLightmap) { GL_SelectTexture( 0 ); } - - hash = generateHashValue(name); - image->next = hashTable[hash]; - hashTable[hash] = image; - + ri.Hunk_FreeTempMemory(upload_data.buffer); return image; } diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index d59e462..cc7241d 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -251,34 +251,9 @@ static void record_and_run_commands(VkCommandPool command_pool, VkQueue queue, s vkFreeCommandBuffers(vk.device, command_pool, 1, &command_buffer); } -static void record_image_layout_transition(VkCommandBuffer command_buffer, VkImage image, VkFormat format, +static void record_image_layout_transition(VkCommandBuffer command_buffer, VkImage image, VkImageAspectFlags image_aspect_flags, VkAccessFlags src_access_flags, VkImageLayout old_layout, VkAccessFlags dst_access_flags, VkImageLayout new_layout) { - auto has_depth_component = [](VkFormat format) { - switch (format) { - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_D16_UNORM_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - return true; - default: - return false; - } - }; - auto has_stencil_component = [](VkFormat format) { - switch (format) { - case VK_FORMAT_S8_UINT: - case VK_FORMAT_D16_UNORM_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - return true; - default: - return false; - } - }; - VkImageMemoryBarrier barrier; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.pNext = nullptr; @@ -289,18 +264,7 @@ static void record_image_layout_transition(VkCommandBuffer command_buffer, VkIma barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.image = image; - - bool depth = has_depth_component(format); - bool stencil = has_stencil_component(format); - if (depth && stencil) - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - else if (depth) - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - else if (stencil) - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; - else - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - + barrier.subresourceRange.aspectMask = image_aspect_flags; barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; barrier.subresourceRange.baseArrayLayer = 0; @@ -860,8 +824,12 @@ void vk_initialize() { VK_CHECK(vkCreateImageView(vk.device, &desc, nullptr, &vk.depth_image_view)); } - record_and_run_commands(vk.command_pool, vk.queue, [&depth_format](VkCommandBuffer command_buffer) { - record_image_layout_transition(command_buffer, vk.depth_image, depth_format, 0, VK_IMAGE_LAYOUT_UNDEFINED, + VkImageAspectFlags image_aspect_flags = VK_IMAGE_ASPECT_DEPTH_BIT; + if (r_stencilbits->integer) + image_aspect_flags |= VK_IMAGE_ASPECT_STENCIL_BIT; + + record_and_run_commands(vk.command_pool, vk.queue, [&image_aspect_flags](VkCommandBuffer command_buffer) { + record_image_layout_transition(command_buffer, vk.depth_image, image_aspect_flags, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); }); } @@ -1321,7 +1289,7 @@ static void record_buffer_memory_barrier(VkCommandBuffer cb, VkBuffer buffer, vkCmdPipelineBarrier(cb, src_stages, dst_stages, 0, 0, nullptr, 1, &barrier, 0, nullptr); } -Vk_Image vk_create_image(int width, int height, int mip_levels, bool repeat_texture) { +Vk_Image vk_create_image(int width, int height, VkFormat format, int mip_levels, bool repeat_texture) { Vk_Image image; // create image @@ -1331,7 +1299,7 @@ Vk_Image vk_create_image(int width, int height, int mip_levels, bool repeat_text desc.pNext = nullptr; desc.flags = 0; desc.imageType = VK_IMAGE_TYPE_2D; - desc.format = VK_FORMAT_R8G8B8A8_UNORM; + desc.format = format; desc.extent.width = width; desc.extent.height = height; desc.extent.depth = 1; @@ -1357,7 +1325,7 @@ Vk_Image vk_create_image(int width, int height, int mip_levels, bool repeat_text desc.flags = 0; desc.image = image.handle; desc.viewType = VK_IMAGE_VIEW_TYPE_2D; - desc.format = VK_FORMAT_R8G8B8A8_UNORM; + desc.format = format; desc.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; desc.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; desc.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; @@ -1387,7 +1355,7 @@ Vk_Image vk_create_image(int width, int height, int mip_levels, bool repeat_text return image; } -void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, const uint8_t* rgba_pixels) { +void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, const uint8_t* pixels, int bytes_per_pixel) { VkBufferImageCopy regions[16]; int num_regions = 0; @@ -1408,7 +1376,7 @@ void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, con regions[num_regions] = region; num_regions++; - buffer_size += width * height * 4; + buffer_size += width * height * bytes_per_pixel; if (!mipmap || (width == 1 && height == 1)) break; @@ -1421,7 +1389,7 @@ void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, con } ensure_staging_buffer_allocation(buffer_size); - Com_Memcpy(vk_resources.staging_buffer_ptr, rgba_pixels, buffer_size); + Com_Memcpy(vk_resources.staging_buffer_ptr, pixels, buffer_size); record_and_run_commands(vk.command_pool, vk.queue, [&image, &num_regions, ®ions](VkCommandBuffer command_buffer) { @@ -1430,12 +1398,12 @@ void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, con VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); - record_image_layout_transition(command_buffer, image, VK_FORMAT_R8G8B8A8_UNORM, + record_image_layout_transition(command_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); vkCmdCopyBufferToImage(command_buffer, vk_resources.staging_buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, num_regions, regions); - record_image_layout_transition(command_buffer, image, VK_FORMAT_R8G8B8A8_UNORM, + record_image_layout_transition(command_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); }); } @@ -2336,11 +2304,11 @@ void vk_read_pixels(byte* buffer) { VK_CHECK(vkBindImageMemory(vk.device, image, memory, 0)); record_and_run_commands(vk.command_pool, vk.queue, [&image](VkCommandBuffer command_buffer) { - record_image_layout_transition(command_buffer, vk.swapchain_images[vk.swapchain_image_index], vk.surface_format.format, + record_image_layout_transition(command_buffer, vk.swapchain_images[vk.swapchain_image_index], VK_IMAGE_ASPECT_COLOR_BIT, VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - record_image_layout_transition(command_buffer, image, VK_FORMAT_R8G8B8A8_UNORM, + record_image_layout_transition(command_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL); }); diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index 1991173..df733f5 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -86,8 +86,8 @@ void vk_release_resources(); // // Resources allocation. // -Vk_Image vk_create_image(int width, int height, int mip_levels, bool repeat_texture); -void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, const uint8_t* rgba_pixels); +Vk_Image vk_create_image(int width, int height, VkFormat format, int mip_levels, bool repeat_texture); +void vk_upload_image_data(VkImage image, int width, int height, bool mipmap, const uint8_t* pixels, int bytes_per_pixel); void vk_update_descriptor_set(VkDescriptorSet set, VkImageView image_view, bool mipmap, bool repeat_texture); VkSampler vk_find_sampler(const Vk_Sampler_Def& def); VkPipeline vk_find_pipeline(const Vk_Pipeline_Def& def);