diff --git a/changelog.md b/changelog.md index c8ee30d..a4a541f 100644 --- a/changelog.md +++ b/changelog.md @@ -7,4 +7,5 @@ Removed cvars: * r_finish * r_ignoreFastPath * r_maskMinidriver +* r_measureOverdraw * r_primitives (always use qglDrawElements) diff --git a/src/engine/renderer/tr_backend.c b/src/engine/renderer/tr_backend.c index 48bc336..4d18b41 100644 --- a/src/engine/renderer/tr_backend.c +++ b/src/engine/renderer/tr_backend.c @@ -426,7 +426,7 @@ void RB_BeginDrawingView (void) { // clear relevant buffers clearBits = GL_DEPTH_BUFFER_BIT; - bool clear_stencil = r_measureOverdraw->integer || r_shadows->integer == 2; + bool clear_stencil = (r_shadows->integer == 2); if ( clear_stencil ) { clearBits |= GL_STENCIL_BUFFER_BIT; @@ -956,24 +956,6 @@ const void *RB_SwapBuffers( const void *data ) { cmd = (const swapBuffersCommand_t *)data; - // we measure overdraw by reading back the stencil buffer and - // counting up the number of increments that have happened - if ( r_measureOverdraw->integer ) { - int i; - long sum = 0; - unsigned char *stencilReadback; - - stencilReadback = (unsigned char*) ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight ); - qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); - - for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { - sum += stencilReadback[i]; - } - - backEnd.pc.c_overDraw += sum; - ri.Hunk_FreeTempMemory( stencilReadback ); - } - GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); diff --git a/src/engine/renderer/tr_cmds.c b/src/engine/renderer/tr_cmds.c index 98b5e3b..12eef54 100644 --- a/src/engine/renderer/tr_cmds.c +++ b/src/engine/renderer/tr_cmds.c @@ -40,10 +40,10 @@ void R_PerformanceCounters( void ) { } if (r_speeds->integer == 1) { - ri.Printf (PRINT_ALL, "%i/%i shaders/surfs %i leafs %i verts %i/%i tris %.2f mtex %.2f dc\n", + ri.Printf (PRINT_ALL, "%i/%i shaders/surfs %i leafs %i verts %i/%i tris %.2f mtex\n", backEnd.pc.c_shaders, backEnd.pc.c_surfaces, tr.pc.c_leafs, backEnd.pc.c_vertexes, backEnd.pc.c_indexes/3, backEnd.pc.c_totalIndexes/3, - R_SumOfUsedImages()/(1000000.0f), backEnd.pc.c_overDraw / (float)(glConfig.vidWidth * glConfig.vidHeight) ); + R_SumOfUsedImages()/(1000000.0f)); } else if (r_speeds->integer == 2) { ri.Printf (PRINT_ALL, "(patch) %i sin %i sclip %i sout %i bin %i bclip %i bout\n", tr.pc.c_sphere_cull_patch_in, tr.pc.c_sphere_cull_patch_clip, tr.pc.c_sphere_cull_patch_out, @@ -312,42 +312,6 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) { tr.frameCount++; tr.frameSceneNum = 0; - // - // do overdraw measurement - // - if ( r_measureOverdraw->integer ) - { - if ( glConfig.stencilBits < 4 ) - { - ri.Printf( PRINT_ALL, "Warning: not enough stencil bits to measure overdraw: %d\n", glConfig.stencilBits ); - ri.Cvar_Set( "r_measureOverdraw", "0" ); - r_measureOverdraw->modified = qfalse; - } - else if ( r_shadows->integer == 2 ) - { - ri.Printf( PRINT_ALL, "Warning: stencil shadows and overdraw measurement are mutually exclusive\n" ); - ri.Cvar_Set( "r_measureOverdraw", "0" ); - r_measureOverdraw->modified = qfalse; - } - else - { - R_SyncRenderThread(); - qglEnable( GL_STENCIL_TEST ); - qglStencilFunc( GL_ALWAYS, 0U, ~0U ); - qglStencilOp( GL_KEEP, GL_INCR, GL_INCR ); - } - r_measureOverdraw->modified = qfalse; - } - else - { - // this is only reached if it was on and is now off - if ( r_measureOverdraw->modified ) { - R_SyncRenderThread(); - qglDisable( GL_STENCIL_TEST ); - } - r_measureOverdraw->modified = qfalse; - } - // // texturemode stuff // diff --git a/src/engine/renderer/tr_init.c b/src/engine/renderer/tr_init.c index e49247c..540ca12 100644 --- a/src/engine/renderer/tr_init.c +++ b/src/engine/renderer/tr_init.c @@ -56,7 +56,6 @@ cvar_t *r_showSmp; cvar_t *r_skipBackEnd; cvar_t *r_ignorehwgamma; -cvar_t *r_measureOverdraw; cvar_t *r_inGameVideo; cvar_t *r_fastsky; @@ -934,7 +933,6 @@ void R_Register( void ) r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT); r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT); - r_measureOverdraw = ri.Cvar_Get( "r_measureOverdraw", "0", CVAR_CHEAT ); r_lodscale = ri.Cvar_Get( "r_lodscale", "5", CVAR_CHEAT ); r_norefresh = ri.Cvar_Get ("r_norefresh", "0", CVAR_CHEAT); r_drawentities = ri.Cvar_Get ("r_drawentities", "1", CVAR_CHEAT ); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 78a1c07..9a0eb0d 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -810,7 +810,6 @@ typedef struct { typedef struct { int c_surfaces, c_shaders, c_vertexes, c_indexes, c_totalIndexes; - float c_overDraw; int c_dlightVertexes; int c_dlightIndexes; @@ -974,8 +973,6 @@ extern cvar_t *r_texturebits; // number of desired texture bits // 32 = use 32-bit textures // all else = error -extern cvar_t *r_measureOverdraw; // enables stencil buffer overdraw measurement - extern cvar_t *r_lodbias; // push/pull LOD transitions extern cvar_t *r_lodscale; diff --git a/src/engine/renderer/tr_shadows.c b/src/engine/renderer/tr_shadows.c index acdb7d2..8765805 100644 --- a/src/engine/renderer/tr_shadows.c +++ b/src/engine/renderer/tr_shadows.c @@ -279,9 +279,6 @@ void RB_ShadowFinish( void ) { qglColor3f( 0.6f, 0.6f, 0.6f ); GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO ); -// qglColor3f( 1, 0, 0 ); -// GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); - qglBegin( GL_QUADS ); qglVertex3f( -100, 100, -10 ); qglVertex3f( 100, 100, -10 ); diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index 82b00c1..d39e435 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -55,24 +55,31 @@ static uint32_t find_memory_type(VkPhysicalDevice physical_device, uint32_t memo return -1; } -static VkFormat find_format_with_features(VkPhysicalDevice physical_device, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) { - for (VkFormat format : candidates) { - VkFormatProperties properties; - vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties); - - if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features) - return format; - if (tiling == VK_IMAGE_TILING_OPTIMAL && (properties.optimalTilingFeatures & features) == features) - return format; - } - - ri.Error(ERR_FATAL, "Vulkan error: failed to find format with requested features"); - return VK_FORMAT_UNDEFINED; // never get here -} - static VkFormat find_depth_format(VkPhysicalDevice physical_device) { - return find_format_with_features(physical_device, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, - VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + if (r_stencilbits->integer > 0) { + VkFormat depth_stencil_formats[2] = {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT}; + for (int i = 0; i < 2; i++) { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(physical_device, depth_stencil_formats[i], &props); + if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0) { + glConfig.stencilBits = 8; + return depth_stencil_formats[i]; + } + } + ri.Error(ERR_FATAL, "find_depth_format: failed to find depth-stencil attachment format"); + } else { + VkFormat depth_formats[2] = {VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT}; + for (int i = 0; i < 2; i++) { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(physical_device, depth_formats[i], &props); + if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0) { + glConfig.stencilBits = 0; + return depth_formats[i]; + } + } + ri.Error(ERR_FATAL, "find_depth_format: failed to find depth attachment format"); + } + return VK_FORMAT_UNDEFINED; // neger get here } static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevice device, VkSurfaceKHR surface, VkSurfaceFormatKHR surface_format) { @@ -85,17 +92,14 @@ static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevic image_extent.height = std::min(surface_caps.maxImageExtent.height, std::max(surface_caps.minImageExtent.height, 480u)); } - // transfer destination usage is required by image clear operations + // VK_IMAGE_USAGE_TRANSFER_DST_BIT is required by image clear operations. if ((surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) == 0) ri.Error(ERR_FATAL, "create_swapchain: VK_IMAGE_USAGE_TRANSFER_DST_BIT is not supported by the swapchain"); + + // VK_IMAGE_USAGE_TRANSFER_SRC_BIT is required in order to take screenshots. if ((surface_caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) == 0) ri.Error(ERR_FATAL, "create_swapchain: VK_IMAGE_USAGE_TRANSFER_SRC_BIT is not supported by the swapchain"); - VkImageUsageFlags image_usage = - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_TRANSFER_DST_BIT | - VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - // determine present mode and swapchain image count uint32_t present_mode_count; VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &present_mode_count, nullptr)); @@ -129,7 +133,7 @@ static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevic desc.imageColorSpace = surface_format.colorSpace; desc.imageExtent = image_extent; desc.imageArrayLayers = 1; - desc.imageUsage = image_usage; + desc.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; desc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; desc.queueFamilyIndexCount = 0; desc.pQueueFamilyIndices = nullptr; @@ -156,12 +160,13 @@ static VkRenderPass create_render_pass(VkDevice device, VkFormat color_format, V attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + bool clear_stencil = (r_shadows->integer == 2); attachments[1].flags = 0; attachments[1].format = depth_format; attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[1].stencilLoadOp = clear_stencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; @@ -2107,7 +2112,7 @@ void vk_begin_frame() { VK_CHECK(vkBeginCommandBuffer(vk.command_buffer, &begin_info)); - // Ensure visibility of writes to geometry buffers. + // Ensure visibility of geometry buffers writes. record_buffer_memory_barrier(vk.command_buffer, vk.vertex_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);