Zero-initialize the context state and data
Using an initialization method or in-class initialization of each member
is bug-prone. Zero-initialization performed by the default constructor
guarantees repeatability.
Also don't skip drawing when the multisample mask is zero. Pipeline
stages prior to fragment processing may have side-effects.
Bug: b/155359026
Change-Id: Ibab131a41282fbdc4f5f84208776725eb3c786bd
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/45748
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Device/Context.cpp b/src/Device/Context.cpp
index da0e2c4..b5f36bf 100644
--- a/src/Device/Context.cpp
+++ b/src/Device/Context.cpp
@@ -24,11 +24,6 @@
namespace sw {
-Context::Context()
-{
- init();
-}
-
bool Context::isDrawPoint(bool polygonModeAware) const
{
switch(topology)
@@ -85,55 +80,6 @@
return false;
}
-void Context::init()
-{
- for(int i = 0; i < RENDERTARGETS; ++i)
- {
- renderTarget[i] = nullptr;
- }
-
- depthBuffer = nullptr;
- stencilBuffer = nullptr;
-
- stencilEnable = false;
- frontStencil = {};
- backStencil = {};
-
- robustBufferAccess = false;
-
- rasterizerDiscard = false;
-
- depthCompareMode = VK_COMPARE_OP_LESS;
- depthBoundsTestEnable = false;
- depthBufferEnable = false;
- depthWriteEnable = false;
-
- cullMode = VK_CULL_MODE_FRONT_BIT;
- frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
- provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
- lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
-
- depthBias = 0.0f;
- slopeDepthBias = 0.0f;
-
- for(int i = 0; i < RENDERTARGETS; i++)
- {
- colorWriteMask[i] = 0x0000000F;
- }
-
- pipelineLayout = nullptr;
-
- pixelShader = nullptr;
- vertexShader = nullptr;
-
- occlusionEnabled = false;
-
- lineWidth = 1.0f;
-
- sampleMask = 0xFFFFFFFF;
- alphaToCoverage = false;
-}
-
bool Context::depthWriteActive() const
{
if(!depthBufferActive()) return false;
diff --git a/src/Device/Context.hpp b/src/Device/Context.hpp
index cee48ad..a54ec2d 100644
--- a/src/Device/Context.hpp
+++ b/src/Device/Context.hpp
@@ -73,9 +73,7 @@
class Context
{
public:
- Context();
-
- void init();
+ Context() = default;
bool isDrawPoint(bool polygonModeAware) const;
bool isDrawLine(bool polygonModeAware) const;
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index 5908de8..22f10f8 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -187,13 +187,6 @@
auto id = nextDrawID++;
MARL_SCOPED_EVENT("draw %d", id);
- int ms = context->sampleCount;
-
- if(!context->multiSampleMask)
- {
- return;
- }
-
marl::Pool<sw::DrawCall>::Loan draw;
{
MARL_SCOPED_EVENT("drawCallPool.borrow()");
@@ -214,6 +207,7 @@
}
DrawCall::SetupFunction setupPrimitives = nullptr;
+ int ms = context->sampleCount;
unsigned int numPrimitivesPerBatch = MaxBatchSize / ms;
if(context->isDrawTriangle(false))
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index e0af236..ffcb353 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -291,6 +291,7 @@
context.polygonMode = rasterizationState->polygonMode;
context.depthBias = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasConstantFactor : 0.0f;
context.slopeDepthBias = (rasterizationState->depthBiasEnable != VK_FALSE) ? rasterizationState->depthBiasSlopeFactor : 0.0f;
+ context.lineWidth = rasterizationState->lineWidth;
const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(rasterizationState->pNext);
while(extensionCreateInfo)
@@ -321,6 +322,10 @@
extensionCreateInfo = extensionCreateInfo->pNext;
}
+ // The sample count affects the batch size, so it needs initialization even if rasterization is disabled.
+ // TODO(b/147812380): Eliminate the dependency between multisampling and batch size.
+ context.sampleCount = 1;
+
const VkPipelineMultisampleStateCreateInfo *multisampleState = pCreateInfo->pMultisampleState;
if(multisampleState)
{
@@ -356,6 +361,10 @@
{
context.sampleMask = multisampleState->pSampleMask[0];
}
+ else // "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
+ {
+ context.sampleMask = ~0;
+ }
context.alphaToCoverage = (multisampleState->alphaToCoverageEnable != VK_FALSE);
}