render target discards and block allocation
continuous-integration/drone/push Build is passing Details

pull/51/head
cosmonaut 2024-02-29 10:44:40 -08:00
parent d568810fa0
commit 8e04b0d1c9
2 changed files with 127 additions and 78 deletions

View File

@ -587,6 +587,7 @@ typedef struct Refresh_ColorAttachmentInfo
Refresh_Vec4 clearColor; /* Can be ignored by RenderPass */
Refresh_LoadOp loadOp;
Refresh_StoreOp storeOp;
uint8_t safeDiscard; /* ignored if loadOp is LOAD */
} Refresh_ColorAttachmentInfo;
typedef struct Refresh_DepthStencilAttachmentInfo
@ -600,6 +601,7 @@ typedef struct Refresh_DepthStencilAttachmentInfo
Refresh_StoreOp storeOp;
Refresh_LoadOp stencilLoadOp;
Refresh_StoreOp stencilStoreOp;
uint8_t safeDiscard; /* ignored if either loadOp or stencilLoadOp is LOAD*/
} Refresh_DepthStencilAttachmentInfo;
/* Functions */

View File

@ -2846,7 +2846,6 @@ static uint8_t VULKAN_INTERNAL_BindResourceMemory(
static uint8_t VULKAN_INTERNAL_BindMemoryForImage(
VulkanRenderer* renderer,
VkImage image,
uint8_t isRenderTarget,
VulkanMemoryUsedRegion** usedRegion
) {
uint8_t bindResult = 0;
@ -2872,7 +2871,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForImage(
renderer,
memoryTypeIndex,
&memoryRequirements,
isRenderTarget,
0,
memoryRequirements.memoryRequirements.size,
VK_NULL_HANDLE,
image,
@ -2895,11 +2894,6 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForImage(
memoryTypeIndex = 0;
requiredMemoryPropertyFlags = 0;
if (isRenderTarget)
{
Refresh_LogWarn("RenderTarget is allocated in host memory, pre-allocate your targets!");
}
Refresh_LogWarn("Out of device-local memory, allocating textures on host-local memory!");
while (VULKAN_INTERNAL_FindImageMemoryRequirements(
@ -2913,7 +2907,7 @@ static uint8_t VULKAN_INTERNAL_BindMemoryForImage(
renderer,
memoryTypeIndex,
&memoryRequirements,
isRenderTarget,
0,
memoryRequirements.memoryRequirements.size,
VK_NULL_HANDLE,
image,
@ -5448,7 +5442,6 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture(
bindResult = VULKAN_INTERNAL_BindMemoryForImage(
renderer,
texture->image,
isRenderTarget,
&texture->usedRegion
);
@ -5601,6 +5594,53 @@ static VulkanTextureHandle* VULKAN_INTERNAL_CreateTextureHandle(
return textureHandle;
}
static void VULKAN_INTERNAL_DiscardActiveTexture(
VulkanRenderer *renderer,
VulkanTextureContainer *textureContainer
) {
VulkanTextureHandle *textureHandle;
uint32_t i;
/* If a previously-discarded buffer is available, we can use that. */
for (i = 0; i < textureContainer->textureCount; i += 1)
{
textureHandle = textureContainer->textureHandles[i];
if (SDL_AtomicGet(&textureHandle->vulkanTexture->referenceCount) == 0)
{
textureContainer->activeTextureHandle = textureHandle;
return;
}
}
/* No texture handle is available, generate a new one. */
textureContainer->activeTextureHandle = VULKAN_INTERNAL_CreateTextureHandle(
renderer,
textureContainer->activeTextureHandle->vulkanTexture->dimensions.width,
textureContainer->activeTextureHandle->vulkanTexture->dimensions.height,
textureContainer->activeTextureHandle->vulkanTexture->depth,
textureContainer->activeTextureHandle->vulkanTexture->isCube,
textureContainer->activeTextureHandle->vulkanTexture->levelCount,
textureContainer->activeTextureHandle->vulkanTexture->sampleCount,
textureContainer->activeTextureHandle->vulkanTexture->format,
textureContainer->activeTextureHandle->vulkanTexture->aspectFlags,
textureContainer->activeTextureHandle->vulkanTexture->usageFlags,
0
);
EXPAND_ARRAY_IF_NEEDED(
textureContainer->textureHandles,
VulkanTextureHandle*,
textureContainer->textureCount + 1,
textureContainer->textureCapacity,
textureContainer->textureCapacity * 2
);
textureContainer->textureHandles[
textureContainer->textureCount
] = textureContainer->activeTextureHandle;
textureContainer->textureCount += 1;
}
static void VULKAN_INTERNAL_CreateRenderTarget(
VulkanRenderer *renderer,
VulkanTexture *texture,
@ -7773,6 +7813,7 @@ static void VULKAN_BeginRenderPass(
VkRenderPass renderPass;
VulkanFramebuffer *framebuffer;
VulkanTextureContainer *textureContainer;
VulkanTexture *texture;
VulkanTexture *msaaTexture = NULL;
uint32_t w, h;
@ -7787,14 +7828,29 @@ static void VULKAN_BeginRenderPass(
uint32_t framebufferWidth = UINT32_MAX;
uint32_t framebufferHeight = UINT32_MAX;
/* The framebuffer cannot be larger than the smallest attachment. */
for (i = 0; i < colorAttachmentCount; i += 1)
{
texture = ((VulkanTextureContainer*) colorAttachmentInfos[i].texture)->activeTextureHandle->vulkanTexture;
textureContainer = (VulkanTextureContainer*) colorAttachmentInfos[i].texture;
if (
colorAttachmentInfos[i].safeDiscard &&
colorAttachmentInfos[i].loadOp != REFRESH_LOADOP_LOAD &&
textureContainer->canBeDiscarded &&
SDL_AtomicGet(&textureContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveTexture(
renderer,
textureContainer
);
}
texture = textureContainer->activeTextureHandle->vulkanTexture;
w = texture->dimensions.width >> colorAttachmentInfos[i].level;
h = texture->dimensions.height >> colorAttachmentInfos[i].level;
/* The framebuffer cannot be larger than the smallest attachment. */
if (w < framebufferWidth)
{
framebufferWidth = w;
@ -7814,10 +7870,28 @@ static void VULKAN_BeginRenderPass(
if (depthStencilAttachmentInfo != NULL)
{
texture = ((VulkanTextureContainer*) depthStencilAttachmentInfo->texture)->activeTextureHandle->vulkanTexture;
textureContainer = (VulkanTextureContainer*) depthStencilAttachmentInfo->texture;
if (
depthStencilAttachmentInfo->safeDiscard &&
depthStencilAttachmentInfo->loadOp != REFRESH_LOADOP_LOAD &&
depthStencilAttachmentInfo->stencilLoadOp != REFRESH_LOADOP_LOAD &&
textureContainer->canBeDiscarded &&
SDL_AtomicGet(&textureContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveTexture(
renderer,
textureContainer
);
}
texture = textureContainer->activeTextureHandle->vulkanTexture;
w = texture->dimensions.width >> depthStencilAttachmentInfo->level;
h = texture->dimensions.height >> depthStencilAttachmentInfo->level;
/* The framebuffer cannot be larger than the smallest attachment. */
if (w < framebufferWidth)
{
framebufferWidth = w;
@ -8493,53 +8567,6 @@ static void VULKAN_INTERNAL_DiscardActiveBuffer(
bufferContainer->bufferCount += 1;
}
static void VULKAN_INTERNAL_DiscardActiveTexture(
VulkanRenderer *renderer,
VulkanTextureContainer *textureContainer
) {
VulkanTextureHandle *textureHandle;
uint32_t i;
/* If a previously-discarded buffer is available, we can use that. */
for (i = 0; i < textureContainer->textureCount; i += 1)
{
textureHandle = textureContainer->textureHandles[i];
if (SDL_AtomicGet(&textureHandle->vulkanTexture->referenceCount) == 0)
{
textureContainer->activeTextureHandle = textureHandle;
return;
}
}
/* No texture handle is available, generate a new one. */
textureContainer->activeTextureHandle = VULKAN_INTERNAL_CreateTextureHandle(
renderer,
textureContainer->activeTextureHandle->vulkanTexture->dimensions.width,
textureContainer->activeTextureHandle->vulkanTexture->dimensions.height,
textureContainer->activeTextureHandle->vulkanTexture->depth,
textureContainer->activeTextureHandle->vulkanTexture->isCube,
textureContainer->activeTextureHandle->vulkanTexture->levelCount,
textureContainer->activeTextureHandle->vulkanTexture->sampleCount,
textureContainer->activeTextureHandle->vulkanTexture->format,
textureContainer->activeTextureHandle->vulkanTexture->aspectFlags,
textureContainer->activeTextureHandle->vulkanTexture->usageFlags,
0
);
EXPAND_ARRAY_IF_NEEDED(
textureContainer->textureHandles,
VulkanTextureHandle*,
textureContainer->textureCount + 1,
textureContainer->textureCapacity,
textureContainer->textureCapacity * 2
);
textureContainer->textureHandles[
textureContainer->textureCount
] = textureContainer->activeTextureHandle;
textureContainer->textureCount += 1;
}
static void VULKAN_SetTransferData(
Refresh_Renderer *driverData,
void* data,
@ -8550,8 +8577,10 @@ static void VULKAN_SetTransferData(
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanBufferContainer *transferBufferContainer = (VulkanBufferContainer*) transferBuffer;
if (option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD && SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0)
{
if (
option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
renderer,
transferBufferContainer
@ -8617,8 +8646,11 @@ static void VULKAN_UploadToTexture(
VulkanTextureContainer *vulkanTextureContainer = (VulkanTextureContainer*) textureSlice->texture;
VkBufferImageCopy imageCopy;
if (option == REFRESH_COPYOPTIONS_SAFEDISCARD && vulkanTextureContainer->canBeDiscarded && SDL_AtomicGet(&vulkanTextureContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0)
{
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
vulkanTextureContainer->canBeDiscarded &&
SDL_AtomicGet(&vulkanTextureContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveTexture(
renderer,
vulkanTextureContainer
@ -8688,8 +8720,10 @@ static void VULKAN_UploadToBuffer(
VulkanBufferContainer *gpuBufferContainer = (VulkanBufferContainer*) gpuBuffer;
VkBufferCopy bufferCopy;
if (option == REFRESH_COPYOPTIONS_SAFEDISCARD && SDL_AtomicGet(&gpuBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0)
{
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&gpuBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
renderer,
gpuBufferContainer
@ -8741,8 +8775,10 @@ static void VULKAN_DownloadFromTexture(
VulkanBufferContainer *transferBufferContainer = (VulkanBufferContainer*) transferBuffer;
VkBufferImageCopy imageCopy;
if (option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD && SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0)
{
if (
option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
renderer,
transferBufferContainer
@ -8812,8 +8848,10 @@ static void VULKAN_DownloadFromBuffer(
VulkanBufferContainer *transferBufferContainer = (VulkanBufferContainer*) transferBuffer;
VkBufferCopy bufferCopy;
if (option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD && SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0)
{
if (
option == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&transferBufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
renderer,
transferBufferContainer
@ -8864,8 +8902,11 @@ static void VULKAN_CopyTextureToTexture(
VulkanTextureContainer *dstContainer = (VulkanTextureContainer*) destination->texture;
VkImageCopy imageCopy;
if (option == REFRESH_COPYOPTIONS_SAFEDISCARD && dstContainer->canBeDiscarded && SDL_AtomicGet(&dstContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0)
{
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
dstContainer->canBeDiscarded &&
SDL_AtomicGet(&dstContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveTexture(
renderer,
dstContainer
@ -8948,8 +8989,10 @@ static void VULKAN_CopyTextureToBuffer(
VulkanBufferContainer *bufferContainer = (VulkanBufferContainer*) gpuBuffer;
VkBufferImageCopy imageCopy;
if (option == REFRESH_COPYOPTIONS_SAFEDISCARD && SDL_AtomicGet(&bufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0)
{
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&bufferContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
renderer,
bufferContainer
@ -9020,8 +9063,10 @@ static void VULKAN_CopyBufferToTexture(
VulkanTextureContainer *textureContainer = (VulkanTextureContainer*) textureSlice->texture;
VkBufferImageCopy imageCopy;
if (option == REFRESH_COPYOPTIONS_SAFEDISCARD && textureContainer->canBeDiscarded && SDL_AtomicGet(&textureContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0)
{
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
textureContainer->canBeDiscarded && SDL_AtomicGet(&textureContainer->activeTextureHandle->vulkanTexture->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveTexture(
renderer,
textureContainer
@ -9092,8 +9137,10 @@ static void VULKAN_CopyBufferToBuffer(
VulkanBufferContainer *dstContainer = (VulkanBufferContainer*) destination;
VkBufferCopy bufferCopy;
if (option == REFRESH_COPYOPTIONS_SAFEDISCARD && SDL_AtomicGet(&dstContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0)
{
if (
option == REFRESH_COPYOPTIONS_SAFEDISCARD &&
SDL_AtomicGet(&dstContainer->activeBufferHandle->vulkanBuffer->referenceCount) > 0
) {
VULKAN_INTERNAL_DiscardActiveBuffer(
renderer,
dstContainer