diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 4fc444c9b..8ee42f6af 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1404,6 +1404,34 @@ namespace bgfx for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii) { viewRemap[m_viewRemap[ii] ] = ViewId(ii); + + View& view = s_ctx->m_view[ii]; + Rect fbRect(0, 0, uint16_t(m_resolution.width), uint16_t(m_resolution.height) ); + if (isValid(view.m_fbh) ) + { + const FrameBufferRef& fb = s_ctx->m_frameBufferRef[view.m_fbh.idx]; + const BackbufferRatio::Enum bbRatio = fb.m_window + ? BackbufferRatio::Count + : BackbufferRatio::Enum(s_ctx->m_textureRef[fb.un.m_th[0].idx].m_bbRatio) + ; + if (BackbufferRatio::Count != bbRatio) + { + getTextureSizeFromRatio(bbRatio, fbRect.m_width, fbRect.m_height); + } + else + { + fbRect.m_width = fb.m_width; + fbRect.m_height = fb.m_height; + } + } + + view.m_rect.intersect(fbRect); + BX_ASSERT(!view.m_rect.isZeroArea(), "View %d: view rect outside of framebuffer extent", ii); + + if (!view.m_scissor.isZero() ) + { + view.m_scissor.intersect(fbRect); + } } for (uint32_t ii = 0, num = m_numRenderItems; ii < num; ++ii) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 10f617e0f..eab239454 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -1865,6 +1865,11 @@ namespace bgfx return m_cubeMap; } + bool is3D() const + { + return 0 < m_depth; + } + String m_name; void* m_ptr; uint64_t m_flags; @@ -1885,6 +1890,8 @@ namespace bgfx struct FrameBufferRef { String m_name; + uint16_t m_width; + uint16_t m_height; union un { @@ -4518,10 +4525,51 @@ namespace bgfx uint8_t color = 0; uint8_t depth = 0; + const TextureRef& firstTexture = m_textureRef[_attachment[0].handle.idx]; + + const uint16_t firstAttachmentWidth = bx::max(firstTexture.m_width >> _attachment[0].mip, 1); + const uint16_t firstAttachmentHeight = bx::max(firstTexture.m_height >> _attachment[0].mip, 1); + for (uint32_t ii = 0; ii < _num; ++ii) { const TextureHandle texHandle = _attachment[ii].handle; + BGFX_CHECK_HANDLE("createFrameBuffer texture", m_textureHandle, texHandle); const TextureRef& tr = m_textureRef[texHandle.idx]; + + BX_ASSERT( + _attachment[ii].mip < tr.m_numMips + , "Invalid texture mip level (%d > %d)." + , _attachment[ii].mip + , tr.m_numMips - 1 + ); + const uint16_t numLayers = tr.m_numLayers * (tr.isCubeMap() ? 6 : 1) * (tr.is3D() ? tr.m_depth : 1); + BX_ASSERT( + (_attachment[ii].layer + _attachment[ii].numLayers) <= numLayers + , "Invalid texture layer range (layer %d + num %d > total %d)." + , _attachment[ii].layer + , _attachment[ii].numLayers + , numLayers + ); + + BX_ASSERT( + _attachment[0].numLayers == _attachment[ii].numLayers + , "Mismatch in attachment layer count (%d != %d)." + , _attachment[ii].numLayers + , _attachment[0].numLayers + ); + BX_ASSERT(firstTexture.m_bbRatio == tr.m_bbRatio, "Mismatch in texture back-buffer ratio."); + if (BackbufferRatio::Count == firstTexture.m_bbRatio) + { + const uint16_t width = bx::max(tr.m_width >> _attachment[ii].mip, 1); + const uint16_t height = bx::max(tr.m_height >> _attachment[ii].mip, 1); + BX_ASSERT( + width == firstAttachmentWidth && height == firstAttachmentHeight + , "Mismatch in texture size (%dx%d != %dx%d)." + , width, height + , firstAttachmentWidth, firstAttachmentHeight + ); + } + if (bimg::isDepth(bimg::TextureFormat::Enum(tr.m_format) ) ) { ++depth; @@ -4534,11 +4582,13 @@ namespace bgfx BX_ASSERT( 0 == (tr.m_flags & BGFX_TEXTURE_READ_BACK) , "Frame buffer texture cannot be read back texture. Attachment %d: has flags 0x%016" PRIx64 "." + , ii + , tr.m_flags ); BX_ASSERT( 0 != (tr.m_flags & BGFX_TEXTURE_RT_MASK) - , "Frame buffer texture is not create with one of `BGFX_TEXTURE_RT*` flags. Attachment %d: has flags 0x%016" PRIx64 "." + , "Frame buffer texture is not created with one of `BGFX_TEXTURE_RT*` flags. Attachment %d: has flags 0x%016" PRIx64 "." , ii , tr.m_flags ); @@ -4569,17 +4619,21 @@ namespace bgfx cmdbuf.write(false); cmdbuf.write(_num); + const TextureRef& firstTexture = m_textureRef[_attachment[0].handle.idx]; + const BackbufferRatio::Enum bbRatio = BackbufferRatio::Enum(firstTexture.m_bbRatio); + FrameBufferRef& ref = m_frameBufferRef[handle.idx]; + if (BackbufferRatio::Count == bbRatio) + { + ref.m_width = bx::max(firstTexture.m_width >> _attachment[0].mip, 1); + ref.m_height = bx::max(firstTexture.m_height >> _attachment[0].mip, 1); + } ref.m_window = false; bx::memSet(ref.un.m_th, 0xff, sizeof(ref.un.m_th) ); - BackbufferRatio::Enum bbRatio = BackbufferRatio::Enum(m_textureRef[_attachment[0].handle.idx].m_bbRatio); + for (uint32_t ii = 0; ii < _num; ++ii) { TextureHandle texHandle = _attachment[ii].handle; - BGFX_CHECK_HANDLE("createFrameBuffer texture", m_textureHandle, texHandle); - BX_ASSERT(bbRatio == m_textureRef[texHandle.idx].m_bbRatio, "Mismatch in texture back-buffer ratio."); - BX_UNUSED(bbRatio); - ref.un.m_th[ii] = texHandle; textureIncRef(texHandle); } @@ -4617,6 +4671,8 @@ namespace bgfx cmdbuf.write(_depthFormat); FrameBufferRef& ref = m_frameBufferRef[handle.idx]; + ref.m_width = _width; + ref.m_height = _height; ref.m_window = true; ref.un.m_nwh = _nwh; } diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 8e56ba489..7ec41055f 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -6496,56 +6496,58 @@ VK_DESTROY VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; VkRenderPass renderPass = s_renderVK->getRenderPass(_num, _attachment); - TextureVK& firstTexture = s_renderVK->m_textures[m_attachment[0].handle.idx]; ::VkImageView textureImageViews[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; m_depth.idx = bx::kInvalidHandle; m_num = 0; - uint16_t numLayers = m_attachment[0].numLayers; + uint8_t viewCount = 0; for (uint8_t ii = 0; ii < m_numTh; ++ii) { - const TextureVK& texture = s_renderVK->m_textures[m_attachment[ii].handle.idx]; + const Attachment& at = m_attachment[ii]; - BX_ASSERT(numLayers == m_attachment[ii].numLayers - , "Mismatching framebuffer attachment layer counts (%d != %d)." - , m_attachment[ii].numLayers - , numLayers - ); - - m_textureImageViews[ii] = texture.createView( - m_attachment[ii].layer - , m_attachment[ii].numLayers - , m_attachment[ii].mip - , 1 - ); - textureImageViews[ii] = m_textureImageViews[ii]; - - if (texture.m_aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) + if (isValid(at.handle) ) { - m_texture[m_num] = m_attachment[ii].handle; - m_num++; + const TextureVK& texture = s_renderVK->m_textures[at.handle.idx]; + m_textureImageViews[ii] = texture.createView( + at.layer + , at.numLayers + , at.mip + , 1 + ); + textureImageViews[viewCount++] = m_textureImageViews[ii]; + + if (texture.m_aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) + { + m_texture[m_num] = at.handle; + m_num++; + } + else if (texture.m_aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + { + m_depth = at.handle; + } } - else if (texture.m_aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + else { - m_depth = m_attachment[ii].handle; + m_textureImageViews[ii] = VK_NULL_HANDLE; } } - m_width = firstTexture.m_width >> m_attachment[0].mip; - m_height = firstTexture.m_height >> m_attachment[0].mip; + const TextureVK& firstTexture = s_renderVK->m_textures[m_attachment[0].handle.idx]; + m_width = bx::uint32_max(firstTexture.m_width >> m_attachment[0].mip, 1); + m_height = bx::uint32_max(firstTexture.m_height >> m_attachment[0].mip, 1); VkFramebufferCreateInfo fci; fci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fci.pNext = NULL; fci.flags = 0; fci.renderPass = renderPass; - fci.attachmentCount = m_numTh; + fci.attachmentCount = viewCount; fci.pAttachments = textureImageViews; fci.width = m_width; fci.height = m_height; - fci.layers = numLayers; + fci.layers = m_attachment[0].numLayers; VK_CHECK(vkCreateFramebuffer(device, &fci, allocatorCb, &m_framebuffer) );