render targets

pull/8/head
cosmonaut 2020-12-18 16:39:03 -08:00
parent a6f13dff8d
commit ba9447ae4c
4 changed files with 445 additions and 110 deletions

View File

@ -376,6 +376,12 @@ typedef struct REFRESH_Viewport
float maxDepth;
} REFRESH_Viewport;
typedef struct REFRESH_TextureSlice
{
REFRESH_Texture *texture;
uint32_t layer; /* 0-5 for cube, or z-slice for 3D */
} REFRESH_TextureSlice;
/* State structures */
typedef struct REFRESH_SamplerStateCreateInfo
@ -565,7 +571,6 @@ typedef struct REFRESH_FramebufferCreateInfo
const REFRESH_DepthStencilTarget *pDepthTarget;
uint32_t width;
uint32_t height;
uint32_t layers;
} REFRESH_FramebufferCreateInfo;
/* Version API */
@ -778,37 +783,15 @@ REFRESHAPI REFRESH_Texture* REFRESH_CreateTextureCube(
uint8_t canBeRenderTarget
);
/* Creates a depth/stencil texture to be used with a DepthStencilTarget.
*
* format: The pixel format of the depth/stencil data.
* width: The width of the texture.
* height: The height of the texture.
*
* Returns an allocated REFRESH_Texture* object. Note that the contents of
* the texture are undefined until SetData is called.
*/
REFRESHAPI REFRESH_DepthStencilTexture* REFRESH_CreateTextureDepthStencil(
REFRESH_Device *device,
REFRESH_DepthFormat format,
uint32_t width,
uint32_t height
);
/* Creates a color target.
*
* width: The width of the color target.
* height: The height of the color target.
* format: The pixel format of the color target.
* multisampleCount: The MSAA value for the color target.
* texture: The texture that the color target will resolve to.
* textureSlice: The texture slice that the color target will resolve to.
*/
REFRESHAPI REFRESH_ColorTarget* REFRESH_GenColorTarget(
REFRESH_Device *device,
uint32_t width,
uint32_t height,
REFRESH_SurfaceFormat format,
uint32_t multisampleCount,
REFRESH_Texture *texture
REFRESH_SampleCount multisampleCount,
REFRESH_TextureSlice textureSlice
);
/* Creates a depth/stencil target.
@ -816,14 +799,12 @@ REFRESHAPI REFRESH_ColorTarget* REFRESH_GenColorTarget(
* width: The width of the depth/stencil target.
* height: The height of the depth/stencil target.
* format: The storage format of the depth/stencil target.
* texture: The texture that the depth/stencil target will resolve to.
*/
REFRESHAPI REFRESH_DepthStencilTarget* REFRESH_GenDepthStencilTarget(
REFRESH_Device *device,
uint32_t width,
uint32_t height,
REFRESH_DepthFormat format,
REFRESH_Texture *texture
REFRESH_DepthFormat format
);
/* Creates a vertex buffer to be used by Draw commands.

View File

@ -338,37 +338,16 @@ REFRESH_Texture* REFRESH_CreateTextureCube(
);
}
REFRESH_DepthStencilTexture* REFRESH_CreateTextureDepthStencil(
REFRESH_Device *device,
REFRESH_DepthFormat format,
uint32_t width,
uint32_t height
) {
NULL_RETURN_NULL(device);
return device->CreateTextureDepthStencil(
device->driverData,
format,
width,
height
);
}
REFRESH_ColorTarget* REFRESH_GenColorTarget(
REFRESH_Device *device,
uint32_t width,
uint32_t height,
REFRESH_SurfaceFormat format,
uint32_t multisampleCount,
REFRESH_Texture *texture
REFRESH_TextureSlice textureSlice
) {
NULL_RETURN_NULL(device);
return device->GenColorTarget(
device->driverData,
width,
height,
format,
multisampleCount,
texture
textureSlice
);
}
@ -376,16 +355,14 @@ REFRESH_DepthStencilTarget* REFRESH_GenDepthStencilTarget(
REFRESH_Device *device,
uint32_t width,
uint32_t height,
REFRESH_DepthFormat format,
REFRESH_Texture *texture
REFRESH_DepthFormat format
) {
NULL_RETURN_NULL(device);
return device->GenDepthStencilTarget(
device->driverData,
width,
height,
format,
texture
format
);
}

View File

@ -261,28 +261,17 @@ struct REFRESH_Device
uint8_t canBeRenderTarget
);
REFRESH_DepthStencilTexture* (*CreateTextureDepthStencil)(
REFRESH_Renderer *driverData,
REFRESH_DepthFormat format,
uint32_t width,
uint32_t height
);
REFRESH_ColorTarget* (*GenColorTarget)(
REFRESH_Renderer *driverData,
uint32_t width,
uint32_t height,
REFRESH_SurfaceFormat format,
uint32_t multisampleCount,
REFRESH_Texture *texture
REFRESH_TextureSlice textureSlice
);
REFRESH_DepthStencilTarget* (*GenDepthStencilTarget)(
REFRESH_Renderer *driverData,
uint32_t width,
uint32_t height,
REFRESH_DepthFormat format,
REFRESH_Texture *texture
REFRESH_DepthFormat format
);
REFRESH_Buffer* (*GenVertexBuffer)(
@ -526,7 +515,6 @@ struct REFRESH_Device
ASSIGN_DRIVER_FUNC(CreateTexture2D, name) \
ASSIGN_DRIVER_FUNC(CreateTexture3D, name) \
ASSIGN_DRIVER_FUNC(CreateTextureCube, name) \
ASSIGN_DRIVER_FUNC(CreateTextureDepthStencil, name) \
ASSIGN_DRIVER_FUNC(GenColorTarget, name) \
ASSIGN_DRIVER_FUNC(GenDepthStencilTarget, name) \
ASSIGN_DRIVER_FUNC(GenVertexBuffer, name) \

View File

@ -346,6 +346,8 @@ static VkBorderColor RefreshToVK_BorderColor[] =
/* Structures */
/* Memory Allocation */
typedef struct VulkanMemoryAllocation VulkanMemoryAllocation;
typedef struct VulkanMemoryFreeRegion
@ -383,6 +385,195 @@ typedef struct VulkanMemoryAllocator
VulkanMemorySubAllocator subAllocators[VK_MAX_MEMORY_TYPES];
} VulkanMemoryAllocator;
/* Memory Barriers */
typedef struct VulkanResourceAccessInfo
{
VkPipelineStageFlags stageMask;
VkAccessFlags accessMask;
VkImageLayout imageLayout;
} VulkanResourceAccessInfo;
static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] =
{
/* RESOURCE_ACCESS_NONE */
{
0,
0,
VK_IMAGE_LAYOUT_UNDEFINED
},
/* RESOURCE_ACCESS_INDEX_BUFFER */
{
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
VK_ACCESS_INDEX_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
},
/* RESOURCE_ACCESS_VERTEX_BUFFER */
{
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
VK_ACCESS_INDEX_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
},
/* RESOURCE_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER */
{
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
},
/* RESOURCE_ACCESS_VERTEX_SHADER_READ_SAMPLED_IMAGE */
{
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
},
/* RESOURCE_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER */
{
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_UNIFORM_READ_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
},
/* RESOURCE_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE */
{
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
},
/* RESOURCE_ACCESS_FRAGMENT_SHADER_READ_COLOR_ATTACHMENT */
{
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
},
/* RESOURCE_ACCESS_FRAGMENT_SHADER_READ_DEPTH_STENCIL_ATTACHMENT */
{
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
},
/* RESOURCE_ACCESS_COLOR_ATTACHMENT_READ */
{
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
},
/* RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ */
{
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
},
/* RESOURCE_ACCESS_TRANSFER_READ */
{
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
},
/* RESOURCE_ACCESS_HOST_READ */
{
VK_PIPELINE_STAGE_HOST_BIT,
VK_ACCESS_HOST_READ_BIT,
VK_IMAGE_LAYOUT_GENERAL
},
/* RESOURCE_ACCESS_PRESENT */
{
0,
0,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
},
/* RESOURCE_ACCESS_END_OF_READ */
{
0,
0,
VK_IMAGE_LAYOUT_UNDEFINED
},
/* RESOURCE_ACCESS_VERTEX_SHADER_WRITE */
{
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT,
VK_IMAGE_LAYOUT_GENERAL
},
/* RESOURCE_ACCESS_FRAGMENT_SHADER_WRITE */
{
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT,
VK_IMAGE_LAYOUT_GENERAL
},
/* RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE */
{
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
},
/* RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE */
{
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
},
/* RESOURCE_ACCESS_TRANSFER_WRITE */
{
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
},
/* RESOURCE_ACCESS_HOST_WRITE */
{
VK_PIPELINE_STAGE_HOST_BIT,
VK_ACCESS_HOST_WRITE_BIT,
VK_IMAGE_LAYOUT_GENERAL
},
/* RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE */
{
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
},
/* RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_WRITE */
{
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
},
/* RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE */
{
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED
},
/* RESOURCE_ACCESS_GENERAL */
{
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
VK_IMAGE_LAYOUT_GENERAL
}
};
/* Renderer Structure */
typedef struct QueueFamilyIndices
{
uint32_t graphicsFamily;
@ -449,6 +640,7 @@ typedef struct VulkanRenderer
VkDescriptorSetLayout fragmentParamLayout;
SDL_mutex *allocatorLock;
SDL_mutex *commandLock;
#define VULKAN_INSTANCE_FUNCTION(ext, ret, func, params) \
vkfntype_##func func;
@ -457,6 +649,8 @@ typedef struct VulkanRenderer
#include "Refresh_Driver_Vulkan_vkfuncs.h"
} VulkanRenderer;
/* Image Data */
typedef struct VulkanTexture
{
VulkanMemoryAllocation *allocation;
@ -469,7 +663,7 @@ typedef struct VulkanTexture
uint32_t depth;
uint32_t layerCount;
uint32_t levelCount;
VkFormat surfaceFormat;
VkFormat format;
VulkanResourceAccessType resourceAccessType;
} VulkanTexture;
@ -482,22 +676,40 @@ typedef struct VulkanDepthStencilTexture
VkImage image;
VkImageView view;
VkExtent2D dimensions;
VkFormat surfaceFormat;
VkFormat format;
VulkanResourceAccessType resourceAccessType;
} VulkanDepthStencilTexture;
typedef struct VulkanColorTarget
{
VulkanTexture *texture;
VkImageView imageView;
VkImageView view;
VulkanTexture *multisampleTexture;
uint32_t multisampleCount;
} VulkanColorTarget;
typedef struct VulkanDepthStencilTarget
{
VulkanDepthStencilTexture *texture;
VkImageView imageView;
VkImageView view;
} VulkanDepthStencilTarget;
/* Forward declarations */
static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer);
/* Macros */
#define RECORD_CMD(cmdCall) \
SDL_LockMutex(renderer->commandLock); \
if (renderer->currentCommandBuffer == NULL) \
{ \
VULKAN_INTERNAL_BeginCommandBuffer(renderer); \
} \
cmdCall; \
renderer->numActiveCommands += 1; \
SDL_UnlockMutex(renderer->commandLock);
/* Error Handling */
static inline const char* VkErrorMessages(VkResult code)
@ -1023,6 +1235,97 @@ static uint8_t VULKAN_INTERNAL_FindAvailableMemory(
return 1;
}
/* Memory Barriers */
static void VULKAN_INTERNAL_ImageMemoryBarrier(
VulkanRenderer *renderer,
VulkanResourceAccessType nextAccess,
VkImageAspectFlags aspectMask,
uint32_t baseLayer,
uint32_t layerCount,
uint32_t baseLevel,
uint32_t levelCount,
uint8_t discardContents,
VkImage image,
VulkanResourceAccessType *resourceAccessType
) {
VkPipelineStageFlags srcStages = 0;
VkPipelineStageFlags dstStages = 0;
VkImageMemoryBarrier memoryBarrier;
VulkanResourceAccessType prevAccess;
const VulkanResourceAccessInfo *pPrevAccessInfo, *pNextAccessInfo;
if (*resourceAccessType == nextAccess)
{
return;
}
memoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
memoryBarrier.pNext = NULL;
memoryBarrier.srcAccessMask = 0;
memoryBarrier.dstAccessMask = 0;
memoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
memoryBarrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
memoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
memoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
memoryBarrier.image = image;
memoryBarrier.subresourceRange.aspectMask = aspectMask;
memoryBarrier.subresourceRange.baseArrayLayer = baseLayer;
memoryBarrier.subresourceRange.layerCount = layerCount;
memoryBarrier.subresourceRange.baseMipLevel = baseLevel;
memoryBarrier.subresourceRange.levelCount = levelCount;
prevAccess = *resourceAccessType;
pPrevAccessInfo = &AccessMap[prevAccess];
srcStages |= pPrevAccessInfo->stageMask;
if (prevAccess > RESOURCE_ACCESS_END_OF_READ)
{
memoryBarrier.srcAccessMask |= pPrevAccessInfo->accessMask;
}
if (discardContents)
{
memoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
}
else
{
memoryBarrier.oldLayout = pPrevAccessInfo->imageLayout;
}
pNextAccessInfo = &AccessMap[nextAccess];
dstStages |= pNextAccessInfo->stageMask;
memoryBarrier.dstAccessMask |= pNextAccessInfo->accessMask;
memoryBarrier.newLayout = pNextAccessInfo->imageLayout;
if (srcStages == 0)
{
srcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
}
if (dstStages == 0)
{
dstStages = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
}
RECORD_CMD(renderer->vkCmdPipelineBarrier(
renderer->currentCommandBuffer,
srcStages,
dstStages,
0,
0,
NULL,
0,
NULL,
1,
&memoryBarrier
));
*resourceAccessType = nextAccess;
}
/* Command Buffers */
static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer)
@ -1867,7 +2170,7 @@ static REFRESH_Framebuffer* VULKAN_CreateFramebuffer(
for (i = 0; i < colorAttachmentCount; i += 1)
{
imageViews[i] = ((VulkanColorTarget*)framebufferCreateInfo->pColorTargets[i])->imageView;
imageViews[i] = ((VulkanColorTarget*)framebufferCreateInfo->pColorTargets[i])->view;
}
vkFramebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
@ -1878,7 +2181,7 @@ static REFRESH_Framebuffer* VULKAN_CreateFramebuffer(
vkFramebufferCreateInfo.pAttachments = imageViews;
vkFramebufferCreateInfo.width = framebufferCreateInfo->width;
vkFramebufferCreateInfo.height = framebufferCreateInfo->height;
vkFramebufferCreateInfo.layers = framebufferCreateInfo->layers;
vkFramebufferCreateInfo.layers = 1;
vulkanResult = renderer->vkCreateFramebuffer(
renderer->logicalDevice,
@ -1923,14 +2226,25 @@ static uint8_t VULKAN_INTERNAL_CreateTexture(
) {
VkResult vulkanResult;
VkImageCreateInfo imageCreateInfo;
VkImageCreateFlags imageCreateFlags = 0;
VkImageViewCreateInfo imageViewCreateInfo;
uint8_t findMemoryResult;
uint8_t is3D = depth > 1 ? 1 : 0;
uint8_t layerCount = isCube ? 6 : 1;
VkComponentMapping swizzle = IDENTITY_SWIZZLE;
if (isCube)
{
imageCreateFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
}
else if (is3D)
{
imageCreateFlags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
}
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.pNext = NULL;
imageCreateInfo.flags = isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
imageCreateInfo.flags = imageCreateFlags;
imageCreateInfo.imageType = imageType;
imageCreateInfo.format = format;
imageCreateInfo.extent.width = width;
@ -2036,7 +2350,7 @@ static uint8_t VULKAN_INTERNAL_CreateTexture(
texture->dimensions.width = width;
texture->dimensions.height = height;
texture->depth = depth;
texture->surfaceFormat = format;
texture->format = format;
texture->levelCount = levelCount;
texture->layerCount = layerCount;
texture->resourceAccessType = RESOURCE_ACCESS_NONE;
@ -2161,7 +2475,7 @@ static uint8_t VULKAN_INTERNAL_CreateTextureDepthStencil(
texture->dimensions.width = width;
texture->dimensions.height = height;
texture->surfaceFormat = format;
texture->format = format;
texture->resourceAccessType = RESOURCE_ACCESS_NONE;
return 1;
@ -2293,47 +2607,121 @@ static REFRESH_Texture* VULKAN_CreateTextureCube(
return (REFRESH_Texture*) result;
}
static REFRESH_DepthStencilTexture* VULKAN_CreateTextureDepthStencil(
REFRESH_Renderer *driverData,
REFRESH_DepthFormat format,
uint32_t width,
uint32_t height
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanDepthStencilTexture *result;
result = (VulkanDepthStencilTexture*) SDL_malloc(sizeof(VulkanDepthStencilTexture));
VULKAN_INTERNAL_CreateTextureDepthStencil(
renderer,
width,
height,
RefreshToVK_DepthFormat[format],
result
);
return (REFRESH_DepthStencilTexture*) result;
}
static REFRESH_ColorTarget* VULKAN_GenColorTarget(
REFRESH_Renderer *driverData,
uint32_t width,
uint32_t height,
REFRESH_SurfaceFormat format,
uint32_t multisampleCount,
REFRESH_Texture *texture
REFRESH_SampleCount multisampleCount,
REFRESH_TextureSlice textureSlice
) {
SDL_assert(0);
VkResult vulkanResult;
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanColorTarget *colorTarget = (VulkanColorTarget*) SDL_malloc(sizeof(VulkanColorTarget));
VkImageViewCreateInfo imageViewCreateInfo;
VkComponentMapping swizzle = IDENTITY_SWIZZLE;
colorTarget->texture = (VulkanTexture*) textureSlice.texture;
colorTarget->multisampleTexture = NULL;
colorTarget->multisampleCount = 1;
/* create resolve target for multisample */
if (multisampleCount > 1)
{
colorTarget->multisampleTexture =
(VulkanTexture*) SDL_malloc(sizeof(VulkanTexture));
VULKAN_INTERNAL_CreateTexture(
renderer,
colorTarget->texture->dimensions.width,
colorTarget->texture->dimensions.height,
1,
0,
RefreshToVK_SampleCount[multisampleCount],
1,
RefreshToVK_SurfaceFormat[colorTarget->texture->format],
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_TYPE_2D,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
colorTarget->multisampleTexture
);
colorTarget->multisampleCount = multisampleCount;
VULKAN_INTERNAL_ImageMemoryBarrier(
renderer,
RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE,
VK_IMAGE_ASPECT_COLOR_BIT,
0,
colorTarget->multisampleTexture->layerCount,
0,
colorTarget->multisampleTexture->levelCount,
0,
colorTarget->multisampleTexture->image,
&colorTarget->multisampleTexture->resourceAccessType
);
}
/* create framebuffer compatible views for RenderTarget */
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.pNext = NULL;
imageViewCreateInfo.flags = 0;
imageViewCreateInfo.image = colorTarget->texture->image;
imageViewCreateInfo.format = colorTarget->texture->format;
imageViewCreateInfo.components = swizzle;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.subresourceRange.baseArrayLayer = textureSlice.layer;
imageViewCreateInfo.subresourceRange.layerCount = 1;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
vulkanResult = renderer->vkCreateImageView(
renderer->logicalDevice,
&imageViewCreateInfo,
NULL,
&colorTarget->view
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResult(
"vkCreateImageView",
vulkanResult
);
REFRESH_LogError("Failed to create color attachment image view");
return NULL;
}
return (REFRESH_ColorTarget*) colorTarget;
}
static REFRESH_DepthStencilTarget* VULKAN_GenDepthStencilTarget(
REFRESH_Renderer *driverData,
uint32_t width,
uint32_t height,
REFRESH_DepthFormat format,
REFRESH_Texture *texture
REFRESH_DepthFormat format
) {
SDL_assert(0);
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanDepthStencilTarget *depthStencilTarget =
(VulkanDepthStencilTarget*) SDL_malloc(
sizeof(VulkanDepthStencilTarget)
);
VulkanDepthStencilTexture *texture =
(VulkanDepthStencilTexture*) SDL_malloc(
sizeof(VulkanDepthStencilTexture)
);
VULKAN_INTERNAL_CreateTextureDepthStencil(
renderer,
width,
height,
RefreshToVK_DepthFormat[format],
texture
);
depthStencilTarget->texture = texture;
depthStencilTarget->view = texture->view;
return (REFRESH_DepthStencilTarget*) depthStencilTarget;
}
static REFRESH_Buffer* VULKAN_GenVertexBuffer(
@ -3891,6 +4279,7 @@ static REFRESH_Device* VULKAN_CreateDevice(
/* Threading */
renderer->allocatorLock = SDL_CreateMutex();
renderer->commandLock = SDL_CreateMutex();
return result;
}