xref: /aosp_15_r20/external/swiftshader/src/Pipeline/VertexProgram.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 // 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 "VertexProgram.hpp"
16 
17 #include "SamplerCore.hpp"
18 #include "Device/Renderer.hpp"
19 #include "Device/Vertex.hpp"
20 #include "System/Debug.hpp"
21 #include "System/Half.hpp"
22 #include "Vulkan/VkDevice.hpp"
23 #include "Vulkan/VkPipelineLayout.hpp"
24 
25 namespace sw {
26 
VertexProgram(const VertexProcessor::State & state,const vk::PipelineLayout * pipelineLayout,const SpirvShader * spirvShader,const vk::DescriptorSet::Bindings & descriptorSets)27 VertexProgram::VertexProgram(
28     const VertexProcessor::State &state,
29     const vk::PipelineLayout *pipelineLayout,
30     const SpirvShader *spirvShader,
31     const vk::DescriptorSet::Bindings &descriptorSets)
32     : VertexRoutine(state, pipelineLayout, spirvShader)
33     , descriptorSets(descriptorSets)
34 {
35 	routine.setImmutableInputBuiltins(spirvShader);
36 
37 	// TODO(b/146486064): Consider only assigning these to the SpirvRoutine iff
38 	// they are ever going to be read.
39 	routine.layer = *Pointer<Int>(data + OFFSET(DrawData, layer));
40 	routine.instanceID = *Pointer<Int>(data + OFFSET(DrawData, instanceID));
41 
42 	routine.setInputBuiltin(spirvShader, spv::BuiltInViewIndex, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
43 		assert(builtin.SizeInComponents == 1);
44 		value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine.layer));
45 	});
46 
47 	routine.setInputBuiltin(spirvShader, spv::BuiltInInstanceIndex, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
48 		// TODO: we could do better here; we know InstanceIndex is uniform across all lanes
49 		assert(builtin.SizeInComponents == 1);
50 		value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine.instanceID));
51 	});
52 
53 	routine.setInputBuiltin(spirvShader, spv::BuiltInSubgroupSize, [&](const Spirv::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
54 		ASSERT(builtin.SizeInComponents == 1);
55 		value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(SIMD::Width));
56 	});
57 
58 	routine.device = device;
59 	routine.descriptorSets = data + OFFSET(DrawData, descriptorSets);
60 	routine.descriptorDynamicOffsets = data + OFFSET(DrawData, descriptorDynamicOffsets);
61 	routine.pushConstants = data + OFFSET(DrawData, pushConstants);
62 	routine.constants = device + OFFSET(vk::Device, constants);
63 }
64 
~VertexProgram()65 VertexProgram::~VertexProgram()
66 {
67 }
68 
program(Pointer<UInt> & batch,UInt & vertexCount)69 void VertexProgram::program(Pointer<UInt> &batch, UInt &vertexCount)
70 {
71 	routine.vertexIndex = *Pointer<SIMD::Int>(As<Pointer<SIMD::Int>>(batch)) +
72 	                      SIMD::Int(*Pointer<Int>(data + OFFSET(DrawData, baseVertex)));
73 
74 	auto it = spirvShader->inputBuiltins.find(spv::BuiltInVertexIndex);
75 	if(it != spirvShader->inputBuiltins.end())
76 	{
77 		assert(it->second.SizeInComponents == 1);
78 		routine.getVariable(it->second.Id)[it->second.FirstComponent] =
79 		    As<SIMD::Float>(routine.vertexIndex);
80 	}
81 
82 	auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
83 	ASSERT(SIMD::Width == 4);
84 	SIMD::Int storesAndAtomicsMask = CmpGE(SIMD::UInt(vertexCount), SIMD::UInt(1, 2, 3, 4));
85 	spirvShader->emit(&routine, activeLaneMask, storesAndAtomicsMask, descriptorSets);
86 
87 	spirvShader->emitEpilog(&routine);
88 }
89 
90 }  // namespace sw
91