blob: f1a490d4320901f8c1ae8e28fdb30c9edaf823c7 [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 }
Nicolas Capens68a82382018-10-02 13:16:55 -040053 }
54
55 void PixelProgram::applyShader(Int cMask[4])
56 {
Ben Clayton225a1302019-04-02 12:28:22 +010057 routine.descriptorSets = data + OFFSET(DrawData, descriptorSets);
58 routine.descriptorDynamicOffsets = data + OFFSET(DrawData, descriptorDynamicOffsets);
Chris Forbesa30de542019-03-18 18:51:55 -070059 routine.pushConstants = data + OFFSET(DrawData, pushConstants);
Chris Forbes548e3662019-04-25 10:00:06 -070060 routine.constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, constants));
Chris Forbesa30de542019-03-18 18:51:55 -070061
Chris Forbes25be5bb2019-04-15 15:20:27 -070062 auto it = spirvShader->inputBuiltins.find(spv::BuiltInFrontFacing);
63 if (it != spirvShader->inputBuiltins.end())
64 {
65 ASSERT(it->second.SizeInComponents == 1);
66 auto frontFacing = Int4(*Pointer<Int>(primitive + OFFSET(Primitive, clockwiseMask)));
67 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<Float4>(frontFacing);
68 }
69
Ben Claytonc0cf68b2019-03-21 17:46:08 +000070 auto activeLaneMask = SIMD::Int(0xFFFFFFFF); // TODO: Control this.
Nicolas Capens09591b82019-04-08 22:51:08 -040071 spirvShader->emit(&routine, activeLaneMask, descriptorSets);
Chris Forbesc61271e2019-02-19 17:01:28 -080072 spirvShader->emitEpilog(&routine);
Chris Forbes1845d5e2018-12-27 11:50:15 -080073
74 for(int i = 0; i < RENDERTARGETS; i++)
Nicolas Capens68a82382018-10-02 13:16:55 -040075 {
Chris Forbesc1fd4082019-02-19 17:19:48 -080076 c[i].x = routine.outputs[i * 4];
77 c[i].y = routine.outputs[i * 4 + 1];
78 c[i].z = routine.outputs[i * 4 + 2];
79 c[i].w = routine.outputs[i * 4 + 3];
Nicolas Capens68a82382018-10-02 13:16:55 -040080 }
81
82 clampColor(c);
83
Chris Forbes97e95892019-04-02 13:37:37 +130084 if(spirvShader->getModes().ContainsKill)
85 {
86 for (auto i = 0u; i < state.multiSample; i++)
87 {
88 cMask[i] &= ~routine.killMask;
89 }
90 }
91
Chris Forbes72881512019-04-15 19:51:26 -070092 it = spirvShader->outputBuiltins.find(spv::BuiltInFragDepth);
93 if (it != spirvShader->outputBuiltins.end())
94 {
95 oDepth = routine.getVariable(it->second.Id)[it->second.FirstComponent];
96 }
97
Chris Forbes81d19c92019-02-10 22:04:56 +000098 if(spirvShader->getModes().DepthReplacing)
Nicolas Capens68a82382018-10-02 13:16:55 -040099 {
100 oDepth = Min(Max(oDepth, Float4(0.0f)), Float4(1.0f));
101 }
102 }
103
104 Bool PixelProgram::alphaTest(Int cMask[4])
105 {
Chris Forbeseae5b962019-04-19 17:01:10 -0700106 if(!state.alphaToCoverage)
Nicolas Capens68a82382018-10-02 13:16:55 -0400107 {
108 return true;
109 }
110
Chris Forbeseae5b962019-04-19 17:01:10 -0700111 alphaToCoverage(cMask, c[0].w);
Nicolas Capens68a82382018-10-02 13:16:55 -0400112
113 Int pass = cMask[0];
114
115 for(unsigned int q = 1; q < state.multiSample; q++)
116 {
117 pass = pass | cMask[q];
118 }
119
120 return pass != 0x0;
121 }
122
Chris Forbese7579262019-02-10 19:21:59 +0000123 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 -0400124 {
125 for(int index = 0; index < RENDERTARGETS; index++)
126 {
127 if(!state.colorWriteActive(index))
128 {
129 continue;
130 }
131
Nicolas Capens68a82382018-10-02 13:16:55 -0400132 switch(state.targetFormat[index])
133 {
Alexis Hetudd152e12018-11-14 13:39:28 -0500134 case VK_FORMAT_R5G6B5_UNORM_PACK16:
135 case VK_FORMAT_B8G8R8A8_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700136 case VK_FORMAT_B8G8R8A8_SRGB:
Alexis Hetudd152e12018-11-14 13:39:28 -0500137 case VK_FORMAT_R8G8B8A8_UNORM:
138 case VK_FORMAT_R8G8B8A8_SRGB:
139 case VK_FORMAT_R8G8_UNORM:
140 case VK_FORMAT_R8_UNORM:
141 case VK_FORMAT_R16G16_UNORM:
142 case VK_FORMAT_R16G16B16A16_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700143 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
144 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400145 for(unsigned int q = 0; q < state.multiSample; q++)
146 {
147 Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[index]));
148 Vector4s color;
149
Alexis Hetudd152e12018-11-14 13:39:28 -0500150 if(state.targetFormat[index] == VK_FORMAT_R5G6B5_UNORM_PACK16)
Nicolas Capens68a82382018-10-02 13:16:55 -0400151 {
152 color.x = UShort4(c[index].x * Float4(0xFBFF), false);
153 color.y = UShort4(c[index].y * Float4(0xFDFF), false);
154 color.z = UShort4(c[index].z * Float4(0xFBFF), false);
155 color.w = UShort4(c[index].w * Float4(0xFFFF), false);
156 }
157 else
158 {
159 color.x = convertFixed16(c[index].x, false);
160 color.y = convertFixed16(c[index].y, false);
161 color.z = convertFixed16(c[index].z, false);
162 color.w = convertFixed16(c[index].w, false);
163 }
164
165 if(state.multiSampleMask & (1 << q))
166 {
167 alphaBlend(index, buffer, color, x);
Nicolas Capens68a82382018-10-02 13:16:55 -0400168 writeColor(index, buffer, x, color, sMask[q], zMask[q], cMask[q]);
169 }
170 }
171 break;
Alexis Hetudd152e12018-11-14 13:39:28 -0500172 case VK_FORMAT_R32_SFLOAT:
173 case VK_FORMAT_R32G32_SFLOAT:
174 case VK_FORMAT_R32G32B32A32_SFLOAT:
175 case VK_FORMAT_R32_SINT:
176 case VK_FORMAT_R32G32_SINT:
177 case VK_FORMAT_R32G32B32A32_SINT:
178 case VK_FORMAT_R32_UINT:
179 case VK_FORMAT_R32G32_UINT:
180 case VK_FORMAT_R32G32B32A32_UINT:
181 case VK_FORMAT_R16_SINT:
182 case VK_FORMAT_R16G16_SINT:
183 case VK_FORMAT_R16G16B16A16_SINT:
184 case VK_FORMAT_R16_UINT:
185 case VK_FORMAT_R16G16_UINT:
186 case VK_FORMAT_R16G16B16A16_UINT:
187 case VK_FORMAT_R8_SINT:
188 case VK_FORMAT_R8G8_SINT:
189 case VK_FORMAT_R8G8B8A8_SINT:
190 case VK_FORMAT_R8_UINT:
191 case VK_FORMAT_R8G8_UINT:
192 case VK_FORMAT_R8G8B8A8_UINT:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700193 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
194 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400195 for(unsigned int q = 0; q < state.multiSample; q++)
196 {
197 Pointer<Byte> buffer = cBuffer[index] + q * *Pointer<Int>(data + OFFSET(DrawData, colorSliceB[index]));
198 Vector4f color = c[index];
199
200 if(state.multiSampleMask & (1 << q))
201 {
202 alphaBlend(index, buffer, color, x);
203 writeColor(index, buffer, x, color, sMask[q], zMask[q], cMask[q]);
204 }
205 }
206 break;
207 default:
Ben Clayton3bb94902019-04-07 13:10:54 +0100208 UNIMPLEMENTED("VkFormat: %d", int(state.targetFormat[index]));
Nicolas Capens68a82382018-10-02 13:16:55 -0400209 }
210 }
211 }
212
Nicolas Capens68a82382018-10-02 13:16:55 -0400213 void PixelProgram::clampColor(Vector4f oC[RENDERTARGETS])
214 {
215 for(int index = 0; index < RENDERTARGETS; index++)
216 {
Chris Forbeseae5b962019-04-19 17:01:10 -0700217 if(!state.colorWriteActive(index) && !(index == 0 && state.alphaToCoverage))
Nicolas Capens68a82382018-10-02 13:16:55 -0400218 {
219 continue;
220 }
221
222 switch(state.targetFormat[index])
223 {
Alexis Hetudd152e12018-11-14 13:39:28 -0500224 case VK_FORMAT_UNDEFINED:
Nicolas Capens68a82382018-10-02 13:16:55 -0400225 break;
Alexis Hetudd152e12018-11-14 13:39:28 -0500226 case VK_FORMAT_R5G6B5_UNORM_PACK16:
227 case VK_FORMAT_B8G8R8A8_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700228 case VK_FORMAT_B8G8R8A8_SRGB:
Alexis Hetudd152e12018-11-14 13:39:28 -0500229 case VK_FORMAT_R8G8B8A8_UNORM:
230 case VK_FORMAT_R8G8B8A8_SRGB:
231 case VK_FORMAT_R8G8_UNORM:
232 case VK_FORMAT_R8_UNORM:
233 case VK_FORMAT_R16G16_UNORM:
234 case VK_FORMAT_R16G16B16A16_UNORM:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700235 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
236 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400237 oC[index].x = Max(oC[index].x, Float4(0.0f)); oC[index].x = Min(oC[index].x, Float4(1.0f));
238 oC[index].y = Max(oC[index].y, Float4(0.0f)); oC[index].y = Min(oC[index].y, Float4(1.0f));
239 oC[index].z = Max(oC[index].z, Float4(0.0f)); oC[index].z = Min(oC[index].z, Float4(1.0f));
240 oC[index].w = Max(oC[index].w, Float4(0.0f)); oC[index].w = Min(oC[index].w, Float4(1.0f));
241 break;
Alexis Hetudd152e12018-11-14 13:39:28 -0500242 case VK_FORMAT_R32_SFLOAT:
243 case VK_FORMAT_R32G32_SFLOAT:
244 case VK_FORMAT_R32G32B32A32_SFLOAT:
245 case VK_FORMAT_R32_SINT:
246 case VK_FORMAT_R32G32_SINT:
247 case VK_FORMAT_R32G32B32A32_SINT:
248 case VK_FORMAT_R32_UINT:
249 case VK_FORMAT_R32G32_UINT:
250 case VK_FORMAT_R32G32B32A32_UINT:
251 case VK_FORMAT_R16_SINT:
252 case VK_FORMAT_R16G16_SINT:
253 case VK_FORMAT_R16G16B16A16_SINT:
254 case VK_FORMAT_R16_UINT:
255 case VK_FORMAT_R16G16_UINT:
256 case VK_FORMAT_R16G16B16A16_UINT:
257 case VK_FORMAT_R8_SINT:
258 case VK_FORMAT_R8G8_SINT:
259 case VK_FORMAT_R8G8B8A8_SINT:
260 case VK_FORMAT_R8_UINT:
261 case VK_FORMAT_R8G8_UINT:
262 case VK_FORMAT_R8G8B8A8_UINT:
Chris Forbes6407c1a2019-04-15 17:22:57 -0700263 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
264 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
Nicolas Capens68a82382018-10-02 13:16:55 -0400265 break;
Nicolas Capens68a82382018-10-02 13:16:55 -0400266 default:
Ben Clayton3bb94902019-04-07 13:10:54 +0100267 UNIMPLEMENTED("VkFormat: %d", int(state.targetFormat[index]));
Nicolas Capens68a82382018-10-02 13:16:55 -0400268 }
269 }
270 }
271
Nicolas Capens68a82382018-10-02 13:16:55 -0400272 Float4 PixelProgram::linearToSRGB(const Float4 &x) // Approximates x^(1.0/2.2)
273 {
274 Float4 sqrtx = Rcp_pp(RcpSqrt_pp(x));
275 Float4 sRGB = sqrtx * Float4(1.14f) - x * Float4(0.14f);
276
277 return Min(Max(sRGB, Float4(0.0f)), Float4(1.0f));
278 }
Nicolas Capens68a82382018-10-02 13:16:55 -0400279}