blob: de2758fb77053cae591bb9d927a4d57e63aa7666 [file] [log] [blame]
Nicolas Capens68a82382018-10-02 13:16:55 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "PixelProgram.hpp"
16
17#include "SamplerCore.hpp"
Nicolas Capens1d8c8db2018-11-05 16:30:42 -050018#include "Device/Primitive.hpp"
19#include "Device/Renderer.hpp"
Nicolas Capens68a82382018-10-02 13:16:55 -040020
21namespace sw
22{
23 extern bool postBlendSRGB;
Nicolas Capens68a82382018-10-02 13:16:55 -040024
25 void PixelProgram::setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w)
26 {
Chris Forbes24466042019-04-22 10:54:23 -070027 routine.windowSpacePosition[0] = x + SIMD::Int(0,1,0,1);
28 routine.windowSpacePosition[1] = y + SIMD::Int(0,0,1,1);
29
Chris Forbes91cf5ad2019-04-15 19:02:12 -070030 auto it = spirvShader->inputBuiltins.find(spv::BuiltInFragCoord);
31 if (it != spirvShader->inputBuiltins.end())
32 {
33 auto &var = routine.getVariable(it->second.Id);
34 var[it->second.FirstComponent] = SIMD::Float(Float(x)) + SIMD::Float(0.5f, 1.5f, 0.5f, 1.5f);
35 var[it->second.FirstComponent+1] = SIMD::Float(Float(y)) + SIMD::Float(0.5f, 0.5f, 1.5f, 1.5f);
36 var[it->second.FirstComponent+2] = z[0]; // sample 0
37 var[it->second.FirstComponent+3] = w;
38 }
Chris Forbes84c3a942019-04-16 09:48:00 -070039
40 it = spirvShader->inputBuiltins.find(spv::BuiltInSubgroupSize);
41 if (it != spirvShader->inputBuiltins.end())
42 {
43 ASSERT(it->second.SizeInComponents == 1);
Chris Forbes793050e2019-04-27 14:48:09 -070044 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<SIMD::Float>(SIMD::Int(SIMD::Width));
Chris Forbes84c3a942019-04-16 09:48:00 -070045 }
46
47 it = spirvShader->inputBuiltins.find(spv::BuiltInSubgroupLocalInvocationId);
48 if (it != spirvShader->inputBuiltins.end())
49 {
50 ASSERT(it->second.SizeInComponents == 1);
51 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 1, 2, 3));
52 }
Ben Clayton2cd983d2019-05-10 11:30:09 +010053
54 it = spirvShader->inputBuiltins.find(spv::BuiltInDeviceIndex);
55 if (it != spirvShader->inputBuiltins.end())
56 {
57 ASSERT(it->second.SizeInComponents == 1);
58 // Only a single physical device is supported.
59 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
60 }
Nicolas Capens68a82382018-10-02 13:16:55 -040061 }
62
63 void PixelProgram::applyShader(Int cMask[4])
64 {
Ben Clayton225a1302019-04-02 12:28:22 +010065 routine.descriptorSets = data + OFFSET(DrawData, descriptorSets);
66 routine.descriptorDynamicOffsets = data + OFFSET(DrawData, descriptorDynamicOffsets);
Chris Forbesa30de542019-03-18 18:51:55 -070067 routine.pushConstants = data + OFFSET(DrawData, pushConstants);
Chris Forbes548e3662019-04-25 10:00:06 -070068 routine.constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, constants));
Chris Forbesa30de542019-03-18 18:51:55 -070069
Chris Forbes25be5bb2019-04-15 15:20:27 -070070 auto it = spirvShader->inputBuiltins.find(spv::BuiltInFrontFacing);
71 if (it != spirvShader->inputBuiltins.end())
72 {
73 ASSERT(it->second.SizeInComponents == 1);
74 auto frontFacing = Int4(*Pointer<Int>(primitive + OFFSET(Primitive, clockwiseMask)));
75 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<Float4>(frontFacing);
76 }
77
Chris Forbes2e043582019-05-01 08:20:01 -070078 // Note: all lanes initially active to facilitate derivatives etc. Actual coverage is
79 // handled separately, through the cMask.
80 auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
81 routine.killMask = 0;
82
Nicolas Capens09591b82019-04-08 22:51:08 -040083 spirvShader->emit(&routine, activeLaneMask, descriptorSets);
Chris Forbesc61271e2019-02-19 17:01:28 -080084 spirvShader->emitEpilog(&routine);
Chris Forbes1845d5e2018-12-27 11:50:15 -080085
86 for(int i = 0; i < RENDERTARGETS; i++)
Nicolas Capens68a82382018-10-02 13:16:55 -040087 {
Chris Forbesc1fd4082019-02-19 17:19:48 -080088 c[i].x = routine.outputs[i * 4];
89 c[i].y = routine.outputs[i * 4 + 1];
90 c[i].z = routine.outputs[i * 4 + 2];
91 c[i].w = routine.outputs[i * 4 + 3];
Nicolas Capens68a82382018-10-02 13:16:55 -040092 }
93
94 clampColor(c);
95
Chris Forbes97e95892019-04-02 13:37:37 +130096 if(spirvShader->getModes().ContainsKill)
97 {
98 for (auto i = 0u; i < state.multiSample; i++)
99 {
100 cMask[i] &= ~routine.killMask;
101 }
102 }
103
Chris Forbes583f6422019-05-03 15:08:21 -0700104 it = spirvShader->outputBuiltins.find(spv::BuiltInSampleMask);
105 if (it != spirvShader->outputBuiltins.end())
106 {
107 auto outputSampleMask = As<SIMD::Int>(routine.getVariable(it->second.Id)[it->second.FirstComponent]);
108
109 for (auto i = 0u; i < state.multiSample; i++)
110 {
111 cMask[i] &= SignMask(CmpNEQ(outputSampleMask & SIMD::Int(1<<i), SIMD::Int(0)));
112 }
113 }
114
Chris Forbes72881512019-04-15 19:51:26 -0700115 it = spirvShader->outputBuiltins.find(spv::BuiltInFragDepth);
116 if (it != spirvShader->outputBuiltins.end())
117 {
Chris Forbes390d8462019-04-26 10:48:36 -0700118 oDepth = Min(Max(routine.getVariable(it->second.Id)[it->second.FirstComponent], Float4(0.0f)), Float4(1.0f));
Nicolas Capens68a82382018-10-02 13:16:55 -0400119 }
120 }
121
122 Bool PixelProgram::alphaTest(Int cMask[4])
123 {
Chris Forbeseae5b962019-04-19 17:01:10 -0700124 if(!state.alphaToCoverage)
Nicolas Capens68a82382018-10-02 13:16:55 -0400125 {
126 return true;
127 }
128
Chris Forbeseae5b962019-04-19 17:01:10 -0700129 alphaToCoverage(cMask, c[0].w);
Nicolas Capens68a82382018-10-02 13:16:55 -0400130
131 Int pass = cMask[0];
132
133 for(unsigned int q = 1; q < state.multiSample; q++)
134 {
135 pass = pass | cMask[q];
136 }
137
138 return pass != 0x0;
139 }
140
Chris Forbese7579262019-02-10 19:21:59 +0000141 void PixelProgram::rasterOperation(Pointer<Byte> cBuffer[4], Int &x, Int sMask[4], Int zMask[4], Int cMask[4])
Nicolas Capens68a82382018-10-02 13:16:55 -0400142 {
143 for(int index = 0; index < RENDERTARGETS; index++)
144 {
145 if(!state.colorWriteActive(index))
146 {
147 continue;
148 }
149
Ben Clayton3d7b7ea2019-05-14 16:49:58 +0100150 auto format = state.targetFormat[index];
151 switch(format)
Nicolas Capens68a82382018-10-02 13:16:55 -0400152 {
Alexis Hetudd152e12018-11-14 13:39:28 -0500153 case VK_FORMAT_R5G6B5_UNORM_PACK16:
154 case VK_FORMAT_B8G8R8A8_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700155 case VK_FORMAT_B8G8R8A8_SRGB:
Alexis Hetudd152e12018-11-14 13:39:28 -0500156 case VK_FORMAT_R8G8B8A8_UNORM:
157 case VK_FORMAT_R8G8B8A8_SRGB:
158 case VK_FORMAT_R8G8_UNORM:
159 case VK_FORMAT_R8_UNORM:
160 case VK_FORMAT_R16G16_UNORM:
161 case VK_FORMAT_R16G16B16A16_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700162 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
163 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
Ben Clayton3d7b7ea2019-05-14 16:49:58 +0100164 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400165 for(unsigned int q = 0; q < state.multiSample; q++)
166 {
167 Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[index]));
168 Vector4s color;
169
Ben Clayton3d7b7ea2019-05-14 16:49:58 +0100170 if(format == VK_FORMAT_R5G6B5_UNORM_PACK16)
Nicolas Capens68a82382018-10-02 13:16:55 -0400171 {
172 color.x = UShort4(c[index].x * Float4(0xFBFF), false);
173 color.y = UShort4(c[index].y * Float4(0xFDFF), false);
174 color.z = UShort4(c[index].z * Float4(0xFBFF), false);
175 color.w = UShort4(c[index].w * Float4(0xFFFF), false);
176 }
177 else
178 {
179 color.x = convertFixed16(c[index].x, false);
180 color.y = convertFixed16(c[index].y, false);
181 color.z = convertFixed16(c[index].z, false);
182 color.w = convertFixed16(c[index].w, false);
183 }
184
185 if(state.multiSampleMask & (1 << q))
186 {
187 alphaBlend(index, buffer, color, x);
Nicolas Capens68a82382018-10-02 13:16:55 -0400188 writeColor(index, buffer, x, color, sMask[q], zMask[q], cMask[q]);
189 }
190 }
191 break;
Ben Clayton8ab40532019-05-10 16:23:13 +0100192 case VK_FORMAT_R16_SFLOAT:
193 case VK_FORMAT_R16G16_SFLOAT:
194 case VK_FORMAT_R16G16B16A16_SFLOAT:
Alexis Hetudd152e12018-11-14 13:39:28 -0500195 case VK_FORMAT_R32_SFLOAT:
196 case VK_FORMAT_R32G32_SFLOAT:
197 case VK_FORMAT_R32G32B32A32_SFLOAT:
198 case VK_FORMAT_R32_SINT:
199 case VK_FORMAT_R32G32_SINT:
200 case VK_FORMAT_R32G32B32A32_SINT:
201 case VK_FORMAT_R32_UINT:
202 case VK_FORMAT_R32G32_UINT:
203 case VK_FORMAT_R32G32B32A32_UINT:
204 case VK_FORMAT_R16_SINT:
205 case VK_FORMAT_R16G16_SINT:
206 case VK_FORMAT_R16G16B16A16_SINT:
207 case VK_FORMAT_R16_UINT:
208 case VK_FORMAT_R16G16_UINT:
209 case VK_FORMAT_R16G16B16A16_UINT:
210 case VK_FORMAT_R8_SINT:
211 case VK_FORMAT_R8G8_SINT:
212 case VK_FORMAT_R8G8B8A8_SINT:
213 case VK_FORMAT_R8_UINT:
214 case VK_FORMAT_R8G8_UINT:
215 case VK_FORMAT_R8G8B8A8_UINT:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700216 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
217 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
Chris Forbesb0f37162019-05-03 07:25:58 -0700218 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400219 for(unsigned int q = 0; q < state.multiSample; q++)
220 {
221 Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[index]));
222 Vector4f color = c[index];
223
224 if(state.multiSampleMask & (1 << q))
225 {
226 alphaBlend(index, buffer, color, x);
227 writeColor(index, buffer, x, color, sMask[q], zMask[q], cMask[q]);
228 }
229 }
230 break;
231 default:
Ben Clayton3d7b7ea2019-05-14 16:49:58 +0100232 UNIMPLEMENTED("VkFormat: %d", int(format));
Nicolas Capens68a82382018-10-02 13:16:55 -0400233 }
234 }
235 }
236
Nicolas Capens68a82382018-10-02 13:16:55 -0400237 void PixelProgram::clampColor(Vector4f oC[RENDERTARGETS])
238 {
239 for(int index = 0; index < RENDERTARGETS; index++)
240 {
Chris Forbeseae5b962019-04-19 17:01:10 -0700241 if(!state.colorWriteActive(index) && !(index == 0 && state.alphaToCoverage))
Nicolas Capens68a82382018-10-02 13:16:55 -0400242 {
243 continue;
244 }
245
246 switch(state.targetFormat[index])
247 {
Alexis Hetudd152e12018-11-14 13:39:28 -0500248 case VK_FORMAT_UNDEFINED:
Nicolas Capens68a82382018-10-02 13:16:55 -0400249 break;
Alexis Hetudd152e12018-11-14 13:39:28 -0500250 case VK_FORMAT_R5G6B5_UNORM_PACK16:
251 case VK_FORMAT_B8G8R8A8_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700252 case VK_FORMAT_B8G8R8A8_SRGB:
Alexis Hetudd152e12018-11-14 13:39:28 -0500253 case VK_FORMAT_R8G8B8A8_UNORM:
254 case VK_FORMAT_R8G8B8A8_SRGB:
255 case VK_FORMAT_R8G8_UNORM:
256 case VK_FORMAT_R8_UNORM:
257 case VK_FORMAT_R16G16_UNORM:
258 case VK_FORMAT_R16G16B16A16_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700259 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
260 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
Chris Forbesb0f37162019-05-03 07:25:58 -0700261 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400262 oC[index].x = Max(oC[index].x, Float4(0.0f)); oC[index].x = Min(oC[index].x, Float4(1.0f));
263 oC[index].y = Max(oC[index].y, Float4(0.0f)); oC[index].y = Min(oC[index].y, Float4(1.0f));
264 oC[index].z = Max(oC[index].z, Float4(0.0f)); oC[index].z = Min(oC[index].z, Float4(1.0f));
265 oC[index].w = Max(oC[index].w, Float4(0.0f)); oC[index].w = Min(oC[index].w, Float4(1.0f));
266 break;
Alexis Hetudd152e12018-11-14 13:39:28 -0500267 case VK_FORMAT_R32_SFLOAT:
268 case VK_FORMAT_R32G32_SFLOAT:
269 case VK_FORMAT_R32G32B32A32_SFLOAT:
270 case VK_FORMAT_R32_SINT:
271 case VK_FORMAT_R32G32_SINT:
272 case VK_FORMAT_R32G32B32A32_SINT:
273 case VK_FORMAT_R32_UINT:
274 case VK_FORMAT_R32G32_UINT:
275 case VK_FORMAT_R32G32B32A32_UINT:
Ben Clayton8ab40532019-05-10 16:23:13 +0100276 case VK_FORMAT_R16_SFLOAT:
277 case VK_FORMAT_R16G16_SFLOAT:
278 case VK_FORMAT_R16G16B16A16_SFLOAT:
Alexis Hetudd152e12018-11-14 13:39:28 -0500279 case VK_FORMAT_R16_SINT:
280 case VK_FORMAT_R16G16_SINT:
281 case VK_FORMAT_R16G16B16A16_SINT:
282 case VK_FORMAT_R16_UINT:
283 case VK_FORMAT_R16G16_UINT:
284 case VK_FORMAT_R16G16B16A16_UINT:
285 case VK_FORMAT_R8_SINT:
286 case VK_FORMAT_R8G8_SINT:
287 case VK_FORMAT_R8G8B8A8_SINT:
288 case VK_FORMAT_R8_UINT:
289 case VK_FORMAT_R8G8_UINT:
290 case VK_FORMAT_R8G8B8A8_UINT:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700291 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
292 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
Chris Forbesb0f37162019-05-03 07:25:58 -0700293 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400294 break;
Nicolas Capens68a82382018-10-02 13:16:55 -0400295 default:
Ben Clayton3bb94902019-04-07 13:10:54 +0100296 UNIMPLEMENTED("VkFormat: %d", int(state.targetFormat[index]));
Nicolas Capens68a82382018-10-02 13:16:55 -0400297 }
298 }
299 }
300
Nicolas Capens68a82382018-10-02 13:16:55 -0400301 Float4 PixelProgram::linearToSRGB(const Float4 &x) // Approximates x^(1.0/2.2)
302 {
303 Float4 sqrtx = Rcp_pp(RcpSqrt_pp(x));
304 Float4 sRGB = sqrtx * Float4(1.14f) - x * Float4(0.14f);
305
306 return Min(Max(sRGB, Float4(0.0f)), Float4(1.0f));
307 }
Nicolas Capens68a82382018-10-02 13:16:55 -0400308}