forked from MoonsideGames/Refresh
viewport and scissor ABI break
parent
9422d4975f
commit
f6b96fe34b
|
@ -485,14 +485,6 @@ typedef struct Refresh_ComputeShaderInfo
|
|||
uint32_t imageBindingCount;
|
||||
} Refresh_ComputeShaderInfo;
|
||||
|
||||
typedef struct Refresh_ViewportState
|
||||
{
|
||||
const Refresh_Viewport *viewports;
|
||||
uint32_t viewportCount;
|
||||
const Refresh_Rect *scissors;
|
||||
uint32_t scissorCount;
|
||||
} Refresh_ViewportState;
|
||||
|
||||
typedef struct Refresh_RasterizerState
|
||||
{
|
||||
uint8_t depthClampEnable;
|
||||
|
@ -546,7 +538,6 @@ typedef struct Refresh_GraphicsPipelineCreateInfo
|
|||
Refresh_GraphicsShaderInfo fragmentShaderInfo;
|
||||
Refresh_VertexInputState vertexInputState;
|
||||
Refresh_PrimitiveType primitiveType;
|
||||
Refresh_ViewportState viewportState;
|
||||
Refresh_RasterizerState rasterizerState;
|
||||
Refresh_MultisampleState multisampleState;
|
||||
Refresh_DepthStencilState depthStencilState;
|
||||
|
@ -991,6 +982,7 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline(
|
|||
/* Graphics State */
|
||||
|
||||
/* Begins a render pass.
|
||||
* This will also set a default viewport and scissor state.
|
||||
*
|
||||
* renderArea:
|
||||
* The area affected by the render pass.
|
||||
|
@ -1024,6 +1016,20 @@ REFRESHAPI void Refresh_BindGraphicsPipeline(
|
|||
Refresh_GraphicsPipeline *graphicsPipeline
|
||||
);
|
||||
|
||||
/* Sets the current viewport state. */
|
||||
REFRESHAPI void Refresh_SetViewportState(
|
||||
Refresh_Device *device,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Viewport *viewport
|
||||
);
|
||||
|
||||
/* Sets the current scissor state. */
|
||||
REFRESHAPI void Refresh_SetScissorState(
|
||||
Refresh_Device *device,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Rect *scissor
|
||||
);
|
||||
|
||||
/* Binds vertex buffers for use with subsequent draw calls. */
|
||||
REFRESHAPI void Refresh_BindVertexBuffers(
|
||||
Refresh_Device *device,
|
||||
|
|
|
@ -601,6 +601,32 @@ void Refresh_EndRenderPass(
|
|||
);
|
||||
}
|
||||
|
||||
void Refresh_SetViewportState(
|
||||
Refresh_Device *device,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Viewport *viewport
|
||||
) {
|
||||
NULL_RETURN(device)
|
||||
device->SetViewportState(
|
||||
device->driverData,
|
||||
commandBuffer,
|
||||
viewport
|
||||
);
|
||||
}
|
||||
|
||||
void Refresh_SetScissorState(
|
||||
Refresh_Device *device,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Rect *scissor
|
||||
) {
|
||||
NULL_RETURN(device)
|
||||
device->SetScissorState(
|
||||
device->driverData,
|
||||
commandBuffer,
|
||||
scissor
|
||||
);
|
||||
}
|
||||
|
||||
void Refresh_BindGraphicsPipeline(
|
||||
Refresh_Device *device,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
|
|
|
@ -390,6 +390,18 @@ struct Refresh_Device
|
|||
Refresh_CommandBuffer *commandBuffer
|
||||
);
|
||||
|
||||
void(*SetViewportState)(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Viewport *viewport
|
||||
);
|
||||
|
||||
void(*SetScissorState)(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Rect *scissor
|
||||
);
|
||||
|
||||
void(*BindGraphicsPipeline)(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
|
@ -495,6 +507,8 @@ struct Refresh_Device
|
|||
ASSIGN_DRIVER_FUNC(QueueDestroyGraphicsPipeline, name) \
|
||||
ASSIGN_DRIVER_FUNC(BeginRenderPass, name) \
|
||||
ASSIGN_DRIVER_FUNC(EndRenderPass, name) \
|
||||
ASSIGN_DRIVER_FUNC(SetViewportState, name) \
|
||||
ASSIGN_DRIVER_FUNC(SetScissorState, name) \
|
||||
ASSIGN_DRIVER_FUNC(BindGraphicsPipeline, name) \
|
||||
ASSIGN_DRIVER_FUNC(BindVertexBuffers, name) \
|
||||
ASSIGN_DRIVER_FUNC(BindIndexBuffer, name) \
|
||||
|
|
|
@ -1495,6 +1495,9 @@ typedef struct VulkanCommandBuffer
|
|||
uint32_t boundDescriptorSetDataCount;
|
||||
uint32_t boundDescriptorSetDataCapacity;
|
||||
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
|
||||
/* Track used resources */
|
||||
|
||||
VulkanBuffer **usedBuffers;
|
||||
|
@ -5763,8 +5766,6 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
|
|||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo;
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportStateCreateInfo;
|
||||
VkViewport *viewports = SDL_stack_alloc(VkViewport, pipelineCreateInfo->viewportState.viewportCount);
|
||||
VkRect2D *scissors = SDL_stack_alloc(VkRect2D, pipelineCreateInfo->viewportState.scissorCount);
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo;
|
||||
|
||||
|
@ -5780,6 +5781,13 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
|
|||
pipelineCreateInfo->attachmentInfo.colorAttachmentCount
|
||||
);
|
||||
|
||||
static const VkDynamicState dynamicStates[] =
|
||||
{
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR
|
||||
};
|
||||
VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo;
|
||||
|
||||
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
|
||||
|
||||
/* Create a "compatible" render pass */
|
||||
|
@ -5789,6 +5797,14 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
|
|||
pipelineCreateInfo->attachmentInfo
|
||||
);
|
||||
|
||||
/* Dynamic state */
|
||||
|
||||
dynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamicStateCreateInfo.pNext = NULL;
|
||||
dynamicStateCreateInfo.flags = 0;
|
||||
dynamicStateCreateInfo.dynamicStateCount = SDL_arraysize(dynamicStates);
|
||||
dynamicStateCreateInfo.pDynamicStates = dynamicStates;
|
||||
|
||||
/* Shader stages */
|
||||
|
||||
graphicsPipeline->vertexShaderModule = (VulkanShaderModule*) pipelineCreateInfo->vertexShaderInfo.shaderModule;
|
||||
|
@ -5868,31 +5884,15 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
|
|||
|
||||
/* Viewport */
|
||||
|
||||
for (i = 0; i < pipelineCreateInfo->viewportState.viewportCount; i += 1)
|
||||
{
|
||||
viewports[i].x = pipelineCreateInfo->viewportState.viewports[i].x;
|
||||
viewports[i].y = pipelineCreateInfo->viewportState.viewports[i].y;
|
||||
viewports[i].width = pipelineCreateInfo->viewportState.viewports[i].w;
|
||||
viewports[i].height = pipelineCreateInfo->viewportState.viewports[i].h;
|
||||
viewports[i].minDepth = pipelineCreateInfo->viewportState.viewports[i].minDepth;
|
||||
viewports[i].maxDepth = pipelineCreateInfo->viewportState.viewports[i].maxDepth;
|
||||
}
|
||||
|
||||
for (i = 0; i < pipelineCreateInfo->viewportState.scissorCount; i += 1)
|
||||
{
|
||||
scissors[i].offset.x = pipelineCreateInfo->viewportState.scissors[i].x;
|
||||
scissors[i].offset.y = pipelineCreateInfo->viewportState.scissors[i].y;
|
||||
scissors[i].extent.width = pipelineCreateInfo->viewportState.scissors[i].w;
|
||||
scissors[i].extent.height = pipelineCreateInfo->viewportState.scissors[i].h;
|
||||
}
|
||||
/* NOTE: viewport and scissor are dynamic, and must be set using the command buffer */
|
||||
|
||||
viewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportStateCreateInfo.pNext = NULL;
|
||||
viewportStateCreateInfo.flags = 0;
|
||||
viewportStateCreateInfo.viewportCount = pipelineCreateInfo->viewportState.viewportCount;
|
||||
viewportStateCreateInfo.pViewports = viewports;
|
||||
viewportStateCreateInfo.scissorCount = pipelineCreateInfo->viewportState.scissorCount;
|
||||
viewportStateCreateInfo.pScissors = scissors;
|
||||
viewportStateCreateInfo.viewportCount = 1;
|
||||
viewportStateCreateInfo.pViewports = NULL;
|
||||
viewportStateCreateInfo.scissorCount = 1;
|
||||
viewportStateCreateInfo.pScissors = NULL;
|
||||
|
||||
/* Rasterization */
|
||||
|
||||
|
@ -6071,7 +6071,7 @@ static Refresh_GraphicsPipeline* VULKAN_CreateGraphicsPipeline(
|
|||
vkPipelineCreateInfo.pMultisampleState = &multisampleStateCreateInfo;
|
||||
vkPipelineCreateInfo.pDepthStencilState = &depthStencilStateCreateInfo;
|
||||
vkPipelineCreateInfo.pColorBlendState = &colorBlendStateCreateInfo;
|
||||
vkPipelineCreateInfo.pDynamicState = VK_NULL_HANDLE;
|
||||
vkPipelineCreateInfo.pDynamicState = &dynamicStateCreateInfo;
|
||||
vkPipelineCreateInfo.layout = graphicsPipeline->pipelineLayout->pipelineLayout;
|
||||
vkPipelineCreateInfo.renderPass = transientRenderPass;
|
||||
vkPipelineCreateInfo.subpass = 0;
|
||||
|
@ -7786,7 +7786,9 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer(
|
|||
VkRenderPass renderPass,
|
||||
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
|
||||
uint32_t colorAttachmentCount,
|
||||
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
|
||||
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo,
|
||||
uint32_t width,
|
||||
uint32_t height
|
||||
) {
|
||||
VkFramebuffer framebuffer;
|
||||
VkFramebufferCreateInfo framebufferInfo;
|
||||
|
@ -7794,10 +7796,7 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer(
|
|||
VkImageView imageViewAttachments[2 * MAX_COLOR_TARGET_BINDINGS + 1];
|
||||
FramebufferHash hash;
|
||||
VulkanRenderTarget *renderTarget;
|
||||
VulkanTexture *texture;
|
||||
uint32_t attachmentCount = 0;
|
||||
uint32_t maxWidth = 0;
|
||||
uint32_t maxHeight = 0;
|
||||
uint32_t i;
|
||||
|
||||
SDL_LockMutex(renderer->framebufferFetchLock);
|
||||
|
@ -7821,8 +7820,6 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer(
|
|||
colorAttachmentInfos[i].sampleCount
|
||||
);
|
||||
|
||||
texture = (VulkanTexture*) colorAttachmentInfos[i].texture;
|
||||
|
||||
hash.colorAttachmentViews[i] = (
|
||||
renderTarget->view
|
||||
);
|
||||
|
@ -7833,16 +7830,6 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer(
|
|||
renderTarget->multisampleTexture->view
|
||||
);
|
||||
}
|
||||
|
||||
if (texture->dimensions.width > maxWidth)
|
||||
{
|
||||
maxWidth = texture->dimensions.width;
|
||||
}
|
||||
|
||||
if (texture->dimensions.height > maxHeight)
|
||||
{
|
||||
maxHeight = texture->dimensions.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (depthStencilAttachmentInfo == NULL)
|
||||
|
@ -7860,20 +7847,10 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer(
|
|||
REFRESH_SAMPLECOUNT_1
|
||||
);
|
||||
hash.depthStencilAttachmentView = renderTarget->view;
|
||||
|
||||
if (texture->dimensions.width > maxWidth)
|
||||
{
|
||||
maxWidth = texture->dimensions.width;
|
||||
}
|
||||
|
||||
if (texture->dimensions.height > maxHeight)
|
||||
{
|
||||
maxHeight = texture->dimensions.height;
|
||||
}
|
||||
}
|
||||
|
||||
hash.width = maxWidth;
|
||||
hash.height = maxHeight;
|
||||
hash.width = width;
|
||||
hash.height = height;
|
||||
|
||||
framebuffer = FramebufferHashArray_Fetch(
|
||||
&renderer->framebufferHashArray,
|
||||
|
@ -7964,6 +7941,84 @@ static VkFramebuffer VULKAN_INTERNAL_FetchFramebuffer(
|
|||
return framebuffer;
|
||||
}
|
||||
|
||||
static void VULKAN_INTERNAL_SetCurrentViewport(
|
||||
VulkanCommandBuffer *commandBuffer,
|
||||
Refresh_Viewport *viewport
|
||||
) {
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
|
||||
vulkanCommandBuffer->currentViewport.x = viewport->x;
|
||||
vulkanCommandBuffer->currentViewport.y = viewport->y;
|
||||
vulkanCommandBuffer->currentViewport.width = viewport->w;
|
||||
vulkanCommandBuffer->currentViewport.height = viewport->h;
|
||||
vulkanCommandBuffer->currentViewport.minDepth = viewport->minDepth;
|
||||
vulkanCommandBuffer->currentViewport.maxDepth = viewport->maxDepth;
|
||||
}
|
||||
|
||||
static void VULKAN_SetViewportState(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Viewport *viewport
|
||||
) {
|
||||
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
|
||||
if (!vulkanCommandBuffer->renderPassInProgress)
|
||||
{
|
||||
Refresh_LogError("Illegal to set viewport state outside of a render pass!");
|
||||
return;
|
||||
}
|
||||
|
||||
VULKAN_INTERNAL_SetCurrentViewport(
|
||||
vulkanCommandBuffer,
|
||||
viewport
|
||||
);
|
||||
|
||||
renderer->vkCmdSetViewport(
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
0,
|
||||
1,
|
||||
&vulkanCommandBuffer->currentViewport
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_INTERNAL_SetCurrentScissor(
|
||||
VulkanCommandBuffer *vulkanCommandBuffer,
|
||||
Refresh_Rect *scissor
|
||||
) {
|
||||
vulkanCommandBuffer->currentScissor.offset.x = scissor->x;
|
||||
vulkanCommandBuffer->currentScissor.offset.y = scissor->y;
|
||||
vulkanCommandBuffer->currentScissor.extent.width = scissor->w;
|
||||
vulkanCommandBuffer->currentScissor.extent.height = scissor->h;
|
||||
}
|
||||
|
||||
static void VULKAN_SetScissorState(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
Refresh_Rect *scissor
|
||||
) {
|
||||
VulkanRenderer* renderer = (VulkanRenderer*) driverData;
|
||||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
|
||||
if (!vulkanCommandBuffer->renderPassInProgress)
|
||||
{
|
||||
Refresh_LogError("Illegal to set scissor state outside of a render pass!");
|
||||
return;
|
||||
}
|
||||
|
||||
VULKAN_INTERNAL_SetCurrentScissor(
|
||||
vulkanCommandBuffer,
|
||||
scissor
|
||||
);
|
||||
|
||||
renderer->vkCmdSetScissor(
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
0,
|
||||
1,
|
||||
&vulkanCommandBuffer->currentScissor
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_BeginRenderPass(
|
||||
Refresh_Renderer *driverData,
|
||||
Refresh_CommandBuffer *commandBuffer,
|
||||
|
@ -7982,6 +8037,10 @@ static void VULKAN_BeginRenderPass(
|
|||
uint32_t clearCount = colorAttachmentCount;
|
||||
uint32_t i;
|
||||
VkImageAspectFlags depthAspectFlags;
|
||||
Refresh_Viewport defaultViewport;
|
||||
Refresh_Rect defaultScissor;
|
||||
uint32_t framebufferWidth = UINT32_MAX;
|
||||
uint32_t framebufferHeight = UINT32_MAX;
|
||||
|
||||
if (colorAttachmentCount == 0 && depthStencilAttachmentInfo == NULL)
|
||||
{
|
||||
|
@ -7989,6 +8048,38 @@ static void VULKAN_BeginRenderPass(
|
|||
return;
|
||||
}
|
||||
|
||||
/* The framebuffer cannot be larger than the smallest attachment. */
|
||||
|
||||
for (i = 0; i < colorAttachmentCount; i += 1)
|
||||
{
|
||||
texture = (VulkanTexture*) colorAttachmentInfos[i].texture;
|
||||
|
||||
if (texture->dimensions.width < framebufferWidth)
|
||||
{
|
||||
framebufferWidth = texture->dimensions.width;
|
||||
}
|
||||
|
||||
if (texture->dimensions.height < framebufferHeight)
|
||||
{
|
||||
framebufferHeight = texture->dimensions.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (depthStencilAttachmentInfo != NULL)
|
||||
{
|
||||
if (texture->dimensions.width < framebufferWidth)
|
||||
{
|
||||
framebufferWidth = texture->dimensions.width;
|
||||
}
|
||||
|
||||
if (texture->dimensions.height < framebufferHeight)
|
||||
{
|
||||
framebufferHeight = texture->dimensions.height;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch required render objects */
|
||||
|
||||
renderPass = VULKAN_INTERNAL_FetchRenderPass(
|
||||
renderer,
|
||||
colorAttachmentInfos,
|
||||
|
@ -8001,7 +8092,9 @@ static void VULKAN_BeginRenderPass(
|
|||
renderPass,
|
||||
colorAttachmentInfos,
|
||||
colorAttachmentCount,
|
||||
depthStencilAttachmentInfo
|
||||
depthStencilAttachmentInfo,
|
||||
framebufferWidth,
|
||||
framebufferHeight
|
||||
);
|
||||
|
||||
/* Layout transitions */
|
||||
|
@ -8103,6 +8196,30 @@ static void VULKAN_BeginRenderPass(
|
|||
(VulkanTexture*) colorAttachmentInfos[i].texture;
|
||||
}
|
||||
vulkanCommandBuffer->renderPassColorTargetCount = colorAttachmentCount;
|
||||
|
||||
/* Set sensible default viewport state */
|
||||
|
||||
defaultViewport.x = 0;
|
||||
defaultViewport.y = 0;
|
||||
defaultViewport.w = framebufferWidth;
|
||||
defaultViewport.h = framebufferHeight;
|
||||
defaultViewport.minDepth = 0;
|
||||
defaultViewport.maxDepth = 1;
|
||||
|
||||
VULKAN_INTERNAL_SetCurrentViewport(
|
||||
vulkanCommandBuffer,
|
||||
&defaultViewport
|
||||
);
|
||||
|
||||
defaultScissor.x = 0;
|
||||
defaultScissor.y = 0;
|
||||
defaultScissor.w = framebufferWidth;
|
||||
defaultScissor.h = framebufferHeight;
|
||||
|
||||
VULKAN_INTERNAL_SetCurrentScissor(
|
||||
vulkanCommandBuffer,
|
||||
&defaultScissor
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_EndRenderPass(
|
||||
|
@ -8175,6 +8292,12 @@ static void VULKAN_BindGraphicsPipeline(
|
|||
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
|
||||
VulkanGraphicsPipeline* pipeline = (VulkanGraphicsPipeline*) graphicsPipeline;
|
||||
|
||||
if (!vulkanCommandBuffer->renderPassInProgress)
|
||||
{
|
||||
Refresh_LogError("Illegal to bind a graphics pipeline outside of a render pass!");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vulkanCommandBuffer->vertexUniformBuffer != renderer->dummyVertexUniformBuffer &&
|
||||
vulkanCommandBuffer->vertexUniformBuffer != NULL
|
||||
) {
|
||||
|
@ -8239,6 +8362,20 @@ static void VULKAN_BindGraphicsPipeline(
|
|||
vulkanCommandBuffer->currentGraphicsPipeline = pipeline;
|
||||
|
||||
VULKAN_INTERNAL_TrackGraphicsPipeline(renderer, vulkanCommandBuffer, pipeline);
|
||||
|
||||
renderer->vkCmdSetViewport(
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
0,
|
||||
1,
|
||||
&vulkanCommandBuffer->currentViewport
|
||||
);
|
||||
|
||||
renderer->vkCmdSetScissor(
|
||||
vulkanCommandBuffer->commandBuffer,
|
||||
0,
|
||||
1,
|
||||
&vulkanCommandBuffer->currentScissor
|
||||
);
|
||||
}
|
||||
|
||||
static void VULKAN_BindVertexBuffers(
|
||||
|
|
Loading…
Reference in New Issue