xref: /aosp_15_r20/external/swiftshader/src/Device/VertexProcessor.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2016 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 "VertexProcessor.hpp"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #include "Pipeline/Constants.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "Pipeline/VertexProgram.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "System/Debug.hpp"
20*03ce13f7SAndroid Build Coastguard Worker #include "System/Math.hpp"
21*03ce13f7SAndroid Build Coastguard Worker #include "Vulkan/VkPipelineLayout.hpp"
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker #include <cstring>
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker namespace sw {
26*03ce13f7SAndroid Build Coastguard Worker 
clear()27*03ce13f7SAndroid Build Coastguard Worker void VertexCache::clear()
28*03ce13f7SAndroid Build Coastguard Worker {
29*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < SIZE; i++)
30*03ce13f7SAndroid Build Coastguard Worker 	{
31*03ce13f7SAndroid Build Coastguard Worker 		tag[i] = 0xFFFFFFFF;
32*03ce13f7SAndroid Build Coastguard Worker 	}
33*03ce13f7SAndroid Build Coastguard Worker }
34*03ce13f7SAndroid Build Coastguard Worker 
computeHash()35*03ce13f7SAndroid Build Coastguard Worker uint32_t VertexProcessor::States::computeHash()
36*03ce13f7SAndroid Build Coastguard Worker {
37*03ce13f7SAndroid Build Coastguard Worker 	uint32_t *state = reinterpret_cast<uint32_t *>(this);
38*03ce13f7SAndroid Build Coastguard Worker 	uint32_t hash = 0;
39*03ce13f7SAndroid Build Coastguard Worker 
40*03ce13f7SAndroid Build Coastguard Worker 	for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++)
41*03ce13f7SAndroid Build Coastguard Worker 	{
42*03ce13f7SAndroid Build Coastguard Worker 		hash ^= state[i];
43*03ce13f7SAndroid Build Coastguard Worker 	}
44*03ce13f7SAndroid Build Coastguard Worker 
45*03ce13f7SAndroid Build Coastguard Worker 	return hash;
46*03ce13f7SAndroid Build Coastguard Worker }
47*03ce13f7SAndroid Build Coastguard Worker 
operator ==(const State & state) const48*03ce13f7SAndroid Build Coastguard Worker bool VertexProcessor::State::operator==(const State &state) const
49*03ce13f7SAndroid Build Coastguard Worker {
50*03ce13f7SAndroid Build Coastguard Worker 	if(hash != state.hash)
51*03ce13f7SAndroid Build Coastguard Worker 	{
52*03ce13f7SAndroid Build Coastguard Worker 		return false;
53*03ce13f7SAndroid Build Coastguard Worker 	}
54*03ce13f7SAndroid Build Coastguard Worker 
55*03ce13f7SAndroid Build Coastguard Worker 	return *static_cast<const States *>(this) == static_cast<const States &>(state);
56*03ce13f7SAndroid Build Coastguard Worker }
57*03ce13f7SAndroid Build Coastguard Worker 
VertexProcessor()58*03ce13f7SAndroid Build Coastguard Worker VertexProcessor::VertexProcessor()
59*03ce13f7SAndroid Build Coastguard Worker {
60*03ce13f7SAndroid Build Coastguard Worker 	setRoutineCacheSize(1024);
61*03ce13f7SAndroid Build Coastguard Worker }
62*03ce13f7SAndroid Build Coastguard Worker 
setRoutineCacheSize(int cacheSize)63*03ce13f7SAndroid Build Coastguard Worker void VertexProcessor::setRoutineCacheSize(int cacheSize)
64*03ce13f7SAndroid Build Coastguard Worker {
65*03ce13f7SAndroid Build Coastguard Worker 	routineCache = std::make_unique<RoutineCacheType>(clamp(cacheSize, 1, 65536));
66*03ce13f7SAndroid Build Coastguard Worker }
67*03ce13f7SAndroid Build Coastguard Worker 
update(const vk::GraphicsState & pipelineState,const sw::SpirvShader * vertexShader,const vk::Inputs & inputs)68*03ce13f7SAndroid Build Coastguard Worker const VertexProcessor::State VertexProcessor::update(const vk::GraphicsState &pipelineState, const sw::SpirvShader *vertexShader, const vk::Inputs &inputs)
69*03ce13f7SAndroid Build Coastguard Worker {
70*03ce13f7SAndroid Build Coastguard Worker 	const vk::VertexInputInterfaceState &vertexInputInterfaceState = pipelineState.getVertexInputInterfaceState();
71*03ce13f7SAndroid Build Coastguard Worker 	const vk::PreRasterizationState &preRasterizationState = pipelineState.getPreRasterizationState();
72*03ce13f7SAndroid Build Coastguard Worker 
73*03ce13f7SAndroid Build Coastguard Worker 	State state;
74*03ce13f7SAndroid Build Coastguard Worker 
75*03ce13f7SAndroid Build Coastguard Worker 	state.shaderID = vertexShader->getIdentifier();
76*03ce13f7SAndroid Build Coastguard Worker 	state.pipelineLayoutIdentifier = preRasterizationState.getPipelineLayout()->identifier;
77*03ce13f7SAndroid Build Coastguard Worker 	state.robustBufferAccess = vertexShader->getRobustBufferAccess();
78*03ce13f7SAndroid Build Coastguard Worker 	state.isPoint = vertexInputInterfaceState.getTopology() == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
79*03ce13f7SAndroid Build Coastguard Worker 	state.depthClipEnable = preRasterizationState.getDepthClipEnable();
80*03ce13f7SAndroid Build Coastguard Worker 	state.depthClipNegativeOneToOne = preRasterizationState.getDepthClipNegativeOneToOne();
81*03ce13f7SAndroid Build Coastguard Worker 
82*03ce13f7SAndroid Build Coastguard Worker 	for(size_t i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++)
83*03ce13f7SAndroid Build Coastguard Worker 	{
84*03ce13f7SAndroid Build Coastguard Worker 		state.input[i].format = inputs.getStream(i).format;
85*03ce13f7SAndroid Build Coastguard Worker 		// TODO: get rid of attribType -- just keep the VK format all the way through, this fully determines
86*03ce13f7SAndroid Build Coastguard Worker 		// how to handle the attribute.
87*03ce13f7SAndroid Build Coastguard Worker 		state.input[i].attribType = vertexShader->inputs[i * 4].Type;
88*03ce13f7SAndroid Build Coastguard Worker 	}
89*03ce13f7SAndroid Build Coastguard Worker 
90*03ce13f7SAndroid Build Coastguard Worker 	state.hash = state.computeHash();
91*03ce13f7SAndroid Build Coastguard Worker 
92*03ce13f7SAndroid Build Coastguard Worker 	return state;
93*03ce13f7SAndroid Build Coastguard Worker }
94*03ce13f7SAndroid Build Coastguard Worker 
routine(const State & state,const vk::PipelineLayout * pipelineLayout,const SpirvShader * vertexShader,const vk::DescriptorSet::Bindings & descriptorSets)95*03ce13f7SAndroid Build Coastguard Worker VertexProcessor::RoutineType VertexProcessor::routine(const State &state,
96*03ce13f7SAndroid Build Coastguard Worker                                                       const vk::PipelineLayout *pipelineLayout,
97*03ce13f7SAndroid Build Coastguard Worker                                                       const SpirvShader *vertexShader,
98*03ce13f7SAndroid Build Coastguard Worker                                                       const vk::DescriptorSet::Bindings &descriptorSets)
99*03ce13f7SAndroid Build Coastguard Worker {
100*03ce13f7SAndroid Build Coastguard Worker 	auto routine = routineCache->lookup(state);
101*03ce13f7SAndroid Build Coastguard Worker 
102*03ce13f7SAndroid Build Coastguard Worker 	if(!routine)  // Create one
103*03ce13f7SAndroid Build Coastguard Worker 	{
104*03ce13f7SAndroid Build Coastguard Worker 		VertexRoutine *generator = new VertexProgram(state, pipelineLayout, vertexShader, descriptorSets);
105*03ce13f7SAndroid Build Coastguard Worker 		generator->generate();
106*03ce13f7SAndroid Build Coastguard Worker 		routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
107*03ce13f7SAndroid Build Coastguard Worker 		delete generator;
108*03ce13f7SAndroid Build Coastguard Worker 
109*03ce13f7SAndroid Build Coastguard Worker 		routineCache->add(state, routine);
110*03ce13f7SAndroid Build Coastguard Worker 	}
111*03ce13f7SAndroid Build Coastguard Worker 
112*03ce13f7SAndroid Build Coastguard Worker 	return routine;
113*03ce13f7SAndroid Build Coastguard Worker }
114*03ce13f7SAndroid Build Coastguard Worker 
115*03ce13f7SAndroid Build Coastguard Worker }  // namespace sw
116