Correct framebuffer's attachments clearing when multiple views are rendered.
This commit is contained in:
parent
73e4db35d7
commit
11791b47a3
|
|
@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#pragma warning (disable: 4032)
|
||||
#pragma warning (disable: 4201)
|
||||
#pragma warning (disable: 4214)
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#include <gl/gl.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -422,21 +422,52 @@ void RB_BeginDrawingView (void) {
|
|||
// clear relevant buffers
|
||||
clearBits = GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
if ( r_measureOverdraw->integer || r_shadows->integer == 2 )
|
||||
bool clear_stencil = r_measureOverdraw->integer || r_shadows->integer == 2;
|
||||
if ( clear_stencil )
|
||||
{
|
||||
clearBits |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
if ( r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) )
|
||||
|
||||
#ifdef _DEBUG
|
||||
float color[4] = { 0.8f, 0.7f, 0.4f, 1.0f }; // FIXME: get color of sky
|
||||
#else
|
||||
float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; // FIXME: get color of sky
|
||||
#endif
|
||||
|
||||
bool clear_color = r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL );
|
||||
if ( clear_color )
|
||||
{
|
||||
clearBits |= GL_COLOR_BUFFER_BIT; // FIXME: only if sky shaders have been used
|
||||
#ifdef _DEBUG
|
||||
qglClearColor( 0.8f, 0.7f, 0.4f, 1.0f ); // FIXME: get color of sky
|
||||
#else
|
||||
qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // FIXME: get color of sky
|
||||
#endif
|
||||
qglClearColor(color[0], color[1], color[2], color[3]);
|
||||
}
|
||||
qglClear( clearBits );
|
||||
|
||||
// VULKAN
|
||||
if (glState.vk_dirty_attachments) {
|
||||
VkClearAttachment attachments[2];
|
||||
uint32_t attachment_count = clear_color ? 2 : 1;
|
||||
|
||||
attachments[0].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
attachments[0].clearValue.depthStencil.depth = 1.0f;
|
||||
|
||||
if (clear_stencil) {
|
||||
attachments[0].aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
attachments[0].clearValue.depthStencil.stencil = 0;
|
||||
}
|
||||
if (clear_color) {
|
||||
attachments[1].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
attachments[1].colorAttachment = 0;
|
||||
attachments[1].clearValue.color = { color[0], color[1], color[2], color[3] };
|
||||
}
|
||||
|
||||
VkClearRect clear_rect;
|
||||
clear_rect.rect = vk_get_viewport_rect();
|
||||
clear_rect.baseArrayLayer = 0;
|
||||
clear_rect.layerCount = 1;
|
||||
|
||||
vkCmdClearAttachments(vk_instance.command_buffer, attachment_count, attachments, 1, &clear_rect);
|
||||
}
|
||||
|
||||
if ( ( backEnd.refdef.rdflags & RDF_HYPERSPACE ) )
|
||||
{
|
||||
RB_Hyperspace();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/qfiles.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
#include "tr_public.h"
|
||||
|
||||
#include "qgl.h"
|
||||
|
||||
// VULKAN
|
||||
|
|
@ -808,6 +809,11 @@ typedef struct {
|
|||
unsigned long glStateBits;
|
||||
|
||||
// VULKAN
|
||||
|
||||
// This flag is used to decide whether framebuffer's attachments should be cleared with vmCmdClearAttachment (vk_dirty_attachments == true),
|
||||
// or they have just been cleared by render pass instance clear op (vk_dirty_attachments == false).
|
||||
bool vk_dirty_attachments;
|
||||
|
||||
image_t* vk_current_images[2];
|
||||
} glstate_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#include "vk.h"
|
||||
#include "tr_local.h"
|
||||
|
||||
#include "vk_utils.h"
|
||||
#include "vk_allocator.h"
|
||||
#include "vk_resource_manager.h"
|
||||
#include "tr_local.h"
|
||||
|
||||
#include "vk_demo.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
|
@ -860,3 +861,31 @@ void vk_destroy_resources() {
|
|||
vkDeviceWaitIdle(vk_instance.device);
|
||||
vk_destroy_pipelines();
|
||||
}
|
||||
|
||||
VkRect2D vk_get_viewport_rect() {
|
||||
VkRect2D r;
|
||||
|
||||
if (backEnd.projection2D) {
|
||||
r.offset.x = 0.0f;
|
||||
r.offset.y = 0.0f;
|
||||
r.extent.width = glConfig.vidWidth;
|
||||
r.extent.height = glConfig.vidHeight;
|
||||
} else {
|
||||
r.offset.x = backEnd.viewParms.viewportX;
|
||||
if (r.offset.x < 0)
|
||||
r.offset.x = 0;
|
||||
|
||||
r.offset.y = glConfig.vidHeight - (backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight);
|
||||
if (r.offset.y < 0)
|
||||
r.offset.y = 0;
|
||||
|
||||
r.extent.width = backEnd.viewParms.viewportWidth;
|
||||
if (r.offset.x + r.extent.width > glConfig.vidWidth)
|
||||
r.extent.width = glConfig.vidWidth - r.offset.x;
|
||||
|
||||
r.extent.height = backEnd.viewParms.viewportHeight;
|
||||
if (r.offset.y + r.extent.height > glConfig.vidHeight)
|
||||
r.extent.height = glConfig.vidHeight - r.offset.y;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ bool vk_initialize(HWND hwnd);
|
|||
void vk_deinitialize();
|
||||
void vk_destroy_resources();
|
||||
|
||||
VkRect2D vk_get_viewport_rect();
|
||||
|
||||
struct Vk_Staging_Buffer {
|
||||
VkBuffer handle = VK_NULL_HANDLE;
|
||||
VkDeviceMemory memory = VK_NULL_HANDLE; // memory associated with a buffer
|
||||
|
|
|
|||
|
|
@ -421,6 +421,8 @@ void Vulkan_Demo::begin_frame() {
|
|||
tess_vertex_buffer_offset = 0;
|
||||
tess_index_buffer_offset = 0;
|
||||
tess_ubo_offset = 0;
|
||||
|
||||
glState.vk_dirty_attachments = false;
|
||||
}
|
||||
|
||||
void Vulkan_Demo::end_frame() {
|
||||
|
|
@ -469,36 +471,20 @@ void Vulkan_Demo::render_tess(const shaderStage_t* stage) {
|
|||
vkCmdBindDescriptorSets(vk_instance.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &set, 1, &tess_ubo_offset);
|
||||
tess_ubo_offset += tess_ubo_offset_step;
|
||||
|
||||
VkViewport viewport;
|
||||
VkRect2D scissor;
|
||||
|
||||
if (backEnd.projection2D) {
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = (float) glConfig.vidWidth;
|
||||
viewport.height = (float)glConfig.vidHeight;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
scissor.offset = {0, 0};
|
||||
scissor.extent = {(uint32_t)glConfig.vidWidth, (uint32_t)glConfig.vidHeight};
|
||||
} else {
|
||||
viewport.x = backEnd.viewParms.viewportX;
|
||||
viewport.y = (float)(glConfig.vidHeight - (backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight));
|
||||
viewport.width = (float) backEnd.viewParms.viewportWidth;
|
||||
viewport.height = (float)backEnd.viewParms.viewportHeight;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
scissor.offset = {backEnd.viewParms.viewportX, (glConfig.vidHeight - (backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight))};
|
||||
if (scissor.offset.y < 0) scissor.offset.y = 0; // receive such data from backEnd, so just adjust to valid value to prevent vulkan warnings
|
||||
scissor.extent = {(uint32_t)backEnd.viewParms.viewportWidth, (uint32_t)backEnd.viewParms.viewportHeight};
|
||||
}
|
||||
|
||||
vkCmdBindPipeline(vk_instance.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stage->vk_pipeline);
|
||||
|
||||
VkRect2D r = vk_get_viewport_rect();
|
||||
vkCmdSetScissor(vk_instance.command_buffer, 0, 1, &r);
|
||||
|
||||
VkViewport viewport;
|
||||
viewport.x = (float)r.offset.x;
|
||||
viewport.y = (float)r.offset.y;
|
||||
viewport.width = (float)r.extent.width;
|
||||
viewport.height = (float)r.extent.height;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
vkCmdSetViewport(vk_instance.command_buffer, 0, 1, &viewport);
|
||||
vkCmdSetScissor(vk_instance.command_buffer, 0, 1, &scissor);
|
||||
|
||||
if (tess.shader->polygonOffset) {
|
||||
vkCmdSetDepthBias(vk_instance.command_buffer, r_offsetUnits->value, 0.0f, r_offsetFactor->value);
|
||||
}
|
||||
|
|
@ -506,6 +492,8 @@ void Vulkan_Demo::render_tess(const shaderStage_t* stage) {
|
|||
vkCmdDrawIndexed(vk_instance.command_buffer, tess.numIndexes, 1, 0, 0, 0);
|
||||
tess_vertex_buffer_offset += tess.numVertexes * sizeof(Vk_Vertex);
|
||||
tess_index_buffer_offset += tess.numIndexes * sizeof(uint32_t);
|
||||
|
||||
glState.vk_dirty_attachments = true;
|
||||
}
|
||||
|
||||
void Vulkan_Demo::render_tess_multi(const shaderStage_t* stage) {
|
||||
|
|
@ -557,36 +545,20 @@ void Vulkan_Demo::render_tess_multi(const shaderStage_t* stage) {
|
|||
vkCmdBindDescriptorSets(vk_instance.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &set, 1, &tess_ubo_offset);
|
||||
tess_ubo_offset += tess_ubo_offset_step;
|
||||
|
||||
VkViewport viewport;
|
||||
VkRect2D scissor;
|
||||
|
||||
if (backEnd.projection2D) {
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = (float) glConfig.vidWidth;
|
||||
viewport.height = (float)glConfig.vidHeight;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
scissor.offset = {0, 0};
|
||||
scissor.extent = {(uint32_t)glConfig.vidWidth, (uint32_t)glConfig.vidHeight};
|
||||
} else {
|
||||
viewport.x = backEnd.viewParms.viewportX;
|
||||
viewport.y = (float)(glConfig.vidHeight - (backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight));
|
||||
viewport.width = (float) backEnd.viewParms.viewportWidth;
|
||||
viewport.height = (float)backEnd.viewParms.viewportHeight;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
scissor.offset = {backEnd.viewParms.viewportX, (glConfig.vidHeight - (backEnd.viewParms.viewportY + backEnd.viewParms.viewportHeight))};
|
||||
if (scissor.offset.y < 0) scissor.offset.y = 0; // receive such data from backEnd, so just adjust to valid value to prevent vulkan warnings
|
||||
scissor.extent = {(uint32_t)backEnd.viewParms.viewportWidth, (uint32_t)backEnd.viewParms.viewportHeight};
|
||||
}
|
||||
|
||||
vkCmdBindPipeline(vk_instance.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stage->vk_pipeline);
|
||||
|
||||
VkRect2D r = vk_get_viewport_rect();
|
||||
vkCmdSetScissor(vk_instance.command_buffer, 0, 1, &r);
|
||||
|
||||
VkViewport viewport;
|
||||
viewport.x = (float)r.offset.x;
|
||||
viewport.y = (float)r.offset.y;
|
||||
viewport.width = (float)r.extent.width;
|
||||
viewport.height = (float)r.extent.height;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
vkCmdSetViewport(vk_instance.command_buffer, 0, 1, &viewport);
|
||||
vkCmdSetScissor(vk_instance.command_buffer, 0, 1, &scissor);
|
||||
|
||||
if (tess.shader->polygonOffset) {
|
||||
vkCmdSetDepthBias(vk_instance.command_buffer, r_offsetUnits->value, 0.0f, r_offsetFactor->value);
|
||||
}
|
||||
|
|
@ -594,4 +566,6 @@ void Vulkan_Demo::render_tess_multi(const shaderStage_t* stage) {
|
|||
vkCmdDrawIndexed(vk_instance.command_buffer, tess.numIndexes, 1, 0, 0, 0);
|
||||
tess_vertex_buffer_offset += tess.numVertexes * sizeof(Vk_Vertex2);
|
||||
tess_index_buffer_offset += tess.numIndexes * sizeof(uint32_t);
|
||||
|
||||
glState.vk_dirty_attachments = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user