diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 9e922901c..d42bde92c 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2290,8 +2290,11 @@ namespace dxvk { const D3D11_RECT* pRects) { m_state.rs.numScissors = NumRects; - for (uint32_t i = 0; i < NumRects; i++) - m_state.rs.scissors.at(i) = pRects[i]; + for (uint32_t i = 0; i < NumRects; i++) { + if (pRects[i].bottom >= pRects[i].top + && pRects[i].right >= pRects[i].left) + m_state.rs.scissors.at(i) = pRects[i]; + } if (m_state.rs.state != nullptr) { D3D11_RASTERIZER_DESC rsDesc; @@ -2554,17 +2557,22 @@ namespace dxvk { } for (uint32_t i = 0; i < m_state.rs.numViewports; i++) { - // TODO D3D11 docs aren't clear about what should happen - // when there are undefined scissor rects for a viewport. - // Figure out what it does on Windows. if (enableScissorTest && (i < m_state.rs.numScissors)) { - const D3D11_RECT& sr = m_state.rs.scissors.at(i); + D3D11_RECT sr = m_state.rs.scissors.at(i); - scissors.at(i) = VkRect2D { - VkOffset2D { sr.left, sr.top }, - VkExtent2D { - static_cast(sr.right - sr.left), - static_cast(sr.bottom - sr.top) } }; + VkOffset2D srPosA; + srPosA.x = std::max(0, sr.left); + srPosA.y = std::max(0, sr.top); + + VkOffset2D srPosB; + srPosB.x = std::max(srPosA.x, sr.right); + srPosB.y = std::max(srPosA.y, sr.bottom); + + VkExtent2D srSize; + srSize.width = uint32_t(srPosB.x - srPosA.x); + srSize.height = uint32_t(srPosB.y - srPosA.y); + + scissors.at(i) = VkRect2D { srPosA, srSize }; } else { scissors.at(i) = VkRect2D { VkOffset2D { 0, 0 },