forked from MoonsideGames/Refresh
implement Clear
parent
ee91cca9f6
commit
cea9b853a4
|
@ -98,7 +98,7 @@ typedef enum REFRESH_StoreOp
|
||||||
|
|
||||||
typedef enum REFRESH_ClearOptions
|
typedef enum REFRESH_ClearOptions
|
||||||
{
|
{
|
||||||
REFRESH_CLEAROPTIONS_TARGET = 1,
|
REFRESH_CLEAROPTIONS_COLOR = 1,
|
||||||
REFRESH_CLEAROPTIONS_DEPTH = 2,
|
REFRESH_CLEAROPTIONS_DEPTH = 2,
|
||||||
REFRESH_CLEAROPTIONS_STENCIL = 4,
|
REFRESH_CLEAROPTIONS_STENCIL = 4,
|
||||||
} REFRESH_ClearOptions;
|
} REFRESH_ClearOptions;
|
||||||
|
@ -619,20 +619,25 @@ REFRESHAPI void REFRESH_DestroyDevice(REFRESH_Device *device);
|
||||||
/* Drawing */
|
/* Drawing */
|
||||||
|
|
||||||
/* Clears the targets of the currently bound framebuffer.
|
/* Clears the targets of the currently bound framebuffer.
|
||||||
|
* If fewer colors are passed than the number of color targets in the
|
||||||
|
* framebuffer, this function will clear the first n color targets.
|
||||||
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* It is generally recommended to clear in BeginRenderPass
|
* It is generally recommended to clear in BeginRenderPass
|
||||||
* rather than by calling this function.
|
* rather than by calling this function unless necessary.
|
||||||
*
|
*
|
||||||
|
* clearRect: Area to clear.
|
||||||
* options: Bitflags to specify color/depth/stencil buffers for clearing.
|
* options: Bitflags to specify color/depth/stencil buffers for clearing.
|
||||||
* colors: The new values of the cleared color buffers.
|
* colors: An array of color values for the cleared color buffers.
|
||||||
* colorCount: The amount of cleared color buffers.
|
* colorCount: The number of colors in the above array.
|
||||||
* depth: The new value of the cleared depth buffer.
|
* depth: The new value of the cleared depth buffer.
|
||||||
* stencil: The new value of the cleared stencil buffer.
|
* stencil: The new value of the cleared stencil buffer.
|
||||||
*/
|
*/
|
||||||
REFRESHAPI void REFRESH_Clear(
|
REFRESHAPI void REFRESH_Clear(
|
||||||
REFRESH_Device *device,
|
REFRESH_Device *device,
|
||||||
|
REFRESH_Rect *clearRect,
|
||||||
REFRESH_ClearOptions options,
|
REFRESH_ClearOptions options,
|
||||||
REFRESH_Vec4 **colors,
|
REFRESH_Color *colors,
|
||||||
uint32_t colorCount,
|
uint32_t colorCount,
|
||||||
float depth,
|
float depth,
|
||||||
int32_t stencil
|
int32_t stencil
|
||||||
|
|
|
@ -149,14 +149,23 @@ void REFRESH_DestroyDevice(REFRESH_Device *device)
|
||||||
|
|
||||||
void REFRESH_Clear(
|
void REFRESH_Clear(
|
||||||
REFRESH_Device *device,
|
REFRESH_Device *device,
|
||||||
|
REFRESH_Rect *clearRect,
|
||||||
REFRESH_ClearOptions options,
|
REFRESH_ClearOptions options,
|
||||||
REFRESH_Vec4 **colors,
|
REFRESH_Color *colors,
|
||||||
uint32_t colorCount,
|
uint32_t colorCount,
|
||||||
float depth,
|
float depth,
|
||||||
int32_t stencil
|
int32_t stencil
|
||||||
) {
|
) {
|
||||||
NULL_RETURN(device);
|
NULL_RETURN(device);
|
||||||
device->Clear(device->driverData, options, colors, colorCount, depth, stencil);
|
device->Clear(
|
||||||
|
device->driverData,
|
||||||
|
clearRect,
|
||||||
|
options,
|
||||||
|
colors,
|
||||||
|
colorCount,
|
||||||
|
depth,
|
||||||
|
stencil
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void REFRESH_DrawIndexedPrimitives(
|
void REFRESH_DrawIndexedPrimitives(
|
||||||
|
|
|
@ -170,8 +170,9 @@ struct REFRESH_Device
|
||||||
|
|
||||||
void (*Clear)(
|
void (*Clear)(
|
||||||
REFRESH_Renderer *driverData,
|
REFRESH_Renderer *driverData,
|
||||||
|
REFRESH_Rect *clearRect,
|
||||||
REFRESH_ClearOptions options,
|
REFRESH_ClearOptions options,
|
||||||
REFRESH_Vec4 **colors,
|
REFRESH_Color *colors,
|
||||||
uint32_t colorCount,
|
uint32_t colorCount,
|
||||||
float depth,
|
float depth,
|
||||||
int32_t stencil
|
int32_t stencil
|
||||||
|
|
|
@ -738,6 +738,8 @@ typedef struct VulkanFramebuffer
|
||||||
VulkanColorTarget *colorTargets[MAX_COLOR_TARGET_BINDINGS];
|
VulkanColorTarget *colorTargets[MAX_COLOR_TARGET_BINDINGS];
|
||||||
uint32_t colorTargetCount;
|
uint32_t colorTargetCount;
|
||||||
VulkanDepthStencilTarget *depthStencilTarget;
|
VulkanDepthStencilTarget *depthStencilTarget;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
} VulkanFramebuffer;
|
} VulkanFramebuffer;
|
||||||
|
|
||||||
/* Cache structures */
|
/* Cache structures */
|
||||||
|
@ -3253,13 +3255,112 @@ static void VULKAN_DestroyDevice(
|
||||||
|
|
||||||
static void VULKAN_Clear(
|
static void VULKAN_Clear(
|
||||||
REFRESH_Renderer *driverData,
|
REFRESH_Renderer *driverData,
|
||||||
|
REFRESH_Rect *clearRect,
|
||||||
REFRESH_ClearOptions options,
|
REFRESH_ClearOptions options,
|
||||||
REFRESH_Vec4 **colors,
|
REFRESH_Color *colors,
|
||||||
uint32_t colorCount,
|
uint32_t colorCount,
|
||||||
float depth,
|
float depth,
|
||||||
int32_t stencil
|
int32_t stencil
|
||||||
) {
|
) {
|
||||||
SDL_assert(0);
|
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||||
|
uint32_t attachmentCount, i;
|
||||||
|
VkClearAttachment clearAttachments[MAX_COLOR_TARGET_BINDINGS + 1];
|
||||||
|
VkClearRect vulkanClearRect;
|
||||||
|
VkClearValue clearValues[4];
|
||||||
|
|
||||||
|
uint8_t shouldClearColor = options & REFRESH_CLEAROPTIONS_COLOR;
|
||||||
|
uint8_t shouldClearDepth = options & REFRESH_CLEAROPTIONS_DEPTH;
|
||||||
|
uint8_t shouldClearStencil = options & REFRESH_CLEAROPTIONS_STENCIL;
|
||||||
|
|
||||||
|
uint8_t shouldClearDepthStencil = (
|
||||||
|
(shouldClearDepth || shouldClearStencil) &&
|
||||||
|
renderer->currentFramebuffer->depthStencilTarget != NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!shouldClearColor && !shouldClearDepthStencil)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vulkanClearRect.baseArrayLayer = 0;
|
||||||
|
vulkanClearRect.layerCount = 1;
|
||||||
|
vulkanClearRect.rect.offset.x = clearRect->x;
|
||||||
|
vulkanClearRect.rect.offset.y = clearRect->y;
|
||||||
|
vulkanClearRect.rect.extent.width = clearRect->w;
|
||||||
|
vulkanClearRect.rect.extent.height = clearRect->h;
|
||||||
|
|
||||||
|
attachmentCount = 0;
|
||||||
|
|
||||||
|
if (shouldClearColor)
|
||||||
|
{
|
||||||
|
for (i = 0; i < colorCount; i += 1)
|
||||||
|
{
|
||||||
|
clearValues[i].color.float32[0] = colors[i].r / 255.0f;
|
||||||
|
clearValues[i].color.float32[1] = colors[i].g / 255.0f;
|
||||||
|
clearValues[i].color.float32[2] = colors[i].b / 255.0f;
|
||||||
|
clearValues[i].color.float32[3] = colors[i].a / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < colorCount; i += 1)
|
||||||
|
{
|
||||||
|
clearAttachments[attachmentCount].aspectMask =
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
clearAttachments[attachmentCount].colorAttachment =
|
||||||
|
attachmentCount;
|
||||||
|
clearAttachments[attachmentCount].clearValue =
|
||||||
|
clearValues[attachmentCount];
|
||||||
|
attachmentCount += 1;
|
||||||
|
|
||||||
|
/* Do NOT clear the multisample image here!
|
||||||
|
* Vulkan treats them both as the same color attachment.
|
||||||
|
* Vulkan is a very good and not confusing at all API.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldClearDepthStencil)
|
||||||
|
{
|
||||||
|
clearAttachments[attachmentCount].aspectMask = 0;
|
||||||
|
clearAttachments[attachmentCount].colorAttachment = 0;
|
||||||
|
|
||||||
|
if (shouldClearDepth)
|
||||||
|
{
|
||||||
|
if (depth < 0.0f)
|
||||||
|
{
|
||||||
|
depth = 0.0f;
|
||||||
|
}
|
||||||
|
else if (depth > 1.0f)
|
||||||
|
{
|
||||||
|
depth = 1.0f;
|
||||||
|
}
|
||||||
|
clearAttachments[attachmentCount].aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
clearAttachments[attachmentCount].clearValue.depthStencil.depth = depth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clearAttachments[attachmentCount].clearValue.depthStencil.depth = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldClearStencil)
|
||||||
|
{
|
||||||
|
clearAttachments[attachmentCount].aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
clearAttachments[attachmentCount].clearValue.depthStencil.stencil = stencil;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clearAttachments[attachmentCount].clearValue.depthStencil.stencil = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
attachmentCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECORD_CMD(renderer->vkCmdClearAttachments(
|
||||||
|
renderer->currentCommandBuffer,
|
||||||
|
attachmentCount,
|
||||||
|
clearAttachments,
|
||||||
|
1,
|
||||||
|
&vulkanClearRect
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VULKAN_DrawInstancedPrimitives(
|
static void VULKAN_DrawInstancedPrimitives(
|
||||||
|
@ -4474,6 +4575,9 @@ static REFRESH_Framebuffer* VULKAN_CreateFramebuffer(
|
||||||
vulkanFramebuffer->depthStencilTarget =
|
vulkanFramebuffer->depthStencilTarget =
|
||||||
(VulkanDepthStencilTarget*) framebufferCreateInfo->pDepthStencilTarget;
|
(VulkanDepthStencilTarget*) framebufferCreateInfo->pDepthStencilTarget;
|
||||||
|
|
||||||
|
vulkanFramebuffer->width = framebufferCreateInfo->width;
|
||||||
|
vulkanFramebuffer->height = framebufferCreateInfo->height;
|
||||||
|
|
||||||
SDL_stack_free(imageViews);
|
SDL_stack_free(imageViews);
|
||||||
return (REFRESH_Framebuffer*) vulkanFramebuffer;
|
return (REFRESH_Framebuffer*) vulkanFramebuffer;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue