1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2020 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #include "Context.hpp"
16*03ce13f7SAndroid Build Coastguard Worker
17*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkBuffer.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkDevice.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkImageView.hpp"
20*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkPipeline.hpp"
21*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkRenderPass.hpp"
22*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkStringify.hpp"
23*03ce13f7SAndroid Build Coastguard Worker
24*03ce13f7SAndroid Build Coastguard Worker namespace {
25*03ce13f7SAndroid Build Coastguard Worker
ComputePrimitiveCount(VkPrimitiveTopology topology,uint32_t vertexCount)26*03ce13f7SAndroid Build Coastguard Worker uint32_t ComputePrimitiveCount(VkPrimitiveTopology topology, uint32_t vertexCount)
27*03ce13f7SAndroid Build Coastguard Worker {
28*03ce13f7SAndroid Build Coastguard Worker switch(topology)
29*03ce13f7SAndroid Build Coastguard Worker {
30*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
31*03ce13f7SAndroid Build Coastguard Worker return vertexCount;
32*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
33*03ce13f7SAndroid Build Coastguard Worker return vertexCount / 2;
34*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
35*03ce13f7SAndroid Build Coastguard Worker return std::max<uint32_t>(vertexCount, 1) - 1;
36*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
37*03ce13f7SAndroid Build Coastguard Worker return vertexCount / 3;
38*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
39*03ce13f7SAndroid Build Coastguard Worker return std::max<uint32_t>(vertexCount, 2) - 2;
40*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
41*03ce13f7SAndroid Build Coastguard Worker return std::max<uint32_t>(vertexCount, 2) - 2;
42*03ce13f7SAndroid Build Coastguard Worker default:
43*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("VkPrimitiveTopology %d", int(topology));
44*03ce13f7SAndroid Build Coastguard Worker }
45*03ce13f7SAndroid Build Coastguard Worker
46*03ce13f7SAndroid Build Coastguard Worker return 0;
47*03ce13f7SAndroid Build Coastguard Worker }
48*03ce13f7SAndroid Build Coastguard Worker
49*03ce13f7SAndroid Build Coastguard Worker template<typename T>
ProcessPrimitiveRestart(T * indexBuffer,VkPrimitiveTopology topology,uint32_t count,std::vector<std::pair<uint32_t,void * >> * indexBuffers)50*03ce13f7SAndroid Build Coastguard Worker void ProcessPrimitiveRestart(T *indexBuffer,
51*03ce13f7SAndroid Build Coastguard Worker VkPrimitiveTopology topology,
52*03ce13f7SAndroid Build Coastguard Worker uint32_t count,
53*03ce13f7SAndroid Build Coastguard Worker std::vector<std::pair<uint32_t, void *>> *indexBuffers)
54*03ce13f7SAndroid Build Coastguard Worker {
55*03ce13f7SAndroid Build Coastguard Worker static const T RestartIndex = static_cast<T>(-1);
56*03ce13f7SAndroid Build Coastguard Worker T *indexBufferStart = indexBuffer;
57*03ce13f7SAndroid Build Coastguard Worker uint32_t vertexCount = 0;
58*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < count; i++)
59*03ce13f7SAndroid Build Coastguard Worker {
60*03ce13f7SAndroid Build Coastguard Worker if(indexBuffer[i] == RestartIndex)
61*03ce13f7SAndroid Build Coastguard Worker {
62*03ce13f7SAndroid Build Coastguard Worker // Record previous segment
63*03ce13f7SAndroid Build Coastguard Worker if(vertexCount > 0)
64*03ce13f7SAndroid Build Coastguard Worker {
65*03ce13f7SAndroid Build Coastguard Worker uint32_t primitiveCount = ComputePrimitiveCount(topology, vertexCount);
66*03ce13f7SAndroid Build Coastguard Worker if(primitiveCount > 0)
67*03ce13f7SAndroid Build Coastguard Worker {
68*03ce13f7SAndroid Build Coastguard Worker indexBuffers->push_back({ primitiveCount, indexBufferStart });
69*03ce13f7SAndroid Build Coastguard Worker }
70*03ce13f7SAndroid Build Coastguard Worker }
71*03ce13f7SAndroid Build Coastguard Worker vertexCount = 0;
72*03ce13f7SAndroid Build Coastguard Worker }
73*03ce13f7SAndroid Build Coastguard Worker else
74*03ce13f7SAndroid Build Coastguard Worker {
75*03ce13f7SAndroid Build Coastguard Worker if(vertexCount == 0)
76*03ce13f7SAndroid Build Coastguard Worker {
77*03ce13f7SAndroid Build Coastguard Worker indexBufferStart = indexBuffer + i;
78*03ce13f7SAndroid Build Coastguard Worker }
79*03ce13f7SAndroid Build Coastguard Worker vertexCount++;
80*03ce13f7SAndroid Build Coastguard Worker }
81*03ce13f7SAndroid Build Coastguard Worker }
82*03ce13f7SAndroid Build Coastguard Worker
83*03ce13f7SAndroid Build Coastguard Worker // Record last segment
84*03ce13f7SAndroid Build Coastguard Worker if(vertexCount > 0)
85*03ce13f7SAndroid Build Coastguard Worker {
86*03ce13f7SAndroid Build Coastguard Worker uint32_t primitiveCount = ComputePrimitiveCount(topology, vertexCount);
87*03ce13f7SAndroid Build Coastguard Worker if(primitiveCount > 0)
88*03ce13f7SAndroid Build Coastguard Worker {
89*03ce13f7SAndroid Build Coastguard Worker indexBuffers->push_back({ primitiveCount, indexBufferStart });
90*03ce13f7SAndroid Build Coastguard Worker }
91*03ce13f7SAndroid Build Coastguard Worker }
92*03ce13f7SAndroid Build Coastguard Worker }
93*03ce13f7SAndroid Build Coastguard Worker
ParseInputsDynamicStateFlags(const VkPipelineDynamicStateCreateInfo * dynamicStateCreateInfo)94*03ce13f7SAndroid Build Coastguard Worker vk::InputsDynamicStateFlags ParseInputsDynamicStateFlags(const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo)
95*03ce13f7SAndroid Build Coastguard Worker {
96*03ce13f7SAndroid Build Coastguard Worker vk::InputsDynamicStateFlags dynamicStateFlags = {};
97*03ce13f7SAndroid Build Coastguard Worker
98*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateCreateInfo == nullptr)
99*03ce13f7SAndroid Build Coastguard Worker {
100*03ce13f7SAndroid Build Coastguard Worker return dynamicStateFlags;
101*03ce13f7SAndroid Build Coastguard Worker }
102*03ce13f7SAndroid Build Coastguard Worker
103*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < dynamicStateCreateInfo->dynamicStateCount; i++)
104*03ce13f7SAndroid Build Coastguard Worker {
105*03ce13f7SAndroid Build Coastguard Worker VkDynamicState dynamicState = dynamicStateCreateInfo->pDynamicStates[i];
106*03ce13f7SAndroid Build Coastguard Worker switch(dynamicState)
107*03ce13f7SAndroid Build Coastguard Worker {
108*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE:
109*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.dynamicVertexInputBindingStride = true;
110*03ce13f7SAndroid Build Coastguard Worker break;
111*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
112*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.dynamicVertexInput = true;
113*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.dynamicVertexInputBindingStride = true;
114*03ce13f7SAndroid Build Coastguard Worker break;
115*03ce13f7SAndroid Build Coastguard Worker
116*03ce13f7SAndroid Build Coastguard Worker default:
117*03ce13f7SAndroid Build Coastguard Worker // The rest of the dynamic state is handled by ParseDynamicStateFlags.
118*03ce13f7SAndroid Build Coastguard Worker break;
119*03ce13f7SAndroid Build Coastguard Worker }
120*03ce13f7SAndroid Build Coastguard Worker }
121*03ce13f7SAndroid Build Coastguard Worker
122*03ce13f7SAndroid Build Coastguard Worker return dynamicStateFlags;
123*03ce13f7SAndroid Build Coastguard Worker }
124*03ce13f7SAndroid Build Coastguard Worker
ParseDynamicStateFlags(const VkPipelineDynamicStateCreateInfo * dynamicStateCreateInfo)125*03ce13f7SAndroid Build Coastguard Worker vk::DynamicStateFlags ParseDynamicStateFlags(const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo)
126*03ce13f7SAndroid Build Coastguard Worker {
127*03ce13f7SAndroid Build Coastguard Worker vk::DynamicStateFlags dynamicStateFlags = {};
128*03ce13f7SAndroid Build Coastguard Worker
129*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateCreateInfo == nullptr)
130*03ce13f7SAndroid Build Coastguard Worker {
131*03ce13f7SAndroid Build Coastguard Worker return dynamicStateFlags;
132*03ce13f7SAndroid Build Coastguard Worker }
133*03ce13f7SAndroid Build Coastguard Worker
134*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateCreateInfo->flags != 0)
135*03ce13f7SAndroid Build Coastguard Worker {
136*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.3: "flags is reserved for future use." "flags must be 0"
137*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("dynamicStateCreateInfo->flags 0x%08X", int(dynamicStateCreateInfo->flags));
138*03ce13f7SAndroid Build Coastguard Worker }
139*03ce13f7SAndroid Build Coastguard Worker
140*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < dynamicStateCreateInfo->dynamicStateCount; i++)
141*03ce13f7SAndroid Build Coastguard Worker {
142*03ce13f7SAndroid Build Coastguard Worker VkDynamicState dynamicState = dynamicStateCreateInfo->pDynamicStates[i];
143*03ce13f7SAndroid Build Coastguard Worker switch(dynamicState)
144*03ce13f7SAndroid Build Coastguard Worker {
145*03ce13f7SAndroid Build Coastguard Worker // Vertex input interface:
146*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE:
147*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.vertexInputInterface.dynamicPrimitiveRestartEnable = true;
148*03ce13f7SAndroid Build Coastguard Worker break;
149*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY:
150*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.vertexInputInterface.dynamicPrimitiveTopology = true;
151*03ce13f7SAndroid Build Coastguard Worker break;
152*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE:
153*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
154*03ce13f7SAndroid Build Coastguard Worker // Handled by ParseInputsDynamicStateFlags
155*03ce13f7SAndroid Build Coastguard Worker break;
156*03ce13f7SAndroid Build Coastguard Worker
157*03ce13f7SAndroid Build Coastguard Worker // Pre-rasterization:
158*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_LINE_WIDTH:
159*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicLineWidth = true;
160*03ce13f7SAndroid Build Coastguard Worker break;
161*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_DEPTH_BIAS:
162*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicDepthBias = true;
163*03ce13f7SAndroid Build Coastguard Worker break;
164*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE:
165*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicDepthBiasEnable = true;
166*03ce13f7SAndroid Build Coastguard Worker break;
167*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_CULL_MODE:
168*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicCullMode = true;
169*03ce13f7SAndroid Build Coastguard Worker break;
170*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_FRONT_FACE:
171*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicFrontFace = true;
172*03ce13f7SAndroid Build Coastguard Worker break;
173*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VIEWPORT:
174*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicViewport = true;
175*03ce13f7SAndroid Build Coastguard Worker break;
176*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_SCISSOR:
177*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicScissor = true;
178*03ce13f7SAndroid Build Coastguard Worker break;
179*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT:
180*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicViewportWithCount = true;
181*03ce13f7SAndroid Build Coastguard Worker break;
182*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT:
183*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicScissorWithCount = true;
184*03ce13f7SAndroid Build Coastguard Worker break;
185*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE:
186*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.preRasterization.dynamicRasterizerDiscardEnable = true;
187*03ce13f7SAndroid Build Coastguard Worker break;
188*03ce13f7SAndroid Build Coastguard Worker
189*03ce13f7SAndroid Build Coastguard Worker // Fragment:
190*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE:
191*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicDepthTestEnable = true;
192*03ce13f7SAndroid Build Coastguard Worker break;
193*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE:
194*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicDepthWriteEnable = true;
195*03ce13f7SAndroid Build Coastguard Worker break;
196*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE:
197*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicDepthBoundsTestEnable = true;
198*03ce13f7SAndroid Build Coastguard Worker break;
199*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
200*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicDepthBounds = true;
201*03ce13f7SAndroid Build Coastguard Worker break;
202*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP:
203*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicDepthCompareOp = true;
204*03ce13f7SAndroid Build Coastguard Worker break;
205*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE:
206*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicStencilTestEnable = true;
207*03ce13f7SAndroid Build Coastguard Worker break;
208*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_STENCIL_OP:
209*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicStencilOp = true;
210*03ce13f7SAndroid Build Coastguard Worker break;
211*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
212*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicStencilCompareMask = true;
213*03ce13f7SAndroid Build Coastguard Worker break;
214*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
215*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicStencilWriteMask = true;
216*03ce13f7SAndroid Build Coastguard Worker break;
217*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
218*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragment.dynamicStencilReference = true;
219*03ce13f7SAndroid Build Coastguard Worker break;
220*03ce13f7SAndroid Build Coastguard Worker
221*03ce13f7SAndroid Build Coastguard Worker // Fragment output interface:
222*03ce13f7SAndroid Build Coastguard Worker case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
223*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags.fragmentOutputInterface.dynamicBlendConstants = true;
224*03ce13f7SAndroid Build Coastguard Worker break;
225*03ce13f7SAndroid Build Coastguard Worker
226*03ce13f7SAndroid Build Coastguard Worker default:
227*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("VkDynamicState %d", int(dynamicState));
228*03ce13f7SAndroid Build Coastguard Worker }
229*03ce13f7SAndroid Build Coastguard Worker }
230*03ce13f7SAndroid Build Coastguard Worker
231*03ce13f7SAndroid Build Coastguard Worker return dynamicStateFlags;
232*03ce13f7SAndroid Build Coastguard Worker }
233*03ce13f7SAndroid Build Coastguard Worker } // namespace
234*03ce13f7SAndroid Build Coastguard Worker
235*03ce13f7SAndroid Build Coastguard Worker namespace vk {
236*03ce13f7SAndroid Build Coastguard Worker
bytesPerIndex() const237*03ce13f7SAndroid Build Coastguard Worker uint32_t IndexBuffer::bytesPerIndex() const
238*03ce13f7SAndroid Build Coastguard Worker {
239*03ce13f7SAndroid Build Coastguard Worker return indexType == VK_INDEX_TYPE_UINT16 ? 2u : 4u;
240*03ce13f7SAndroid Build Coastguard Worker }
241*03ce13f7SAndroid Build Coastguard Worker
setIndexBufferBinding(const VertexInputBinding & indexBufferBinding,VkIndexType type)242*03ce13f7SAndroid Build Coastguard Worker void IndexBuffer::setIndexBufferBinding(const VertexInputBinding &indexBufferBinding, VkIndexType type)
243*03ce13f7SAndroid Build Coastguard Worker {
244*03ce13f7SAndroid Build Coastguard Worker binding = indexBufferBinding;
245*03ce13f7SAndroid Build Coastguard Worker indexType = type;
246*03ce13f7SAndroid Build Coastguard Worker }
247*03ce13f7SAndroid Build Coastguard Worker
getIndexBuffers(VkPrimitiveTopology topology,uint32_t count,uint32_t first,bool indexed,bool hasPrimitiveRestartEnable,std::vector<std::pair<uint32_t,void * >> * indexBuffers) const248*03ce13f7SAndroid Build Coastguard Worker void IndexBuffer::getIndexBuffers(VkPrimitiveTopology topology, uint32_t count, uint32_t first, bool indexed, bool hasPrimitiveRestartEnable, std::vector<std::pair<uint32_t, void *>> *indexBuffers) const
249*03ce13f7SAndroid Build Coastguard Worker {
250*03ce13f7SAndroid Build Coastguard Worker if(indexed)
251*03ce13f7SAndroid Build Coastguard Worker {
252*03ce13f7SAndroid Build Coastguard Worker const VkDeviceSize bufferSize = binding.buffer->getSize();
253*03ce13f7SAndroid Build Coastguard Worker if(binding.offset >= bufferSize)
254*03ce13f7SAndroid Build Coastguard Worker {
255*03ce13f7SAndroid Build Coastguard Worker return; // Nothing to draw
256*03ce13f7SAndroid Build Coastguard Worker }
257*03ce13f7SAndroid Build Coastguard Worker
258*03ce13f7SAndroid Build Coastguard Worker const VkDeviceSize maxIndices = (bufferSize - binding.offset) / bytesPerIndex();
259*03ce13f7SAndroid Build Coastguard Worker if(first > maxIndices)
260*03ce13f7SAndroid Build Coastguard Worker {
261*03ce13f7SAndroid Build Coastguard Worker return; // Nothing to draw
262*03ce13f7SAndroid Build Coastguard Worker }
263*03ce13f7SAndroid Build Coastguard Worker
264*03ce13f7SAndroid Build Coastguard Worker void *indexBuffer = binding.buffer->getOffsetPointer(binding.offset + first * bytesPerIndex());
265*03ce13f7SAndroid Build Coastguard Worker if(hasPrimitiveRestartEnable)
266*03ce13f7SAndroid Build Coastguard Worker {
267*03ce13f7SAndroid Build Coastguard Worker switch(indexType)
268*03ce13f7SAndroid Build Coastguard Worker {
269*03ce13f7SAndroid Build Coastguard Worker case VK_INDEX_TYPE_UINT16:
270*03ce13f7SAndroid Build Coastguard Worker ProcessPrimitiveRestart(static_cast<uint16_t *>(indexBuffer), topology, count, indexBuffers);
271*03ce13f7SAndroid Build Coastguard Worker break;
272*03ce13f7SAndroid Build Coastguard Worker case VK_INDEX_TYPE_UINT32:
273*03ce13f7SAndroid Build Coastguard Worker ProcessPrimitiveRestart(static_cast<uint32_t *>(indexBuffer), topology, count, indexBuffers);
274*03ce13f7SAndroid Build Coastguard Worker break;
275*03ce13f7SAndroid Build Coastguard Worker default:
276*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("VkIndexType %d", int(indexType));
277*03ce13f7SAndroid Build Coastguard Worker }
278*03ce13f7SAndroid Build Coastguard Worker }
279*03ce13f7SAndroid Build Coastguard Worker else
280*03ce13f7SAndroid Build Coastguard Worker {
281*03ce13f7SAndroid Build Coastguard Worker indexBuffers->push_back({ ComputePrimitiveCount(topology, count), indexBuffer });
282*03ce13f7SAndroid Build Coastguard Worker }
283*03ce13f7SAndroid Build Coastguard Worker }
284*03ce13f7SAndroid Build Coastguard Worker else
285*03ce13f7SAndroid Build Coastguard Worker {
286*03ce13f7SAndroid Build Coastguard Worker indexBuffers->push_back({ ComputePrimitiveCount(topology, count), nullptr });
287*03ce13f7SAndroid Build Coastguard Worker }
288*03ce13f7SAndroid Build Coastguard Worker }
289*03ce13f7SAndroid Build Coastguard Worker
colorFormat(int location) const290*03ce13f7SAndroid Build Coastguard Worker VkFormat Attachments::colorFormat(int location) const
291*03ce13f7SAndroid Build Coastguard Worker {
292*03ce13f7SAndroid Build Coastguard Worker ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));
293*03ce13f7SAndroid Build Coastguard Worker
294*03ce13f7SAndroid Build Coastguard Worker if(colorBuffer[location])
295*03ce13f7SAndroid Build Coastguard Worker {
296*03ce13f7SAndroid Build Coastguard Worker return colorBuffer[location]->getFormat();
297*03ce13f7SAndroid Build Coastguard Worker }
298*03ce13f7SAndroid Build Coastguard Worker else
299*03ce13f7SAndroid Build Coastguard Worker {
300*03ce13f7SAndroid Build Coastguard Worker return VK_FORMAT_UNDEFINED;
301*03ce13f7SAndroid Build Coastguard Worker }
302*03ce13f7SAndroid Build Coastguard Worker }
303*03ce13f7SAndroid Build Coastguard Worker
depthFormat() const304*03ce13f7SAndroid Build Coastguard Worker VkFormat Attachments::depthFormat() const
305*03ce13f7SAndroid Build Coastguard Worker {
306*03ce13f7SAndroid Build Coastguard Worker if(depthBuffer)
307*03ce13f7SAndroid Build Coastguard Worker {
308*03ce13f7SAndroid Build Coastguard Worker return depthBuffer->getFormat();
309*03ce13f7SAndroid Build Coastguard Worker }
310*03ce13f7SAndroid Build Coastguard Worker else
311*03ce13f7SAndroid Build Coastguard Worker {
312*03ce13f7SAndroid Build Coastguard Worker return VK_FORMAT_UNDEFINED;
313*03ce13f7SAndroid Build Coastguard Worker }
314*03ce13f7SAndroid Build Coastguard Worker }
315*03ce13f7SAndroid Build Coastguard Worker
depthStencilFormat() const316*03ce13f7SAndroid Build Coastguard Worker VkFormat Attachments::depthStencilFormat() const
317*03ce13f7SAndroid Build Coastguard Worker {
318*03ce13f7SAndroid Build Coastguard Worker if(depthBuffer)
319*03ce13f7SAndroid Build Coastguard Worker {
320*03ce13f7SAndroid Build Coastguard Worker return depthBuffer->getFormat();
321*03ce13f7SAndroid Build Coastguard Worker }
322*03ce13f7SAndroid Build Coastguard Worker else if(stencilBuffer)
323*03ce13f7SAndroid Build Coastguard Worker {
324*03ce13f7SAndroid Build Coastguard Worker return stencilBuffer->getFormat();
325*03ce13f7SAndroid Build Coastguard Worker }
326*03ce13f7SAndroid Build Coastguard Worker else
327*03ce13f7SAndroid Build Coastguard Worker {
328*03ce13f7SAndroid Build Coastguard Worker return VK_FORMAT_UNDEFINED;
329*03ce13f7SAndroid Build Coastguard Worker }
330*03ce13f7SAndroid Build Coastguard Worker }
331*03ce13f7SAndroid Build Coastguard Worker
initialize(const VkPipelineVertexInputStateCreateInfo * vertexInputState,const VkPipelineDynamicStateCreateInfo * dynamicStateCreateInfo)332*03ce13f7SAndroid Build Coastguard Worker void Inputs::initialize(const VkPipelineVertexInputStateCreateInfo *vertexInputState, const VkPipelineDynamicStateCreateInfo *dynamicStateCreateInfo)
333*03ce13f7SAndroid Build Coastguard Worker {
334*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags = ParseInputsDynamicStateFlags(dynamicStateCreateInfo);
335*03ce13f7SAndroid Build Coastguard Worker
336*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicVertexInput)
337*03ce13f7SAndroid Build Coastguard Worker {
338*03ce13f7SAndroid Build Coastguard Worker return;
339*03ce13f7SAndroid Build Coastguard Worker }
340*03ce13f7SAndroid Build Coastguard Worker
341*03ce13f7SAndroid Build Coastguard Worker if(vertexInputState->flags != 0)
342*03ce13f7SAndroid Build Coastguard Worker {
343*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
344*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("vertexInputState->flags");
345*03ce13f7SAndroid Build Coastguard Worker }
346*03ce13f7SAndroid Build Coastguard Worker
347*03ce13f7SAndroid Build Coastguard Worker // Temporary in-binding-order representation of buffer strides, to be consumed below
348*03ce13f7SAndroid Build Coastguard Worker // when considering attributes. TODO: unfuse buffers from attributes in backend, is old GL model.
349*03ce13f7SAndroid Build Coastguard Worker uint32_t vertexStrides[MAX_VERTEX_INPUT_BINDINGS];
350*03ce13f7SAndroid Build Coastguard Worker uint32_t instanceStrides[MAX_VERTEX_INPUT_BINDINGS];
351*03ce13f7SAndroid Build Coastguard Worker VkVertexInputRate inputRates[MAX_VERTEX_INPUT_BINDINGS];
352*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < vertexInputState->vertexBindingDescriptionCount; i++)
353*03ce13f7SAndroid Build Coastguard Worker {
354*03ce13f7SAndroid Build Coastguard Worker const auto &desc = vertexInputState->pVertexBindingDescriptions[i];
355*03ce13f7SAndroid Build Coastguard Worker inputRates[desc.binding] = desc.inputRate;
356*03ce13f7SAndroid Build Coastguard Worker vertexStrides[desc.binding] = desc.inputRate == VK_VERTEX_INPUT_RATE_VERTEX ? desc.stride : 0;
357*03ce13f7SAndroid Build Coastguard Worker instanceStrides[desc.binding] = desc.inputRate == VK_VERTEX_INPUT_RATE_INSTANCE ? desc.stride : 0;
358*03ce13f7SAndroid Build Coastguard Worker }
359*03ce13f7SAndroid Build Coastguard Worker
360*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < vertexInputState->vertexAttributeDescriptionCount; i++)
361*03ce13f7SAndroid Build Coastguard Worker {
362*03ce13f7SAndroid Build Coastguard Worker const auto &desc = vertexInputState->pVertexAttributeDescriptions[i];
363*03ce13f7SAndroid Build Coastguard Worker sw::Stream &input = stream[desc.location];
364*03ce13f7SAndroid Build Coastguard Worker input.format = desc.format;
365*03ce13f7SAndroid Build Coastguard Worker input.offset = desc.offset;
366*03ce13f7SAndroid Build Coastguard Worker input.binding = desc.binding;
367*03ce13f7SAndroid Build Coastguard Worker input.inputRate = inputRates[desc.binding];
368*03ce13f7SAndroid Build Coastguard Worker if(!dynamicStateFlags.dynamicVertexInputBindingStride)
369*03ce13f7SAndroid Build Coastguard Worker {
370*03ce13f7SAndroid Build Coastguard Worker // The following gets overriden with dynamic state anyway and setting it is
371*03ce13f7SAndroid Build Coastguard Worker // harmless. But it is not done to be able to catch bugs with this dynamic
372*03ce13f7SAndroid Build Coastguard Worker // state easier.
373*03ce13f7SAndroid Build Coastguard Worker input.vertexStride = vertexStrides[desc.binding];
374*03ce13f7SAndroid Build Coastguard Worker input.instanceStride = instanceStrides[desc.binding];
375*03ce13f7SAndroid Build Coastguard Worker }
376*03ce13f7SAndroid Build Coastguard Worker }
377*03ce13f7SAndroid Build Coastguard Worker }
378*03ce13f7SAndroid Build Coastguard Worker
updateDescriptorSets(const DescriptorSet::Array & dso,const DescriptorSet::Bindings & ds,const DescriptorSet::DynamicOffsets & ddo)379*03ce13f7SAndroid Build Coastguard Worker void Inputs::updateDescriptorSets(const DescriptorSet::Array &dso,
380*03ce13f7SAndroid Build Coastguard Worker const DescriptorSet::Bindings &ds,
381*03ce13f7SAndroid Build Coastguard Worker const DescriptorSet::DynamicOffsets &ddo)
382*03ce13f7SAndroid Build Coastguard Worker {
383*03ce13f7SAndroid Build Coastguard Worker descriptorSetObjects = dso;
384*03ce13f7SAndroid Build Coastguard Worker descriptorSets = ds;
385*03ce13f7SAndroid Build Coastguard Worker descriptorDynamicOffsets = ddo;
386*03ce13f7SAndroid Build Coastguard Worker }
387*03ce13f7SAndroid Build Coastguard Worker
bindVertexInputs(int firstInstance)388*03ce13f7SAndroid Build Coastguard Worker void Inputs::bindVertexInputs(int firstInstance)
389*03ce13f7SAndroid Build Coastguard Worker {
390*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
391*03ce13f7SAndroid Build Coastguard Worker {
392*03ce13f7SAndroid Build Coastguard Worker auto &attrib = stream[i];
393*03ce13f7SAndroid Build Coastguard Worker if(attrib.format != VK_FORMAT_UNDEFINED)
394*03ce13f7SAndroid Build Coastguard Worker {
395*03ce13f7SAndroid Build Coastguard Worker const auto &vertexInput = vertexInputBindings[attrib.binding];
396*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize offset = attrib.offset + vertexInput.offset +
397*03ce13f7SAndroid Build Coastguard Worker getInstanceStride(i) * firstInstance;
398*03ce13f7SAndroid Build Coastguard Worker attrib.buffer = vertexInput.buffer ? vertexInput.buffer->getOffsetPointer(offset) : nullptr;
399*03ce13f7SAndroid Build Coastguard Worker
400*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize size = vertexInput.buffer ? vertexInput.buffer->getSize() : 0;
401*03ce13f7SAndroid Build Coastguard Worker attrib.robustnessSize = (size > offset) ? size - offset : 0;
402*03ce13f7SAndroid Build Coastguard Worker }
403*03ce13f7SAndroid Build Coastguard Worker }
404*03ce13f7SAndroid Build Coastguard Worker }
405*03ce13f7SAndroid Build Coastguard Worker
setVertexInputBinding(const VertexInputBinding bindings[],const DynamicState & dynamicState)406*03ce13f7SAndroid Build Coastguard Worker void Inputs::setVertexInputBinding(const VertexInputBinding bindings[], const DynamicState &dynamicState)
407*03ce13f7SAndroid Build Coastguard Worker {
408*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; ++i)
409*03ce13f7SAndroid Build Coastguard Worker {
410*03ce13f7SAndroid Build Coastguard Worker vertexInputBindings[i] = bindings[i];
411*03ce13f7SAndroid Build Coastguard Worker }
412*03ce13f7SAndroid Build Coastguard Worker
413*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicVertexInput)
414*03ce13f7SAndroid Build Coastguard Worker {
415*03ce13f7SAndroid Build Coastguard Worker // If the entire vertex input state is dynamic, recalculate the contents of `stream`.
416*03ce13f7SAndroid Build Coastguard Worker // This is similar to Inputs::initialize.
417*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < sw::MAX_INTERFACE_COMPONENTS / 4; i++)
418*03ce13f7SAndroid Build Coastguard Worker {
419*03ce13f7SAndroid Build Coastguard Worker const auto &desc = dynamicState.vertexInputAttributes[i];
420*03ce13f7SAndroid Build Coastguard Worker const auto &bindingDesc = dynamicState.vertexInputBindings[desc.binding];
421*03ce13f7SAndroid Build Coastguard Worker sw::Stream &input = stream[i];
422*03ce13f7SAndroid Build Coastguard Worker input.format = desc.format;
423*03ce13f7SAndroid Build Coastguard Worker input.offset = desc.offset;
424*03ce13f7SAndroid Build Coastguard Worker input.binding = desc.binding;
425*03ce13f7SAndroid Build Coastguard Worker input.inputRate = bindingDesc.inputRate;
426*03ce13f7SAndroid Build Coastguard Worker }
427*03ce13f7SAndroid Build Coastguard Worker }
428*03ce13f7SAndroid Build Coastguard Worker
429*03ce13f7SAndroid Build Coastguard Worker // Stride may come from two different dynamic states
430*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicVertexInput || dynamicStateFlags.dynamicVertexInputBindingStride)
431*03ce13f7SAndroid Build Coastguard Worker {
432*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < sw::MAX_INTERFACE_COMPONENTS / 4; i++)
433*03ce13f7SAndroid Build Coastguard Worker {
434*03ce13f7SAndroid Build Coastguard Worker sw::Stream &input = stream[i];
435*03ce13f7SAndroid Build Coastguard Worker const VkDeviceSize stride = dynamicState.vertexInputBindings[input.binding].stride;
436*03ce13f7SAndroid Build Coastguard Worker
437*03ce13f7SAndroid Build Coastguard Worker input.vertexStride = input.inputRate == VK_VERTEX_INPUT_RATE_VERTEX ? stride : 0;
438*03ce13f7SAndroid Build Coastguard Worker input.instanceStride = input.inputRate == VK_VERTEX_INPUT_RATE_INSTANCE ? stride : 0;
439*03ce13f7SAndroid Build Coastguard Worker }
440*03ce13f7SAndroid Build Coastguard Worker }
441*03ce13f7SAndroid Build Coastguard Worker }
442*03ce13f7SAndroid Build Coastguard Worker
advanceInstanceAttributes()443*03ce13f7SAndroid Build Coastguard Worker void Inputs::advanceInstanceAttributes()
444*03ce13f7SAndroid Build Coastguard Worker {
445*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < vk::MAX_VERTEX_INPUT_BINDINGS; i++)
446*03ce13f7SAndroid Build Coastguard Worker {
447*03ce13f7SAndroid Build Coastguard Worker auto &attrib = stream[i];
448*03ce13f7SAndroid Build Coastguard Worker
449*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize instanceStride = getInstanceStride(i);
450*03ce13f7SAndroid Build Coastguard Worker if((attrib.format != VK_FORMAT_UNDEFINED) && instanceStride && (instanceStride < attrib.robustnessSize))
451*03ce13f7SAndroid Build Coastguard Worker {
452*03ce13f7SAndroid Build Coastguard Worker // Under the casts: attrib.buffer += instanceStride
453*03ce13f7SAndroid Build Coastguard Worker attrib.buffer = (const void *)((uintptr_t)attrib.buffer + instanceStride);
454*03ce13f7SAndroid Build Coastguard Worker attrib.robustnessSize -= instanceStride;
455*03ce13f7SAndroid Build Coastguard Worker }
456*03ce13f7SAndroid Build Coastguard Worker }
457*03ce13f7SAndroid Build Coastguard Worker }
458*03ce13f7SAndroid Build Coastguard Worker
getVertexStride(uint32_t i) const459*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize Inputs::getVertexStride(uint32_t i) const
460*03ce13f7SAndroid Build Coastguard Worker {
461*03ce13f7SAndroid Build Coastguard Worker auto &attrib = stream[i];
462*03ce13f7SAndroid Build Coastguard Worker if(attrib.format != VK_FORMAT_UNDEFINED)
463*03ce13f7SAndroid Build Coastguard Worker {
464*03ce13f7SAndroid Build Coastguard Worker return attrib.vertexStride;
465*03ce13f7SAndroid Build Coastguard Worker }
466*03ce13f7SAndroid Build Coastguard Worker
467*03ce13f7SAndroid Build Coastguard Worker return 0;
468*03ce13f7SAndroid Build Coastguard Worker }
469*03ce13f7SAndroid Build Coastguard Worker
getInstanceStride(uint32_t i) const470*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize Inputs::getInstanceStride(uint32_t i) const
471*03ce13f7SAndroid Build Coastguard Worker {
472*03ce13f7SAndroid Build Coastguard Worker auto &attrib = stream[i];
473*03ce13f7SAndroid Build Coastguard Worker if(attrib.format != VK_FORMAT_UNDEFINED)
474*03ce13f7SAndroid Build Coastguard Worker {
475*03ce13f7SAndroid Build Coastguard Worker return attrib.instanceStride;
476*03ce13f7SAndroid Build Coastguard Worker }
477*03ce13f7SAndroid Build Coastguard Worker
478*03ce13f7SAndroid Build Coastguard Worker return 0;
479*03ce13f7SAndroid Build Coastguard Worker }
480*03ce13f7SAndroid Build Coastguard Worker
set(const VkPipelineMultisampleStateCreateInfo * multisampleState)481*03ce13f7SAndroid Build Coastguard Worker void MultisampleState::set(const VkPipelineMultisampleStateCreateInfo *multisampleState)
482*03ce13f7SAndroid Build Coastguard Worker {
483*03ce13f7SAndroid Build Coastguard Worker if(multisampleState->flags != 0)
484*03ce13f7SAndroid Build Coastguard Worker {
485*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
486*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("pCreateInfo->pMultisampleState->flags 0x%08X", int(multisampleState->flags));
487*03ce13f7SAndroid Build Coastguard Worker }
488*03ce13f7SAndroid Build Coastguard Worker
489*03ce13f7SAndroid Build Coastguard Worker sampleShadingEnable = (multisampleState->sampleShadingEnable != VK_FALSE);
490*03ce13f7SAndroid Build Coastguard Worker if(sampleShadingEnable)
491*03ce13f7SAndroid Build Coastguard Worker {
492*03ce13f7SAndroid Build Coastguard Worker minSampleShading = multisampleState->minSampleShading;
493*03ce13f7SAndroid Build Coastguard Worker }
494*03ce13f7SAndroid Build Coastguard Worker
495*03ce13f7SAndroid Build Coastguard Worker if(multisampleState->alphaToOneEnable != VK_FALSE)
496*03ce13f7SAndroid Build Coastguard Worker {
497*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("VkPhysicalDeviceFeatures::alphaToOne");
498*03ce13f7SAndroid Build Coastguard Worker }
499*03ce13f7SAndroid Build Coastguard Worker
500*03ce13f7SAndroid Build Coastguard Worker switch(multisampleState->rasterizationSamples)
501*03ce13f7SAndroid Build Coastguard Worker {
502*03ce13f7SAndroid Build Coastguard Worker case VK_SAMPLE_COUNT_1_BIT:
503*03ce13f7SAndroid Build Coastguard Worker sampleCount = 1;
504*03ce13f7SAndroid Build Coastguard Worker break;
505*03ce13f7SAndroid Build Coastguard Worker case VK_SAMPLE_COUNT_4_BIT:
506*03ce13f7SAndroid Build Coastguard Worker sampleCount = 4;
507*03ce13f7SAndroid Build Coastguard Worker break;
508*03ce13f7SAndroid Build Coastguard Worker default:
509*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("Unsupported sample count");
510*03ce13f7SAndroid Build Coastguard Worker }
511*03ce13f7SAndroid Build Coastguard Worker
512*03ce13f7SAndroid Build Coastguard Worker VkSampleMask sampleMask;
513*03ce13f7SAndroid Build Coastguard Worker if(multisampleState->pSampleMask)
514*03ce13f7SAndroid Build Coastguard Worker {
515*03ce13f7SAndroid Build Coastguard Worker sampleMask = multisampleState->pSampleMask[0];
516*03ce13f7SAndroid Build Coastguard Worker }
517*03ce13f7SAndroid Build Coastguard Worker else // "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
518*03ce13f7SAndroid Build Coastguard Worker {
519*03ce13f7SAndroid Build Coastguard Worker sampleMask = ~0;
520*03ce13f7SAndroid Build Coastguard Worker }
521*03ce13f7SAndroid Build Coastguard Worker
522*03ce13f7SAndroid Build Coastguard Worker alphaToCoverage = (multisampleState->alphaToCoverageEnable != VK_FALSE);
523*03ce13f7SAndroid Build Coastguard Worker multiSampleMask = sampleMask & ((unsigned)0xFFFFFFFF >> (32 - sampleCount));
524*03ce13f7SAndroid Build Coastguard Worker }
525*03ce13f7SAndroid Build Coastguard Worker
initialize(const VkPipelineVertexInputStateCreateInfo * vertexInputState,const VkPipelineInputAssemblyStateCreateInfo * inputAssemblyState,const DynamicStateFlags & allDynamicStateFlags)526*03ce13f7SAndroid Build Coastguard Worker void VertexInputInterfaceState::initialize(const VkPipelineVertexInputStateCreateInfo *vertexInputState,
527*03ce13f7SAndroid Build Coastguard Worker const VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState,
528*03ce13f7SAndroid Build Coastguard Worker const DynamicStateFlags &allDynamicStateFlags)
529*03ce13f7SAndroid Build Coastguard Worker {
530*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags = allDynamicStateFlags.vertexInputInterface;
531*03ce13f7SAndroid Build Coastguard Worker
532*03ce13f7SAndroid Build Coastguard Worker if(vertexInputState && vertexInputState->flags != 0)
533*03ce13f7SAndroid Build Coastguard Worker {
534*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
535*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("vertexInputState->flags");
536*03ce13f7SAndroid Build Coastguard Worker }
537*03ce13f7SAndroid Build Coastguard Worker
538*03ce13f7SAndroid Build Coastguard Worker if(inputAssemblyState->flags != 0)
539*03ce13f7SAndroid Build Coastguard Worker {
540*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
541*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("pCreateInfo->pInputAssemblyState->flags 0x%08X", int(inputAssemblyState->flags));
542*03ce13f7SAndroid Build Coastguard Worker }
543*03ce13f7SAndroid Build Coastguard Worker
544*03ce13f7SAndroid Build Coastguard Worker primitiveRestartEnable = (inputAssemblyState->primitiveRestartEnable != VK_FALSE);
545*03ce13f7SAndroid Build Coastguard Worker topology = inputAssemblyState->topology;
546*03ce13f7SAndroid Build Coastguard Worker }
547*03ce13f7SAndroid Build Coastguard Worker
applyState(const DynamicState & dynamicState)548*03ce13f7SAndroid Build Coastguard Worker void VertexInputInterfaceState::applyState(const DynamicState &dynamicState)
549*03ce13f7SAndroid Build Coastguard Worker {
550*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicPrimitiveRestartEnable)
551*03ce13f7SAndroid Build Coastguard Worker {
552*03ce13f7SAndroid Build Coastguard Worker primitiveRestartEnable = dynamicState.primitiveRestartEnable;
553*03ce13f7SAndroid Build Coastguard Worker }
554*03ce13f7SAndroid Build Coastguard Worker
555*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicPrimitiveTopology)
556*03ce13f7SAndroid Build Coastguard Worker {
557*03ce13f7SAndroid Build Coastguard Worker topology = dynamicState.primitiveTopology;
558*03ce13f7SAndroid Build Coastguard Worker }
559*03ce13f7SAndroid Build Coastguard Worker }
560*03ce13f7SAndroid Build Coastguard Worker
isDrawPoint(bool polygonModeAware,VkPolygonMode polygonMode) const561*03ce13f7SAndroid Build Coastguard Worker bool VertexInputInterfaceState::isDrawPoint(bool polygonModeAware, VkPolygonMode polygonMode) const
562*03ce13f7SAndroid Build Coastguard Worker {
563*03ce13f7SAndroid Build Coastguard Worker switch(topology)
564*03ce13f7SAndroid Build Coastguard Worker {
565*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
566*03ce13f7SAndroid Build Coastguard Worker return true;
567*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
568*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
569*03ce13f7SAndroid Build Coastguard Worker return false;
570*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
571*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
572*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
573*03ce13f7SAndroid Build Coastguard Worker return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_POINT) : false;
574*03ce13f7SAndroid Build Coastguard Worker default:
575*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("topology %d", int(topology));
576*03ce13f7SAndroid Build Coastguard Worker }
577*03ce13f7SAndroid Build Coastguard Worker return false;
578*03ce13f7SAndroid Build Coastguard Worker }
579*03ce13f7SAndroid Build Coastguard Worker
isDrawLine(bool polygonModeAware,VkPolygonMode polygonMode) const580*03ce13f7SAndroid Build Coastguard Worker bool VertexInputInterfaceState::isDrawLine(bool polygonModeAware, VkPolygonMode polygonMode) const
581*03ce13f7SAndroid Build Coastguard Worker {
582*03ce13f7SAndroid Build Coastguard Worker switch(topology)
583*03ce13f7SAndroid Build Coastguard Worker {
584*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
585*03ce13f7SAndroid Build Coastguard Worker return false;
586*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
587*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
588*03ce13f7SAndroid Build Coastguard Worker return true;
589*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
590*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
591*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
592*03ce13f7SAndroid Build Coastguard Worker return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_LINE) : false;
593*03ce13f7SAndroid Build Coastguard Worker default:
594*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("topology %d", int(topology));
595*03ce13f7SAndroid Build Coastguard Worker }
596*03ce13f7SAndroid Build Coastguard Worker return false;
597*03ce13f7SAndroid Build Coastguard Worker }
598*03ce13f7SAndroid Build Coastguard Worker
isDrawTriangle(bool polygonModeAware,VkPolygonMode polygonMode) const599*03ce13f7SAndroid Build Coastguard Worker bool VertexInputInterfaceState::isDrawTriangle(bool polygonModeAware, VkPolygonMode polygonMode) const
600*03ce13f7SAndroid Build Coastguard Worker {
601*03ce13f7SAndroid Build Coastguard Worker switch(topology)
602*03ce13f7SAndroid Build Coastguard Worker {
603*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
604*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
605*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
606*03ce13f7SAndroid Build Coastguard Worker return false;
607*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
608*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
609*03ce13f7SAndroid Build Coastguard Worker case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
610*03ce13f7SAndroid Build Coastguard Worker return polygonModeAware ? (polygonMode == VK_POLYGON_MODE_FILL) : true;
611*03ce13f7SAndroid Build Coastguard Worker default:
612*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("topology %d", int(topology));
613*03ce13f7SAndroid Build Coastguard Worker }
614*03ce13f7SAndroid Build Coastguard Worker return false;
615*03ce13f7SAndroid Build Coastguard Worker }
616*03ce13f7SAndroid Build Coastguard Worker
initialize(const vk::Device * device,const PipelineLayout * layout,const VkPipelineViewportStateCreateInfo * viewportState,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const vk::RenderPass * renderPass,uint32_t subpassIndex,const VkPipelineRenderingCreateInfo * rendering,const DynamicStateFlags & allDynamicStateFlags)617*03ce13f7SAndroid Build Coastguard Worker void PreRasterizationState::initialize(const vk::Device *device,
618*03ce13f7SAndroid Build Coastguard Worker const PipelineLayout *layout,
619*03ce13f7SAndroid Build Coastguard Worker const VkPipelineViewportStateCreateInfo *viewportState,
620*03ce13f7SAndroid Build Coastguard Worker const VkPipelineRasterizationStateCreateInfo *rasterizationState,
621*03ce13f7SAndroid Build Coastguard Worker const vk::RenderPass *renderPass, uint32_t subpassIndex,
622*03ce13f7SAndroid Build Coastguard Worker const VkPipelineRenderingCreateInfo *rendering,
623*03ce13f7SAndroid Build Coastguard Worker const DynamicStateFlags &allDynamicStateFlags)
624*03ce13f7SAndroid Build Coastguard Worker {
625*03ce13f7SAndroid Build Coastguard Worker pipelineLayout = layout;
626*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags = allDynamicStateFlags.preRasterization;
627*03ce13f7SAndroid Build Coastguard Worker
628*03ce13f7SAndroid Build Coastguard Worker if(rasterizationState->flags != 0)
629*03ce13f7SAndroid Build Coastguard Worker {
630*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
631*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("pCreateInfo->pRasterizationState->flags 0x%08X", int(rasterizationState->flags));
632*03ce13f7SAndroid Build Coastguard Worker }
633*03ce13f7SAndroid Build Coastguard Worker
634*03ce13f7SAndroid Build Coastguard Worker rasterizerDiscard = rasterizationState->rasterizerDiscardEnable != VK_FALSE;
635*03ce13f7SAndroid Build Coastguard Worker cullMode = rasterizationState->cullMode;
636*03ce13f7SAndroid Build Coastguard Worker frontFace = rasterizationState->frontFace;
637*03ce13f7SAndroid Build Coastguard Worker polygonMode = rasterizationState->polygonMode;
638*03ce13f7SAndroid Build Coastguard Worker depthBiasEnable = rasterizationState->depthBiasEnable;
639*03ce13f7SAndroid Build Coastguard Worker constantDepthBias = rasterizationState->depthBiasConstantFactor;
640*03ce13f7SAndroid Build Coastguard Worker slopeDepthBias = rasterizationState->depthBiasSlopeFactor;
641*03ce13f7SAndroid Build Coastguard Worker depthBiasClamp = rasterizationState->depthBiasClamp;
642*03ce13f7SAndroid Build Coastguard Worker depthRangeUnrestricted = device->hasExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
643*03ce13f7SAndroid Build Coastguard Worker depthClampEnable = rasterizationState->depthClampEnable != VK_FALSE;
644*03ce13f7SAndroid Build Coastguard Worker depthClipEnable = !depthClampEnable;
645*03ce13f7SAndroid Build Coastguard Worker
646*03ce13f7SAndroid Build Coastguard Worker // From the Vulkan spec for vkCmdSetDepthBias:
647*03ce13f7SAndroid Build Coastguard Worker // The bias value O for a polygon is:
648*03ce13f7SAndroid Build Coastguard Worker // O = dbclamp(...)
649*03ce13f7SAndroid Build Coastguard Worker // where dbclamp(x) =
650*03ce13f7SAndroid Build Coastguard Worker // * x depthBiasClamp = 0 or NaN
651*03ce13f7SAndroid Build Coastguard Worker // * min(x, depthBiasClamp) depthBiasClamp > 0
652*03ce13f7SAndroid Build Coastguard Worker // * max(x, depthBiasClamp) depthBiasClamp < 0
653*03ce13f7SAndroid Build Coastguard Worker // So it should be safe to resolve NaNs to 0.0f.
654*03ce13f7SAndroid Build Coastguard Worker if(std::isnan(depthBiasClamp))
655*03ce13f7SAndroid Build Coastguard Worker {
656*03ce13f7SAndroid Build Coastguard Worker depthBiasClamp = 0.0f;
657*03ce13f7SAndroid Build Coastguard Worker }
658*03ce13f7SAndroid Build Coastguard Worker
659*03ce13f7SAndroid Build Coastguard Worker if(!dynamicStateFlags.dynamicLineWidth)
660*03ce13f7SAndroid Build Coastguard Worker {
661*03ce13f7SAndroid Build Coastguard Worker lineWidth = rasterizationState->lineWidth;
662*03ce13f7SAndroid Build Coastguard Worker }
663*03ce13f7SAndroid Build Coastguard Worker
664*03ce13f7SAndroid Build Coastguard Worker const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(rasterizationState->pNext);
665*03ce13f7SAndroid Build Coastguard Worker while(extensionCreateInfo)
666*03ce13f7SAndroid Build Coastguard Worker {
667*03ce13f7SAndroid Build Coastguard Worker switch(extensionCreateInfo->sType)
668*03ce13f7SAndroid Build Coastguard Worker {
669*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT:
670*03ce13f7SAndroid Build Coastguard Worker {
671*03ce13f7SAndroid Build Coastguard Worker const VkPipelineRasterizationLineStateCreateInfoEXT *lineStateCreateInfo = reinterpret_cast<const VkPipelineRasterizationLineStateCreateInfoEXT *>(extensionCreateInfo);
672*03ce13f7SAndroid Build Coastguard Worker lineRasterizationMode = lineStateCreateInfo->lineRasterizationMode;
673*03ce13f7SAndroid Build Coastguard Worker }
674*03ce13f7SAndroid Build Coastguard Worker break;
675*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT:
676*03ce13f7SAndroid Build Coastguard Worker {
677*03ce13f7SAndroid Build Coastguard Worker const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *provokingVertexModeCreateInfo =
678*03ce13f7SAndroid Build Coastguard Worker reinterpret_cast<const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *>(extensionCreateInfo);
679*03ce13f7SAndroid Build Coastguard Worker provokingVertexMode = provokingVertexModeCreateInfo->provokingVertexMode;
680*03ce13f7SAndroid Build Coastguard Worker }
681*03ce13f7SAndroid Build Coastguard Worker break;
682*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT:
683*03ce13f7SAndroid Build Coastguard Worker {
684*03ce13f7SAndroid Build Coastguard Worker const auto *depthClipInfo = reinterpret_cast<const VkPipelineRasterizationDepthClipStateCreateInfoEXT *>(extensionCreateInfo);
685*03ce13f7SAndroid Build Coastguard Worker // Reserved for future use.
686*03ce13f7SAndroid Build Coastguard Worker ASSERT(depthClipInfo->flags == 0);
687*03ce13f7SAndroid Build Coastguard Worker depthClipEnable = depthClipInfo->depthClipEnable != VK_FALSE;
688*03ce13f7SAndroid Build Coastguard Worker }
689*03ce13f7SAndroid Build Coastguard Worker break;
690*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_APPLICATION_INFO:
691*03ce13f7SAndroid Build Coastguard Worker // SwiftShader doesn't interact with application info, but dEQP includes it
692*03ce13f7SAndroid Build Coastguard Worker break;
693*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_MAX_ENUM:
694*03ce13f7SAndroid Build Coastguard Worker // dEQP tests that this value is ignored.
695*03ce13f7SAndroid Build Coastguard Worker break;
696*03ce13f7SAndroid Build Coastguard Worker default:
697*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("pCreateInfo->pRasterizationState->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
698*03ce13f7SAndroid Build Coastguard Worker break;
699*03ce13f7SAndroid Build Coastguard Worker }
700*03ce13f7SAndroid Build Coastguard Worker
701*03ce13f7SAndroid Build Coastguard Worker extensionCreateInfo = extensionCreateInfo->pNext;
702*03ce13f7SAndroid Build Coastguard Worker }
703*03ce13f7SAndroid Build Coastguard Worker
704*03ce13f7SAndroid Build Coastguard Worker if(!rasterizerDiscard || dynamicStateFlags.dynamicRasterizerDiscardEnable)
705*03ce13f7SAndroid Build Coastguard Worker {
706*03ce13f7SAndroid Build Coastguard Worker extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(viewportState->pNext);
707*03ce13f7SAndroid Build Coastguard Worker while(extensionCreateInfo != nullptr)
708*03ce13f7SAndroid Build Coastguard Worker {
709*03ce13f7SAndroid Build Coastguard Worker switch(extensionCreateInfo->sType)
710*03ce13f7SAndroid Build Coastguard Worker {
711*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT:
712*03ce13f7SAndroid Build Coastguard Worker {
713*03ce13f7SAndroid Build Coastguard Worker const auto *depthClipControl = reinterpret_cast<const VkPipelineViewportDepthClipControlCreateInfoEXT *>(extensionCreateInfo);
714*03ce13f7SAndroid Build Coastguard Worker depthClipNegativeOneToOne = depthClipControl->negativeOneToOne != VK_FALSE;
715*03ce13f7SAndroid Build Coastguard Worker }
716*03ce13f7SAndroid Build Coastguard Worker break;
717*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_MAX_ENUM:
718*03ce13f7SAndroid Build Coastguard Worker // dEQP passes this value expecting the driver to ignore it.
719*03ce13f7SAndroid Build Coastguard Worker break;
720*03ce13f7SAndroid Build Coastguard Worker default:
721*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("pCreateInfo->pViewportState->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
722*03ce13f7SAndroid Build Coastguard Worker break;
723*03ce13f7SAndroid Build Coastguard Worker }
724*03ce13f7SAndroid Build Coastguard Worker extensionCreateInfo = extensionCreateInfo->pNext;
725*03ce13f7SAndroid Build Coastguard Worker }
726*03ce13f7SAndroid Build Coastguard Worker
727*03ce13f7SAndroid Build Coastguard Worker if(viewportState->flags != 0)
728*03ce13f7SAndroid Build Coastguard Worker {
729*03ce13f7SAndroid Build Coastguard Worker // Vulkan 1.2: "flags is reserved for future use." "flags must be 0"
730*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("pCreateInfo->pViewportState->flags 0x%08X", int(viewportState->flags));
731*03ce13f7SAndroid Build Coastguard Worker }
732*03ce13f7SAndroid Build Coastguard Worker
733*03ce13f7SAndroid Build Coastguard Worker if((viewportState->viewportCount > 1) ||
734*03ce13f7SAndroid Build Coastguard Worker (viewportState->scissorCount > 1))
735*03ce13f7SAndroid Build Coastguard Worker {
736*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("VkPhysicalDeviceFeatures::multiViewport");
737*03ce13f7SAndroid Build Coastguard Worker }
738*03ce13f7SAndroid Build Coastguard Worker
739*03ce13f7SAndroid Build Coastguard Worker if(!dynamicStateFlags.dynamicScissor && !dynamicStateFlags.dynamicScissorWithCount)
740*03ce13f7SAndroid Build Coastguard Worker {
741*03ce13f7SAndroid Build Coastguard Worker scissor = viewportState->pScissors[0];
742*03ce13f7SAndroid Build Coastguard Worker }
743*03ce13f7SAndroid Build Coastguard Worker
744*03ce13f7SAndroid Build Coastguard Worker if(!dynamicStateFlags.dynamicViewport && !dynamicStateFlags.dynamicViewportWithCount)
745*03ce13f7SAndroid Build Coastguard Worker {
746*03ce13f7SAndroid Build Coastguard Worker viewport = viewportState->pViewports[0];
747*03ce13f7SAndroid Build Coastguard Worker }
748*03ce13f7SAndroid Build Coastguard Worker }
749*03ce13f7SAndroid Build Coastguard Worker }
750*03ce13f7SAndroid Build Coastguard Worker
applyState(const DynamicState & dynamicState)751*03ce13f7SAndroid Build Coastguard Worker void PreRasterizationState::applyState(const DynamicState &dynamicState)
752*03ce13f7SAndroid Build Coastguard Worker {
753*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicLineWidth)
754*03ce13f7SAndroid Build Coastguard Worker {
755*03ce13f7SAndroid Build Coastguard Worker lineWidth = dynamicState.lineWidth;
756*03ce13f7SAndroid Build Coastguard Worker }
757*03ce13f7SAndroid Build Coastguard Worker
758*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicDepthBias)
759*03ce13f7SAndroid Build Coastguard Worker {
760*03ce13f7SAndroid Build Coastguard Worker constantDepthBias = dynamicState.depthBiasConstantFactor;
761*03ce13f7SAndroid Build Coastguard Worker slopeDepthBias = dynamicState.depthBiasSlopeFactor;
762*03ce13f7SAndroid Build Coastguard Worker depthBiasClamp = dynamicState.depthBiasClamp;
763*03ce13f7SAndroid Build Coastguard Worker }
764*03ce13f7SAndroid Build Coastguard Worker
765*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicDepthBiasEnable)
766*03ce13f7SAndroid Build Coastguard Worker {
767*03ce13f7SAndroid Build Coastguard Worker depthBiasEnable = dynamicState.depthBiasEnable;
768*03ce13f7SAndroid Build Coastguard Worker }
769*03ce13f7SAndroid Build Coastguard Worker
770*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicCullMode)
771*03ce13f7SAndroid Build Coastguard Worker {
772*03ce13f7SAndroid Build Coastguard Worker cullMode = dynamicState.cullMode;
773*03ce13f7SAndroid Build Coastguard Worker }
774*03ce13f7SAndroid Build Coastguard Worker
775*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicFrontFace)
776*03ce13f7SAndroid Build Coastguard Worker {
777*03ce13f7SAndroid Build Coastguard Worker frontFace = dynamicState.frontFace;
778*03ce13f7SAndroid Build Coastguard Worker }
779*03ce13f7SAndroid Build Coastguard Worker
780*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicViewport)
781*03ce13f7SAndroid Build Coastguard Worker {
782*03ce13f7SAndroid Build Coastguard Worker viewport = dynamicState.viewport;
783*03ce13f7SAndroid Build Coastguard Worker }
784*03ce13f7SAndroid Build Coastguard Worker
785*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicScissor)
786*03ce13f7SAndroid Build Coastguard Worker {
787*03ce13f7SAndroid Build Coastguard Worker scissor = dynamicState.scissor;
788*03ce13f7SAndroid Build Coastguard Worker }
789*03ce13f7SAndroid Build Coastguard Worker
790*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicViewportWithCount && dynamicState.viewportCount > 0)
791*03ce13f7SAndroid Build Coastguard Worker {
792*03ce13f7SAndroid Build Coastguard Worker viewport = dynamicState.viewports[0];
793*03ce13f7SAndroid Build Coastguard Worker }
794*03ce13f7SAndroid Build Coastguard Worker
795*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicScissorWithCount && dynamicState.scissorCount > 0)
796*03ce13f7SAndroid Build Coastguard Worker {
797*03ce13f7SAndroid Build Coastguard Worker scissor = dynamicState.scissors[0];
798*03ce13f7SAndroid Build Coastguard Worker }
799*03ce13f7SAndroid Build Coastguard Worker
800*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicRasterizerDiscardEnable)
801*03ce13f7SAndroid Build Coastguard Worker {
802*03ce13f7SAndroid Build Coastguard Worker rasterizerDiscard = dynamicState.rasterizerDiscardEnable;
803*03ce13f7SAndroid Build Coastguard Worker }
804*03ce13f7SAndroid Build Coastguard Worker }
805*03ce13f7SAndroid Build Coastguard Worker
initialize(const PipelineLayout * layout,const VkPipelineDepthStencilStateCreateInfo * depthStencilState,const vk::RenderPass * renderPass,uint32_t subpassIndex,const VkPipelineRenderingCreateInfo * rendering,const DynamicStateFlags & allDynamicStateFlags)806*03ce13f7SAndroid Build Coastguard Worker void FragmentState::initialize(
807*03ce13f7SAndroid Build Coastguard Worker const PipelineLayout *layout,
808*03ce13f7SAndroid Build Coastguard Worker const VkPipelineDepthStencilStateCreateInfo *depthStencilState,
809*03ce13f7SAndroid Build Coastguard Worker const vk::RenderPass *renderPass, uint32_t subpassIndex,
810*03ce13f7SAndroid Build Coastguard Worker const VkPipelineRenderingCreateInfo *rendering,
811*03ce13f7SAndroid Build Coastguard Worker const DynamicStateFlags &allDynamicStateFlags)
812*03ce13f7SAndroid Build Coastguard Worker {
813*03ce13f7SAndroid Build Coastguard Worker pipelineLayout = layout;
814*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags = allDynamicStateFlags.fragment;
815*03ce13f7SAndroid Build Coastguard Worker
816*03ce13f7SAndroid Build Coastguard Worker if(renderPass)
817*03ce13f7SAndroid Build Coastguard Worker {
818*03ce13f7SAndroid Build Coastguard Worker const VkSubpassDescription &subpass = renderPass->getSubpass(subpassIndex);
819*03ce13f7SAndroid Build Coastguard Worker
820*03ce13f7SAndroid Build Coastguard Worker // Ignore pDepthStencilState when "the subpass of the render pass the pipeline
821*03ce13f7SAndroid Build Coastguard Worker // is created against does not use a depth/stencil attachment"
822*03ce13f7SAndroid Build Coastguard Worker if(subpass.pDepthStencilAttachment &&
823*03ce13f7SAndroid Build Coastguard Worker subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
824*03ce13f7SAndroid Build Coastguard Worker {
825*03ce13f7SAndroid Build Coastguard Worker setDepthStencilState(depthStencilState);
826*03ce13f7SAndroid Build Coastguard Worker }
827*03ce13f7SAndroid Build Coastguard Worker }
828*03ce13f7SAndroid Build Coastguard Worker else // No render pass
829*03ce13f7SAndroid Build Coastguard Worker {
830*03ce13f7SAndroid Build Coastguard Worker // When a pipeline is created without a VkRenderPass, if the VkPipelineRenderingCreateInfo structure
831*03ce13f7SAndroid Build Coastguard Worker // is present in the pNext chain of VkGraphicsPipelineCreateInfo, it specifies the view mask and
832*03ce13f7SAndroid Build Coastguard Worker // format of attachments used for rendering. If this structure is not specified, and the pipeline
833*03ce13f7SAndroid Build Coastguard Worker // does not include a VkRenderPass, viewMask and colorAttachmentCount are 0, and
834*03ce13f7SAndroid Build Coastguard Worker // depthAttachmentFormat and stencilAttachmentFormat are VK_FORMAT_UNDEFINED. If a graphics pipeline
835*03ce13f7SAndroid Build Coastguard Worker // is created with a valid VkRenderPass, parameters of this structure are ignored.
836*03ce13f7SAndroid Build Coastguard Worker
837*03ce13f7SAndroid Build Coastguard Worker if(rendering)
838*03ce13f7SAndroid Build Coastguard Worker {
839*03ce13f7SAndroid Build Coastguard Worker if((rendering->depthAttachmentFormat != VK_FORMAT_UNDEFINED) ||
840*03ce13f7SAndroid Build Coastguard Worker (rendering->stencilAttachmentFormat != VK_FORMAT_UNDEFINED))
841*03ce13f7SAndroid Build Coastguard Worker {
842*03ce13f7SAndroid Build Coastguard Worker // If renderPass is VK_NULL_HANDLE, the pipeline is being created with fragment
843*03ce13f7SAndroid Build Coastguard Worker // shader state, and either of VkPipelineRenderingCreateInfo::depthAttachmentFormat
844*03ce13f7SAndroid Build Coastguard Worker // or VkPipelineRenderingCreateInfo::stencilAttachmentFormat are not
845*03ce13f7SAndroid Build Coastguard Worker // VK_FORMAT_UNDEFINED, pDepthStencilState must be a valid pointer to a valid
846*03ce13f7SAndroid Build Coastguard Worker // VkPipelineDepthStencilStateCreateInfo structure
847*03ce13f7SAndroid Build Coastguard Worker ASSERT(depthStencilState);
848*03ce13f7SAndroid Build Coastguard Worker
849*03ce13f7SAndroid Build Coastguard Worker setDepthStencilState(depthStencilState);
850*03ce13f7SAndroid Build Coastguard Worker }
851*03ce13f7SAndroid Build Coastguard Worker }
852*03ce13f7SAndroid Build Coastguard Worker }
853*03ce13f7SAndroid Build Coastguard Worker }
854*03ce13f7SAndroid Build Coastguard Worker
applyState(const DynamicState & dynamicState)855*03ce13f7SAndroid Build Coastguard Worker void FragmentState::applyState(const DynamicState &dynamicState)
856*03ce13f7SAndroid Build Coastguard Worker {
857*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicDepthTestEnable)
858*03ce13f7SAndroid Build Coastguard Worker {
859*03ce13f7SAndroid Build Coastguard Worker depthTestEnable = dynamicState.depthTestEnable;
860*03ce13f7SAndroid Build Coastguard Worker }
861*03ce13f7SAndroid Build Coastguard Worker
862*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicDepthWriteEnable)
863*03ce13f7SAndroid Build Coastguard Worker {
864*03ce13f7SAndroid Build Coastguard Worker depthWriteEnable = dynamicState.depthWriteEnable;
865*03ce13f7SAndroid Build Coastguard Worker }
866*03ce13f7SAndroid Build Coastguard Worker
867*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicDepthBoundsTestEnable)
868*03ce13f7SAndroid Build Coastguard Worker {
869*03ce13f7SAndroid Build Coastguard Worker depthBoundsTestEnable = dynamicState.depthBoundsTestEnable;
870*03ce13f7SAndroid Build Coastguard Worker }
871*03ce13f7SAndroid Build Coastguard Worker
872*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicDepthBounds && depthBoundsTestEnable)
873*03ce13f7SAndroid Build Coastguard Worker {
874*03ce13f7SAndroid Build Coastguard Worker minDepthBounds = dynamicState.minDepthBounds;
875*03ce13f7SAndroid Build Coastguard Worker maxDepthBounds = dynamicState.maxDepthBounds;
876*03ce13f7SAndroid Build Coastguard Worker }
877*03ce13f7SAndroid Build Coastguard Worker
878*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicDepthCompareOp)
879*03ce13f7SAndroid Build Coastguard Worker {
880*03ce13f7SAndroid Build Coastguard Worker depthCompareMode = dynamicState.depthCompareOp;
881*03ce13f7SAndroid Build Coastguard Worker }
882*03ce13f7SAndroid Build Coastguard Worker
883*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicStencilTestEnable)
884*03ce13f7SAndroid Build Coastguard Worker {
885*03ce13f7SAndroid Build Coastguard Worker stencilEnable = dynamicState.stencilTestEnable;
886*03ce13f7SAndroid Build Coastguard Worker }
887*03ce13f7SAndroid Build Coastguard Worker
888*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicStencilOp && stencilEnable)
889*03ce13f7SAndroid Build Coastguard Worker {
890*03ce13f7SAndroid Build Coastguard Worker if(dynamicState.faceMask & VK_STENCIL_FACE_FRONT_BIT)
891*03ce13f7SAndroid Build Coastguard Worker {
892*03ce13f7SAndroid Build Coastguard Worker frontStencil.compareOp = dynamicState.frontStencil.compareOp;
893*03ce13f7SAndroid Build Coastguard Worker frontStencil.depthFailOp = dynamicState.frontStencil.depthFailOp;
894*03ce13f7SAndroid Build Coastguard Worker frontStencil.failOp = dynamicState.frontStencil.failOp;
895*03ce13f7SAndroid Build Coastguard Worker frontStencil.passOp = dynamicState.frontStencil.passOp;
896*03ce13f7SAndroid Build Coastguard Worker }
897*03ce13f7SAndroid Build Coastguard Worker
898*03ce13f7SAndroid Build Coastguard Worker if(dynamicState.faceMask & VK_STENCIL_FACE_BACK_BIT)
899*03ce13f7SAndroid Build Coastguard Worker {
900*03ce13f7SAndroid Build Coastguard Worker backStencil.compareOp = dynamicState.backStencil.compareOp;
901*03ce13f7SAndroid Build Coastguard Worker backStencil.depthFailOp = dynamicState.backStencil.depthFailOp;
902*03ce13f7SAndroid Build Coastguard Worker backStencil.failOp = dynamicState.backStencil.failOp;
903*03ce13f7SAndroid Build Coastguard Worker backStencil.passOp = dynamicState.backStencil.passOp;
904*03ce13f7SAndroid Build Coastguard Worker }
905*03ce13f7SAndroid Build Coastguard Worker }
906*03ce13f7SAndroid Build Coastguard Worker
907*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicStencilCompareMask && stencilEnable)
908*03ce13f7SAndroid Build Coastguard Worker {
909*03ce13f7SAndroid Build Coastguard Worker frontStencil.compareMask = dynamicState.frontStencil.compareMask;
910*03ce13f7SAndroid Build Coastguard Worker backStencil.compareMask = dynamicState.backStencil.compareMask;
911*03ce13f7SAndroid Build Coastguard Worker }
912*03ce13f7SAndroid Build Coastguard Worker
913*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicStencilWriteMask && stencilEnable)
914*03ce13f7SAndroid Build Coastguard Worker {
915*03ce13f7SAndroid Build Coastguard Worker frontStencil.writeMask = dynamicState.frontStencil.writeMask;
916*03ce13f7SAndroid Build Coastguard Worker backStencil.writeMask = dynamicState.backStencil.writeMask;
917*03ce13f7SAndroid Build Coastguard Worker }
918*03ce13f7SAndroid Build Coastguard Worker
919*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicStencilReference && stencilEnable)
920*03ce13f7SAndroid Build Coastguard Worker {
921*03ce13f7SAndroid Build Coastguard Worker frontStencil.reference = dynamicState.frontStencil.reference;
922*03ce13f7SAndroid Build Coastguard Worker backStencil.reference = dynamicState.backStencil.reference;
923*03ce13f7SAndroid Build Coastguard Worker }
924*03ce13f7SAndroid Build Coastguard Worker }
925*03ce13f7SAndroid Build Coastguard Worker
depthWriteActive(const Attachments & attachments) const926*03ce13f7SAndroid Build Coastguard Worker bool FragmentState::depthWriteActive(const Attachments &attachments) const
927*03ce13f7SAndroid Build Coastguard Worker {
928*03ce13f7SAndroid Build Coastguard Worker // "Depth writes are always disabled when depthTestEnable is VK_FALSE."
929*03ce13f7SAndroid Build Coastguard Worker return depthTestActive(attachments) && depthWriteEnable;
930*03ce13f7SAndroid Build Coastguard Worker }
931*03ce13f7SAndroid Build Coastguard Worker
depthTestActive(const Attachments & attachments) const932*03ce13f7SAndroid Build Coastguard Worker bool FragmentState::depthTestActive(const Attachments &attachments) const
933*03ce13f7SAndroid Build Coastguard Worker {
934*03ce13f7SAndroid Build Coastguard Worker return attachments.depthBuffer && depthTestEnable;
935*03ce13f7SAndroid Build Coastguard Worker }
936*03ce13f7SAndroid Build Coastguard Worker
stencilActive(const Attachments & attachments) const937*03ce13f7SAndroid Build Coastguard Worker bool FragmentState::stencilActive(const Attachments &attachments) const
938*03ce13f7SAndroid Build Coastguard Worker {
939*03ce13f7SAndroid Build Coastguard Worker return attachments.stencilBuffer && stencilEnable;
940*03ce13f7SAndroid Build Coastguard Worker }
941*03ce13f7SAndroid Build Coastguard Worker
depthBoundsTestActive(const Attachments & attachments) const942*03ce13f7SAndroid Build Coastguard Worker bool FragmentState::depthBoundsTestActive(const Attachments &attachments) const
943*03ce13f7SAndroid Build Coastguard Worker {
944*03ce13f7SAndroid Build Coastguard Worker return attachments.depthBuffer && depthBoundsTestEnable;
945*03ce13f7SAndroid Build Coastguard Worker }
946*03ce13f7SAndroid Build Coastguard Worker
setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo * depthStencilState)947*03ce13f7SAndroid Build Coastguard Worker void FragmentState::setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo *depthStencilState)
948*03ce13f7SAndroid Build Coastguard Worker {
949*03ce13f7SAndroid Build Coastguard Worker if((depthStencilState->flags &
950*03ce13f7SAndroid Build Coastguard Worker ~(VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT |
951*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT)) != 0)
952*03ce13f7SAndroid Build Coastguard Worker {
953*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("depthStencilState->flags 0x%08X", int(depthStencilState->flags));
954*03ce13f7SAndroid Build Coastguard Worker }
955*03ce13f7SAndroid Build Coastguard Worker
956*03ce13f7SAndroid Build Coastguard Worker depthBoundsTestEnable = (depthStencilState->depthBoundsTestEnable != VK_FALSE);
957*03ce13f7SAndroid Build Coastguard Worker minDepthBounds = depthStencilState->minDepthBounds;
958*03ce13f7SAndroid Build Coastguard Worker maxDepthBounds = depthStencilState->maxDepthBounds;
959*03ce13f7SAndroid Build Coastguard Worker
960*03ce13f7SAndroid Build Coastguard Worker depthTestEnable = (depthStencilState->depthTestEnable != VK_FALSE);
961*03ce13f7SAndroid Build Coastguard Worker depthWriteEnable = (depthStencilState->depthWriteEnable != VK_FALSE);
962*03ce13f7SAndroid Build Coastguard Worker depthCompareMode = depthStencilState->depthCompareOp;
963*03ce13f7SAndroid Build Coastguard Worker
964*03ce13f7SAndroid Build Coastguard Worker stencilEnable = (depthStencilState->stencilTestEnable != VK_FALSE);
965*03ce13f7SAndroid Build Coastguard Worker if(stencilEnable)
966*03ce13f7SAndroid Build Coastguard Worker {
967*03ce13f7SAndroid Build Coastguard Worker frontStencil = depthStencilState->front;
968*03ce13f7SAndroid Build Coastguard Worker backStencil = depthStencilState->back;
969*03ce13f7SAndroid Build Coastguard Worker }
970*03ce13f7SAndroid Build Coastguard Worker }
971*03ce13f7SAndroid Build Coastguard Worker
initialize(const VkPipelineColorBlendStateCreateInfo * colorBlendState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const vk::RenderPass * renderPass,uint32_t subpassIndex,const VkPipelineRenderingCreateInfo * rendering,const DynamicStateFlags & allDynamicStateFlags)972*03ce13f7SAndroid Build Coastguard Worker void FragmentOutputInterfaceState::initialize(const VkPipelineColorBlendStateCreateInfo *colorBlendState,
973*03ce13f7SAndroid Build Coastguard Worker const VkPipelineMultisampleStateCreateInfo *multisampleState,
974*03ce13f7SAndroid Build Coastguard Worker const vk::RenderPass *renderPass, uint32_t subpassIndex,
975*03ce13f7SAndroid Build Coastguard Worker const VkPipelineRenderingCreateInfo *rendering,
976*03ce13f7SAndroid Build Coastguard Worker const DynamicStateFlags &allDynamicStateFlags)
977*03ce13f7SAndroid Build Coastguard Worker {
978*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags = allDynamicStateFlags.fragmentOutputInterface;
979*03ce13f7SAndroid Build Coastguard Worker
980*03ce13f7SAndroid Build Coastguard Worker multisample.set(multisampleState);
981*03ce13f7SAndroid Build Coastguard Worker
982*03ce13f7SAndroid Build Coastguard Worker if(renderPass)
983*03ce13f7SAndroid Build Coastguard Worker {
984*03ce13f7SAndroid Build Coastguard Worker const VkSubpassDescription &subpass = renderPass->getSubpass(subpassIndex);
985*03ce13f7SAndroid Build Coastguard Worker
986*03ce13f7SAndroid Build Coastguard Worker // Ignore pColorBlendState when "the subpass of the render pass the pipeline
987*03ce13f7SAndroid Build Coastguard Worker // is created against does not use any color attachments"
988*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < subpass.colorAttachmentCount; i++)
989*03ce13f7SAndroid Build Coastguard Worker {
990*03ce13f7SAndroid Build Coastguard Worker if(subpass.pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED)
991*03ce13f7SAndroid Build Coastguard Worker {
992*03ce13f7SAndroid Build Coastguard Worker setColorBlendState(colorBlendState);
993*03ce13f7SAndroid Build Coastguard Worker break;
994*03ce13f7SAndroid Build Coastguard Worker }
995*03ce13f7SAndroid Build Coastguard Worker }
996*03ce13f7SAndroid Build Coastguard Worker }
997*03ce13f7SAndroid Build Coastguard Worker else // No render pass
998*03ce13f7SAndroid Build Coastguard Worker {
999*03ce13f7SAndroid Build Coastguard Worker // When a pipeline is created without a VkRenderPass, if the VkPipelineRenderingCreateInfo structure
1000*03ce13f7SAndroid Build Coastguard Worker // is present in the pNext chain of VkGraphicsPipelineCreateInfo, it specifies the view mask and
1001*03ce13f7SAndroid Build Coastguard Worker // format of attachments used for rendering. If this structure is not specified, and the pipeline
1002*03ce13f7SAndroid Build Coastguard Worker // does not include a VkRenderPass, viewMask and colorAttachmentCount are 0, and
1003*03ce13f7SAndroid Build Coastguard Worker // depthAttachmentFormat and stencilAttachmentFormat are VK_FORMAT_UNDEFINED. If a graphics pipeline
1004*03ce13f7SAndroid Build Coastguard Worker // is created with a valid VkRenderPass, parameters of this structure are ignored.
1005*03ce13f7SAndroid Build Coastguard Worker
1006*03ce13f7SAndroid Build Coastguard Worker if(rendering)
1007*03ce13f7SAndroid Build Coastguard Worker {
1008*03ce13f7SAndroid Build Coastguard Worker if(rendering->colorAttachmentCount > 0)
1009*03ce13f7SAndroid Build Coastguard Worker {
1010*03ce13f7SAndroid Build Coastguard Worker // If renderPass is VK_NULL_HANDLE, the pipeline is being created with fragment
1011*03ce13f7SAndroid Build Coastguard Worker // output interface state, and VkPipelineRenderingCreateInfo::colorAttachmentCount
1012*03ce13f7SAndroid Build Coastguard Worker // is not equal to 0, pColorBlendState must be a valid pointer to a valid
1013*03ce13f7SAndroid Build Coastguard Worker // VkPipelineColorBlendStateCreateInfo structure
1014*03ce13f7SAndroid Build Coastguard Worker ASSERT(colorBlendState);
1015*03ce13f7SAndroid Build Coastguard Worker
1016*03ce13f7SAndroid Build Coastguard Worker setColorBlendState(colorBlendState);
1017*03ce13f7SAndroid Build Coastguard Worker }
1018*03ce13f7SAndroid Build Coastguard Worker }
1019*03ce13f7SAndroid Build Coastguard Worker }
1020*03ce13f7SAndroid Build Coastguard Worker }
1021*03ce13f7SAndroid Build Coastguard Worker
applyState(const DynamicState & dynamicState)1022*03ce13f7SAndroid Build Coastguard Worker void FragmentOutputInterfaceState::applyState(const DynamicState &dynamicState)
1023*03ce13f7SAndroid Build Coastguard Worker {
1024*03ce13f7SAndroid Build Coastguard Worker if(dynamicStateFlags.dynamicBlendConstants)
1025*03ce13f7SAndroid Build Coastguard Worker {
1026*03ce13f7SAndroid Build Coastguard Worker blendConstants = dynamicState.blendConstants;
1027*03ce13f7SAndroid Build Coastguard Worker }
1028*03ce13f7SAndroid Build Coastguard Worker }
1029*03ce13f7SAndroid Build Coastguard Worker
setColorBlendState(const VkPipelineColorBlendStateCreateInfo * colorBlendState)1030*03ce13f7SAndroid Build Coastguard Worker void FragmentOutputInterfaceState::setColorBlendState(const VkPipelineColorBlendStateCreateInfo *colorBlendState)
1031*03ce13f7SAndroid Build Coastguard Worker {
1032*03ce13f7SAndroid Build Coastguard Worker if(colorBlendState->flags != 0 &&
1033*03ce13f7SAndroid Build Coastguard Worker colorBlendState->flags != VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT)
1034*03ce13f7SAndroid Build Coastguard Worker {
1035*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("colorBlendState->flags 0x%08X", int(colorBlendState->flags));
1036*03ce13f7SAndroid Build Coastguard Worker }
1037*03ce13f7SAndroid Build Coastguard Worker
1038*03ce13f7SAndroid Build Coastguard Worker if(colorBlendState->logicOpEnable != VK_FALSE)
1039*03ce13f7SAndroid Build Coastguard Worker {
1040*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("VkPhysicalDeviceFeatures::logicOp");
1041*03ce13f7SAndroid Build Coastguard Worker }
1042*03ce13f7SAndroid Build Coastguard Worker
1043*03ce13f7SAndroid Build Coastguard Worker if(!dynamicStateFlags.dynamicBlendConstants)
1044*03ce13f7SAndroid Build Coastguard Worker {
1045*03ce13f7SAndroid Build Coastguard Worker blendConstants.x = colorBlendState->blendConstants[0];
1046*03ce13f7SAndroid Build Coastguard Worker blendConstants.y = colorBlendState->blendConstants[1];
1047*03ce13f7SAndroid Build Coastguard Worker blendConstants.z = colorBlendState->blendConstants[2];
1048*03ce13f7SAndroid Build Coastguard Worker blendConstants.w = colorBlendState->blendConstants[3];
1049*03ce13f7SAndroid Build Coastguard Worker }
1050*03ce13f7SAndroid Build Coastguard Worker
1051*03ce13f7SAndroid Build Coastguard Worker const VkBaseInStructure *extensionColorBlendInfo = reinterpret_cast<const VkBaseInStructure *>(colorBlendState->pNext);
1052*03ce13f7SAndroid Build Coastguard Worker while(extensionColorBlendInfo)
1053*03ce13f7SAndroid Build Coastguard Worker {
1054*03ce13f7SAndroid Build Coastguard Worker switch(extensionColorBlendInfo->sType)
1055*03ce13f7SAndroid Build Coastguard Worker {
1056*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT:
1057*03ce13f7SAndroid Build Coastguard Worker {
1058*03ce13f7SAndroid Build Coastguard Worker const VkPipelineColorBlendAdvancedStateCreateInfoEXT *colorBlendAdvancedCreateInfo = reinterpret_cast<const VkPipelineColorBlendAdvancedStateCreateInfoEXT *>(extensionColorBlendInfo);
1059*03ce13f7SAndroid Build Coastguard Worker ASSERT(colorBlendAdvancedCreateInfo->blendOverlap == VK_BLEND_OVERLAP_UNCORRELATED_EXT);
1060*03ce13f7SAndroid Build Coastguard Worker ASSERT(colorBlendAdvancedCreateInfo->dstPremultiplied == VK_TRUE);
1061*03ce13f7SAndroid Build Coastguard Worker ASSERT(colorBlendAdvancedCreateInfo->srcPremultiplied == VK_TRUE);
1062*03ce13f7SAndroid Build Coastguard Worker }
1063*03ce13f7SAndroid Build Coastguard Worker break;
1064*03ce13f7SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_MAX_ENUM:
1065*03ce13f7SAndroid Build Coastguard Worker // dEQP tests that this value is ignored.
1066*03ce13f7SAndroid Build Coastguard Worker break;
1067*03ce13f7SAndroid Build Coastguard Worker default:
1068*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("colorBlendState->pNext sType = %s", vk::Stringify(extensionColorBlendInfo->sType).c_str());
1069*03ce13f7SAndroid Build Coastguard Worker break;
1070*03ce13f7SAndroid Build Coastguard Worker }
1071*03ce13f7SAndroid Build Coastguard Worker
1072*03ce13f7SAndroid Build Coastguard Worker extensionColorBlendInfo = extensionColorBlendInfo->pNext;
1073*03ce13f7SAndroid Build Coastguard Worker }
1074*03ce13f7SAndroid Build Coastguard Worker
1075*03ce13f7SAndroid Build Coastguard Worker ASSERT(colorBlendState->attachmentCount <= sw::MAX_COLOR_BUFFERS);
1076*03ce13f7SAndroid Build Coastguard Worker for(auto i = 0u; i < colorBlendState->attachmentCount; i++)
1077*03ce13f7SAndroid Build Coastguard Worker {
1078*03ce13f7SAndroid Build Coastguard Worker const VkPipelineColorBlendAttachmentState &attachment = colorBlendState->pAttachments[i];
1079*03ce13f7SAndroid Build Coastguard Worker colorWriteMask[i] = attachment.colorWriteMask;
1080*03ce13f7SAndroid Build Coastguard Worker blendState[i] = { (attachment.blendEnable != VK_FALSE),
1081*03ce13f7SAndroid Build Coastguard Worker attachment.srcColorBlendFactor, attachment.dstColorBlendFactor, attachment.colorBlendOp,
1082*03ce13f7SAndroid Build Coastguard Worker attachment.srcAlphaBlendFactor, attachment.dstAlphaBlendFactor, attachment.alphaBlendOp };
1083*03ce13f7SAndroid Build Coastguard Worker }
1084*03ce13f7SAndroid Build Coastguard Worker }
1085*03ce13f7SAndroid Build Coastguard Worker
getBlendState(int location,const Attachments & attachments,bool fragmentContainsKill) const1086*03ce13f7SAndroid Build Coastguard Worker BlendState FragmentOutputInterfaceState::getBlendState(int location, const Attachments &attachments, bool fragmentContainsKill) const
1087*03ce13f7SAndroid Build Coastguard Worker {
1088*03ce13f7SAndroid Build Coastguard Worker ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));
1089*03ce13f7SAndroid Build Coastguard Worker const uint32_t index = attachments.locationToIndex[location];
1090*03ce13f7SAndroid Build Coastguard Worker if(index == VK_ATTACHMENT_UNUSED)
1091*03ce13f7SAndroid Build Coastguard Worker {
1092*03ce13f7SAndroid Build Coastguard Worker return {};
1093*03ce13f7SAndroid Build Coastguard Worker }
1094*03ce13f7SAndroid Build Coastguard Worker
1095*03ce13f7SAndroid Build Coastguard Worker ASSERT((index >= 0) && (index < sw::MAX_COLOR_BUFFERS));
1096*03ce13f7SAndroid Build Coastguard Worker auto &state = blendState[index];
1097*03ce13f7SAndroid Build Coastguard Worker
1098*03ce13f7SAndroid Build Coastguard Worker BlendState activeBlendState = {};
1099*03ce13f7SAndroid Build Coastguard Worker activeBlendState.alphaBlendEnable = alphaBlendActive(location, attachments, fragmentContainsKill);
1100*03ce13f7SAndroid Build Coastguard Worker
1101*03ce13f7SAndroid Build Coastguard Worker if(activeBlendState.alphaBlendEnable)
1102*03ce13f7SAndroid Build Coastguard Worker {
1103*03ce13f7SAndroid Build Coastguard Worker vk::Format format = attachments.colorBuffer[location]->getFormat(VK_IMAGE_ASPECT_COLOR_BIT);
1104*03ce13f7SAndroid Build Coastguard Worker
1105*03ce13f7SAndroid Build Coastguard Worker activeBlendState.sourceBlendFactor = blendFactor(state.blendOperation, state.sourceBlendFactor);
1106*03ce13f7SAndroid Build Coastguard Worker activeBlendState.destBlendFactor = blendFactor(state.blendOperation, state.destBlendFactor);
1107*03ce13f7SAndroid Build Coastguard Worker activeBlendState.blendOperation = blendOperation(state.blendOperation, state.sourceBlendFactor, state.destBlendFactor, format);
1108*03ce13f7SAndroid Build Coastguard Worker activeBlendState.sourceBlendFactorAlpha = blendFactor(state.blendOperationAlpha, state.sourceBlendFactorAlpha);
1109*03ce13f7SAndroid Build Coastguard Worker activeBlendState.destBlendFactorAlpha = blendFactor(state.blendOperationAlpha, state.destBlendFactorAlpha);
1110*03ce13f7SAndroid Build Coastguard Worker activeBlendState.blendOperationAlpha = blendOperation(state.blendOperationAlpha, state.sourceBlendFactorAlpha, state.destBlendFactorAlpha, format);
1111*03ce13f7SAndroid Build Coastguard Worker }
1112*03ce13f7SAndroid Build Coastguard Worker
1113*03ce13f7SAndroid Build Coastguard Worker return activeBlendState;
1114*03ce13f7SAndroid Build Coastguard Worker }
1115*03ce13f7SAndroid Build Coastguard Worker
alphaBlendActive(int location,const Attachments & attachments,bool fragmentContainsKill) const1116*03ce13f7SAndroid Build Coastguard Worker bool FragmentOutputInterfaceState::alphaBlendActive(int location, const Attachments &attachments, bool fragmentContainsKill) const
1117*03ce13f7SAndroid Build Coastguard Worker {
1118*03ce13f7SAndroid Build Coastguard Worker ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));
1119*03ce13f7SAndroid Build Coastguard Worker const uint32_t index = attachments.locationToIndex[location];
1120*03ce13f7SAndroid Build Coastguard Worker if(index == VK_ATTACHMENT_UNUSED)
1121*03ce13f7SAndroid Build Coastguard Worker {
1122*03ce13f7SAndroid Build Coastguard Worker return false;
1123*03ce13f7SAndroid Build Coastguard Worker }
1124*03ce13f7SAndroid Build Coastguard Worker
1125*03ce13f7SAndroid Build Coastguard Worker ASSERT((index >= 0) && (index < sw::MAX_COLOR_BUFFERS));
1126*03ce13f7SAndroid Build Coastguard Worker auto &state = blendState[index];
1127*03ce13f7SAndroid Build Coastguard Worker
1128*03ce13f7SAndroid Build Coastguard Worker if(!attachments.colorBuffer[location] || !blendState[index].alphaBlendEnable)
1129*03ce13f7SAndroid Build Coastguard Worker {
1130*03ce13f7SAndroid Build Coastguard Worker return false;
1131*03ce13f7SAndroid Build Coastguard Worker }
1132*03ce13f7SAndroid Build Coastguard Worker
1133*03ce13f7SAndroid Build Coastguard Worker if(!(colorWriteActive(attachments) || fragmentContainsKill))
1134*03ce13f7SAndroid Build Coastguard Worker {
1135*03ce13f7SAndroid Build Coastguard Worker return false;
1136*03ce13f7SAndroid Build Coastguard Worker }
1137*03ce13f7SAndroid Build Coastguard Worker
1138*03ce13f7SAndroid Build Coastguard Worker vk::Format format = attachments.colorBuffer[location]->getFormat(VK_IMAGE_ASPECT_COLOR_BIT);
1139*03ce13f7SAndroid Build Coastguard Worker bool colorBlend = blendOperation(state.blendOperation, state.sourceBlendFactor, state.destBlendFactor, format) != VK_BLEND_OP_SRC_EXT;
1140*03ce13f7SAndroid Build Coastguard Worker bool alphaBlend = blendOperation(state.blendOperationAlpha, state.sourceBlendFactorAlpha, state.destBlendFactorAlpha, format) != VK_BLEND_OP_SRC_EXT;
1141*03ce13f7SAndroid Build Coastguard Worker
1142*03ce13f7SAndroid Build Coastguard Worker return colorBlend || alphaBlend;
1143*03ce13f7SAndroid Build Coastguard Worker }
1144*03ce13f7SAndroid Build Coastguard Worker
blendFactor(VkBlendOp blendOperation,VkBlendFactor blendFactor) const1145*03ce13f7SAndroid Build Coastguard Worker VkBlendFactor FragmentOutputInterfaceState::blendFactor(VkBlendOp blendOperation, VkBlendFactor blendFactor) const
1146*03ce13f7SAndroid Build Coastguard Worker {
1147*03ce13f7SAndroid Build Coastguard Worker switch(blendOperation)
1148*03ce13f7SAndroid Build Coastguard Worker {
1149*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_ADD:
1150*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_SUBTRACT:
1151*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_REVERSE_SUBTRACT:
1152*03ce13f7SAndroid Build Coastguard Worker return blendFactor;
1153*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_MIN:
1154*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_MAX:
1155*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_MULTIPLY_EXT:
1156*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_SCREEN_EXT:
1157*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_OVERLAY_EXT:
1158*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_DARKEN_EXT:
1159*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_LIGHTEN_EXT:
1160*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_COLORDODGE_EXT:
1161*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_COLORBURN_EXT:
1162*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HARDLIGHT_EXT:
1163*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_SOFTLIGHT_EXT:
1164*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_DIFFERENCE_EXT:
1165*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_EXCLUSION_EXT:
1166*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_HUE_EXT:
1167*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_SATURATION_EXT:
1168*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_COLOR_EXT:
1169*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
1170*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_FACTOR_ONE;
1171*03ce13f7SAndroid Build Coastguard Worker default:
1172*03ce13f7SAndroid Build Coastguard Worker ASSERT(false);
1173*03ce13f7SAndroid Build Coastguard Worker return blendFactor;
1174*03ce13f7SAndroid Build Coastguard Worker }
1175*03ce13f7SAndroid Build Coastguard Worker }
1176*03ce13f7SAndroid Build Coastguard Worker
blendOperation(VkBlendOp blendOperation,VkBlendFactor sourceBlendFactor,VkBlendFactor destBlendFactor,vk::Format format) const1177*03ce13f7SAndroid Build Coastguard Worker VkBlendOp FragmentOutputInterfaceState::blendOperation(VkBlendOp blendOperation, VkBlendFactor sourceBlendFactor, VkBlendFactor destBlendFactor, vk::Format format) const
1178*03ce13f7SAndroid Build Coastguard Worker {
1179*03ce13f7SAndroid Build Coastguard Worker switch(blendOperation)
1180*03ce13f7SAndroid Build Coastguard Worker {
1181*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_ADD:
1182*03ce13f7SAndroid Build Coastguard Worker if(sourceBlendFactor == VK_BLEND_FACTOR_ZERO)
1183*03ce13f7SAndroid Build Coastguard Worker {
1184*03ce13f7SAndroid Build Coastguard Worker if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
1185*03ce13f7SAndroid Build Coastguard Worker {
1186*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_ZERO_EXT;
1187*03ce13f7SAndroid Build Coastguard Worker }
1188*03ce13f7SAndroid Build Coastguard Worker else if(destBlendFactor == VK_BLEND_FACTOR_ONE)
1189*03ce13f7SAndroid Build Coastguard Worker {
1190*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_DST_EXT;
1191*03ce13f7SAndroid Build Coastguard Worker }
1192*03ce13f7SAndroid Build Coastguard Worker }
1193*03ce13f7SAndroid Build Coastguard Worker else if(sourceBlendFactor == VK_BLEND_FACTOR_ONE)
1194*03ce13f7SAndroid Build Coastguard Worker {
1195*03ce13f7SAndroid Build Coastguard Worker if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
1196*03ce13f7SAndroid Build Coastguard Worker {
1197*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_SRC_EXT;
1198*03ce13f7SAndroid Build Coastguard Worker }
1199*03ce13f7SAndroid Build Coastguard Worker }
1200*03ce13f7SAndroid Build Coastguard Worker break;
1201*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_SUBTRACT:
1202*03ce13f7SAndroid Build Coastguard Worker if(sourceBlendFactor == VK_BLEND_FACTOR_ZERO)
1203*03ce13f7SAndroid Build Coastguard Worker {
1204*03ce13f7SAndroid Build Coastguard Worker if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
1205*03ce13f7SAndroid Build Coastguard Worker {
1206*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_ZERO_EXT;
1207*03ce13f7SAndroid Build Coastguard Worker }
1208*03ce13f7SAndroid Build Coastguard Worker else if(format.isUnsignedNormalized())
1209*03ce13f7SAndroid Build Coastguard Worker {
1210*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
1211*03ce13f7SAndroid Build Coastguard Worker }
1212*03ce13f7SAndroid Build Coastguard Worker }
1213*03ce13f7SAndroid Build Coastguard Worker else if(sourceBlendFactor == VK_BLEND_FACTOR_ONE)
1214*03ce13f7SAndroid Build Coastguard Worker {
1215*03ce13f7SAndroid Build Coastguard Worker if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
1216*03ce13f7SAndroid Build Coastguard Worker {
1217*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_SRC_EXT;
1218*03ce13f7SAndroid Build Coastguard Worker }
1219*03ce13f7SAndroid Build Coastguard Worker }
1220*03ce13f7SAndroid Build Coastguard Worker break;
1221*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_REVERSE_SUBTRACT:
1222*03ce13f7SAndroid Build Coastguard Worker if(sourceBlendFactor == VK_BLEND_FACTOR_ZERO)
1223*03ce13f7SAndroid Build Coastguard Worker {
1224*03ce13f7SAndroid Build Coastguard Worker if(destBlendFactor == VK_BLEND_FACTOR_ZERO)
1225*03ce13f7SAndroid Build Coastguard Worker {
1226*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_ZERO_EXT;
1227*03ce13f7SAndroid Build Coastguard Worker }
1228*03ce13f7SAndroid Build Coastguard Worker else if(destBlendFactor == VK_BLEND_FACTOR_ONE)
1229*03ce13f7SAndroid Build Coastguard Worker {
1230*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_DST_EXT;
1231*03ce13f7SAndroid Build Coastguard Worker }
1232*03ce13f7SAndroid Build Coastguard Worker }
1233*03ce13f7SAndroid Build Coastguard Worker else
1234*03ce13f7SAndroid Build Coastguard Worker {
1235*03ce13f7SAndroid Build Coastguard Worker if(destBlendFactor == VK_BLEND_FACTOR_ZERO && format.isUnsignedNormalized())
1236*03ce13f7SAndroid Build Coastguard Worker {
1237*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_ZERO_EXT; // Negative, clamped to zero
1238*03ce13f7SAndroid Build Coastguard Worker }
1239*03ce13f7SAndroid Build Coastguard Worker }
1240*03ce13f7SAndroid Build Coastguard Worker break;
1241*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_MIN:
1242*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_MIN;
1243*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_MAX:
1244*03ce13f7SAndroid Build Coastguard Worker return VK_BLEND_OP_MAX;
1245*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_MULTIPLY_EXT:
1246*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_SCREEN_EXT:
1247*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_OVERLAY_EXT:
1248*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_DARKEN_EXT:
1249*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_LIGHTEN_EXT:
1250*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_COLORDODGE_EXT:
1251*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_COLORBURN_EXT:
1252*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HARDLIGHT_EXT:
1253*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_SOFTLIGHT_EXT:
1254*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_DIFFERENCE_EXT:
1255*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_EXCLUSION_EXT:
1256*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_HUE_EXT:
1257*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_SATURATION_EXT:
1258*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_COLOR_EXT:
1259*03ce13f7SAndroid Build Coastguard Worker case VK_BLEND_OP_HSL_LUMINOSITY_EXT:
1260*03ce13f7SAndroid Build Coastguard Worker return blendOperation;
1261*03ce13f7SAndroid Build Coastguard Worker default:
1262*03ce13f7SAndroid Build Coastguard Worker ASSERT(false);
1263*03ce13f7SAndroid Build Coastguard Worker }
1264*03ce13f7SAndroid Build Coastguard Worker
1265*03ce13f7SAndroid Build Coastguard Worker return blendOperation;
1266*03ce13f7SAndroid Build Coastguard Worker }
1267*03ce13f7SAndroid Build Coastguard Worker
colorWriteActive(const Attachments & attachments) const1268*03ce13f7SAndroid Build Coastguard Worker bool FragmentOutputInterfaceState::colorWriteActive(const Attachments &attachments) const
1269*03ce13f7SAndroid Build Coastguard Worker {
1270*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < sw::MAX_COLOR_BUFFERS; i++)
1271*03ce13f7SAndroid Build Coastguard Worker {
1272*03ce13f7SAndroid Build Coastguard Worker if(colorWriteActive(i, attachments))
1273*03ce13f7SAndroid Build Coastguard Worker {
1274*03ce13f7SAndroid Build Coastguard Worker return true;
1275*03ce13f7SAndroid Build Coastguard Worker }
1276*03ce13f7SAndroid Build Coastguard Worker }
1277*03ce13f7SAndroid Build Coastguard Worker
1278*03ce13f7SAndroid Build Coastguard Worker return false;
1279*03ce13f7SAndroid Build Coastguard Worker }
1280*03ce13f7SAndroid Build Coastguard Worker
colorWriteActive(int location,const Attachments & attachments) const1281*03ce13f7SAndroid Build Coastguard Worker int FragmentOutputInterfaceState::colorWriteActive(int location, const Attachments &attachments) const
1282*03ce13f7SAndroid Build Coastguard Worker {
1283*03ce13f7SAndroid Build Coastguard Worker ASSERT((location >= 0) && (location < sw::MAX_COLOR_BUFFERS));
1284*03ce13f7SAndroid Build Coastguard Worker const uint32_t index = attachments.locationToIndex[location];
1285*03ce13f7SAndroid Build Coastguard Worker if(index == VK_ATTACHMENT_UNUSED)
1286*03ce13f7SAndroid Build Coastguard Worker {
1287*03ce13f7SAndroid Build Coastguard Worker return 0;
1288*03ce13f7SAndroid Build Coastguard Worker }
1289*03ce13f7SAndroid Build Coastguard Worker
1290*03ce13f7SAndroid Build Coastguard Worker ASSERT((index >= 0) && (index < sw::MAX_COLOR_BUFFERS));
1291*03ce13f7SAndroid Build Coastguard Worker auto &state = blendState[index];
1292*03ce13f7SAndroid Build Coastguard Worker
1293*03ce13f7SAndroid Build Coastguard Worker if(!attachments.colorBuffer[location] || attachments.colorBuffer[location]->getFormat() == VK_FORMAT_UNDEFINED)
1294*03ce13f7SAndroid Build Coastguard Worker {
1295*03ce13f7SAndroid Build Coastguard Worker return 0;
1296*03ce13f7SAndroid Build Coastguard Worker }
1297*03ce13f7SAndroid Build Coastguard Worker
1298*03ce13f7SAndroid Build Coastguard Worker vk::Format format = attachments.colorBuffer[location]->getFormat(VK_IMAGE_ASPECT_COLOR_BIT);
1299*03ce13f7SAndroid Build Coastguard Worker
1300*03ce13f7SAndroid Build Coastguard Worker if(blendOperation(state.blendOperation, state.sourceBlendFactor, state.destBlendFactor, format) == VK_BLEND_OP_DST_EXT &&
1301*03ce13f7SAndroid Build Coastguard Worker blendOperation(state.blendOperationAlpha, state.sourceBlendFactorAlpha, state.destBlendFactorAlpha, format) == VK_BLEND_OP_DST_EXT)
1302*03ce13f7SAndroid Build Coastguard Worker {
1303*03ce13f7SAndroid Build Coastguard Worker return 0;
1304*03ce13f7SAndroid Build Coastguard Worker }
1305*03ce13f7SAndroid Build Coastguard Worker
1306*03ce13f7SAndroid Build Coastguard Worker return colorWriteMask[index];
1307*03ce13f7SAndroid Build Coastguard Worker }
1308*03ce13f7SAndroid Build Coastguard Worker
GraphicsState(const Device * device,const VkGraphicsPipelineCreateInfo * pCreateInfo,const PipelineLayout * layout)1309*03ce13f7SAndroid Build Coastguard Worker GraphicsState::GraphicsState(const Device *device, const VkGraphicsPipelineCreateInfo *pCreateInfo,
1310*03ce13f7SAndroid Build Coastguard Worker const PipelineLayout *layout)
1311*03ce13f7SAndroid Build Coastguard Worker {
1312*03ce13f7SAndroid Build Coastguard Worker if((pCreateInfo->flags &
1313*03ce13f7SAndroid Build Coastguard Worker ~(VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT |
1314*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_DERIVATIVE_BIT |
1315*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT |
1316*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT |
1317*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT |
1318*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_LIBRARY_BIT_KHR |
1319*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT |
1320*03ce13f7SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT)) != 0)
1321*03ce13f7SAndroid Build Coastguard Worker {
1322*03ce13f7SAndroid Build Coastguard Worker UNSUPPORTED("pCreateInfo->flags 0x%08X", int(pCreateInfo->flags));
1323*03ce13f7SAndroid Build Coastguard Worker }
1324*03ce13f7SAndroid Build Coastguard Worker
1325*03ce13f7SAndroid Build Coastguard Worker DynamicStateFlags dynamicStateFlags = ParseDynamicStateFlags(pCreateInfo->pDynamicState);
1326*03ce13f7SAndroid Build Coastguard Worker const auto *rendering = GetExtendedStruct<VkPipelineRenderingCreateInfo>(pCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO);
1327*03ce13f7SAndroid Build Coastguard Worker
1328*03ce13f7SAndroid Build Coastguard Worker // First, get the subset of state specified in pCreateInfo itself.
1329*03ce13f7SAndroid Build Coastguard Worker validSubset = GraphicsPipeline::GetGraphicsPipelineSubset(pCreateInfo);
1330*03ce13f7SAndroid Build Coastguard Worker
1331*03ce13f7SAndroid Build Coastguard Worker // If rasterizer discard is enabled (and not dynamically overridable), ignore the fragment
1332*03ce13f7SAndroid Build Coastguard Worker // and fragment output subsets, as they will not be used.
1333*03ce13f7SAndroid Build Coastguard Worker if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) != 0 &&
1334*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->pRasterizationState->rasterizerDiscardEnable &&
1335*03ce13f7SAndroid Build Coastguard Worker !dynamicStateFlags.preRasterization.dynamicRasterizerDiscardEnable)
1336*03ce13f7SAndroid Build Coastguard Worker {
1337*03ce13f7SAndroid Build Coastguard Worker validSubset &= ~(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
1338*03ce13f7SAndroid Build Coastguard Worker }
1339*03ce13f7SAndroid Build Coastguard Worker
1340*03ce13f7SAndroid Build Coastguard Worker if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) != 0)
1341*03ce13f7SAndroid Build Coastguard Worker {
1342*03ce13f7SAndroid Build Coastguard Worker vertexInputInterfaceState.initialize(pCreateInfo->pVertexInputState,
1343*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->pInputAssemblyState,
1344*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags);
1345*03ce13f7SAndroid Build Coastguard Worker }
1346*03ce13f7SAndroid Build Coastguard Worker if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) != 0)
1347*03ce13f7SAndroid Build Coastguard Worker {
1348*03ce13f7SAndroid Build Coastguard Worker preRasterizationState.initialize(device,
1349*03ce13f7SAndroid Build Coastguard Worker layout,
1350*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->pViewportState,
1351*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->pRasterizationState,
1352*03ce13f7SAndroid Build Coastguard Worker vk::Cast(pCreateInfo->renderPass),
1353*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->subpass,
1354*03ce13f7SAndroid Build Coastguard Worker rendering,
1355*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags);
1356*03ce13f7SAndroid Build Coastguard Worker }
1357*03ce13f7SAndroid Build Coastguard Worker if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) != 0)
1358*03ce13f7SAndroid Build Coastguard Worker {
1359*03ce13f7SAndroid Build Coastguard Worker fragmentState.initialize(layout,
1360*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->pDepthStencilState,
1361*03ce13f7SAndroid Build Coastguard Worker vk::Cast(pCreateInfo->renderPass),
1362*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->subpass,
1363*03ce13f7SAndroid Build Coastguard Worker rendering,
1364*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags);
1365*03ce13f7SAndroid Build Coastguard Worker }
1366*03ce13f7SAndroid Build Coastguard Worker if((validSubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) != 0)
1367*03ce13f7SAndroid Build Coastguard Worker {
1368*03ce13f7SAndroid Build Coastguard Worker fragmentOutputInterfaceState.initialize(pCreateInfo->pColorBlendState,
1369*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->pMultisampleState,
1370*03ce13f7SAndroid Build Coastguard Worker vk::Cast(pCreateInfo->renderPass),
1371*03ce13f7SAndroid Build Coastguard Worker pCreateInfo->subpass,
1372*03ce13f7SAndroid Build Coastguard Worker rendering,
1373*03ce13f7SAndroid Build Coastguard Worker dynamicStateFlags);
1374*03ce13f7SAndroid Build Coastguard Worker }
1375*03ce13f7SAndroid Build Coastguard Worker
1376*03ce13f7SAndroid Build Coastguard Worker // Then, apply state coming from pipeline libraries.
1377*03ce13f7SAndroid Build Coastguard Worker const auto *libraryCreateInfo = vk::GetExtendedStruct<VkPipelineLibraryCreateInfoKHR>(pCreateInfo->pNext, VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR);
1378*03ce13f7SAndroid Build Coastguard Worker if(libraryCreateInfo)
1379*03ce13f7SAndroid Build Coastguard Worker {
1380*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < libraryCreateInfo->libraryCount; ++i)
1381*03ce13f7SAndroid Build Coastguard Worker {
1382*03ce13f7SAndroid Build Coastguard Worker const auto *library = static_cast<const GraphicsPipeline *>(vk::Cast(libraryCreateInfo->pLibraries[i]));
1383*03ce13f7SAndroid Build Coastguard Worker const GraphicsState &libraryState = library->getState();
1384*03ce13f7SAndroid Build Coastguard Worker const VkGraphicsPipelineLibraryFlagsEXT librarySubset = libraryState.validSubset;
1385*03ce13f7SAndroid Build Coastguard Worker
1386*03ce13f7SAndroid Build Coastguard Worker // The library subsets should be disjoint
1387*03ce13f7SAndroid Build Coastguard Worker ASSERT((libraryState.validSubset & validSubset) == 0);
1388*03ce13f7SAndroid Build Coastguard Worker
1389*03ce13f7SAndroid Build Coastguard Worker if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) != 0)
1390*03ce13f7SAndroid Build Coastguard Worker {
1391*03ce13f7SAndroid Build Coastguard Worker vertexInputInterfaceState = libraryState.vertexInputInterfaceState;
1392*03ce13f7SAndroid Build Coastguard Worker }
1393*03ce13f7SAndroid Build Coastguard Worker if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) != 0)
1394*03ce13f7SAndroid Build Coastguard Worker {
1395*03ce13f7SAndroid Build Coastguard Worker preRasterizationState = libraryState.preRasterizationState;
1396*03ce13f7SAndroid Build Coastguard Worker if(layout)
1397*03ce13f7SAndroid Build Coastguard Worker {
1398*03ce13f7SAndroid Build Coastguard Worker preRasterizationState.overridePipelineLayout(layout);
1399*03ce13f7SAndroid Build Coastguard Worker }
1400*03ce13f7SAndroid Build Coastguard Worker }
1401*03ce13f7SAndroid Build Coastguard Worker if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) != 0)
1402*03ce13f7SAndroid Build Coastguard Worker {
1403*03ce13f7SAndroid Build Coastguard Worker fragmentState = libraryState.fragmentState;
1404*03ce13f7SAndroid Build Coastguard Worker if(layout)
1405*03ce13f7SAndroid Build Coastguard Worker {
1406*03ce13f7SAndroid Build Coastguard Worker fragmentState.overridePipelineLayout(layout);
1407*03ce13f7SAndroid Build Coastguard Worker }
1408*03ce13f7SAndroid Build Coastguard Worker }
1409*03ce13f7SAndroid Build Coastguard Worker if((librarySubset & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) != 0)
1410*03ce13f7SAndroid Build Coastguard Worker {
1411*03ce13f7SAndroid Build Coastguard Worker fragmentOutputInterfaceState = libraryState.fragmentOutputInterfaceState;
1412*03ce13f7SAndroid Build Coastguard Worker }
1413*03ce13f7SAndroid Build Coastguard Worker
1414*03ce13f7SAndroid Build Coastguard Worker validSubset |= libraryState.validSubset;
1415*03ce13f7SAndroid Build Coastguard Worker }
1416*03ce13f7SAndroid Build Coastguard Worker }
1417*03ce13f7SAndroid Build Coastguard Worker }
1418*03ce13f7SAndroid Build Coastguard Worker
combineStates(const DynamicState & dynamicState) const1419*03ce13f7SAndroid Build Coastguard Worker GraphicsState GraphicsState::combineStates(const DynamicState &dynamicState) const
1420*03ce13f7SAndroid Build Coastguard Worker {
1421*03ce13f7SAndroid Build Coastguard Worker GraphicsState combinedState = *this;
1422*03ce13f7SAndroid Build Coastguard Worker
1423*03ce13f7SAndroid Build Coastguard Worker // Make a copy of the states for modification, then either keep the pipeline state or apply the dynamic state.
1424*03ce13f7SAndroid Build Coastguard Worker combinedState.vertexInputInterfaceState.applyState(dynamicState);
1425*03ce13f7SAndroid Build Coastguard Worker combinedState.preRasterizationState.applyState(dynamicState);
1426*03ce13f7SAndroid Build Coastguard Worker combinedState.fragmentState.applyState(dynamicState);
1427*03ce13f7SAndroid Build Coastguard Worker combinedState.fragmentOutputInterfaceState.applyState(dynamicState);
1428*03ce13f7SAndroid Build Coastguard Worker
1429*03ce13f7SAndroid Build Coastguard Worker return combinedState;
1430*03ce13f7SAndroid Build Coastguard Worker }
1431*03ce13f7SAndroid Build Coastguard Worker
1432*03ce13f7SAndroid Build Coastguard Worker } // namespace vk
1433