blob: c7c403c59d8ffde04cbf84f9f6f7b21ca307403e [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 "VertexProcessor.hpp"
16
Nicolas Capens1d8c8db2018-11-05 16:30:42 -050017#include "Pipeline/Constants.hpp"
Ben Claytonfccfc562019-12-17 20:37:31 +000018#include "Pipeline/VertexProgram.hpp"
Ben Clayton25e06e02020-02-07 11:19:08 +000019#include "System/Debug.hpp"
Nicolas Capens1d8c8db2018-11-05 16:30:42 -050020#include "System/Math.hpp"
Nicolas Capens5ab1f362020-04-22 01:39:36 -040021#include "Vulkan/VkPipelineLayout.hpp"
Nicolas Capens68a82382018-10-02 13:16:55 -040022
Nicolas Capense8993212019-06-21 12:21:08 -040023#include <cstring>
Nicolas Capens68a82382018-10-02 13:16:55 -040024
Nicolas Capens157ba262019-12-10 17:49:14 -050025namespace sw {
26
27void VertexCache::clear()
Nicolas Capens68a82382018-10-02 13:16:55 -040028{
Nicolas Capens157ba262019-12-10 17:49:14 -050029 for(uint32_t i = 0; i < SIZE; i++)
Nicolas Capens68a82382018-10-02 13:16:55 -040030 {
Nicolas Capens157ba262019-12-10 17:49:14 -050031 tag[i] = 0xFFFFFFFF;
Nicolas Capens68a82382018-10-02 13:16:55 -040032 }
33}
Nicolas Capens157ba262019-12-10 17:49:14 -050034
35uint32_t VertexProcessor::States::computeHash()
36{
Ben Claytonfccfc562019-12-17 20:37:31 +000037 uint32_t *state = reinterpret_cast<uint32_t *>(this);
Nicolas Capens157ba262019-12-10 17:49:14 -050038 uint32_t hash = 0;
39
40 for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++)
41 {
42 hash ^= state[i];
43 }
44
45 return hash;
46}
47
Nicolas Capens157ba262019-12-10 17:49:14 -050048bool VertexProcessor::State::operator==(const State &state) const
49{
50 if(hash != state.hash)
51 {
52 return false;
53 }
54
Nicolas Capens1885f692020-03-23 11:28:44 -040055 return *static_cast<const States *>(this) == static_cast<const States &>(state);
Nicolas Capens157ba262019-12-10 17:49:14 -050056}
57
58VertexProcessor::VertexProcessor()
59{
Nicolas Capens157ba262019-12-10 17:49:14 -050060 setRoutineCacheSize(1024);
61}
62
Nicolas Capens157ba262019-12-10 17:49:14 -050063void VertexProcessor::setRoutineCacheSize(int cacheSize)
64{
Ben Clayton197e2512020-04-12 16:35:12 +010065 routineCache = std::make_unique<RoutineCacheType>(clamp(cacheSize, 1, 65536));
Nicolas Capens157ba262019-12-10 17:49:14 -050066}
67
Ben Claytonfccfc562019-12-17 20:37:31 +000068const VertexProcessor::State VertexProcessor::update(const sw::Context *context)
Nicolas Capens157ba262019-12-10 17:49:14 -050069{
70 State state;
71
72 state.shaderID = context->vertexShader->getSerialID();
Nicolas Capens5ab1f362020-04-22 01:39:36 -040073 state.pipelineLayoutIdentifier = context->pipelineLayout->identifier;
Nicolas Capens157ba262019-12-10 17:49:14 -050074 state.robustBufferAccess = context->robustBufferAccess;
75 state.isPoint = context->topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
76
77 for(int i = 0; i < MAX_INTERFACE_COMPONENTS / 4; i++)
78 {
Alexis Hetub766e5e2020-01-20 11:40:28 -050079 state.input[i].format = context->input[i].format;
Nicolas Capens157ba262019-12-10 17:49:14 -050080 // TODO: get rid of attribType -- just keep the VK format all the way through, this fully determines
81 // how to handle the attribute.
Ben Claytonfccfc562019-12-17 20:37:31 +000082 state.input[i].attribType = context->vertexShader->inputs[i * 4].Type;
Nicolas Capens157ba262019-12-10 17:49:14 -050083 }
84
85 state.hash = state.computeHash();
86
87 return state;
88}
89
90VertexProcessor::RoutineType VertexProcessor::routine(const State &state,
91 vk::PipelineLayout const *pipelineLayout,
92 SpirvShader const *vertexShader,
93 const vk::DescriptorSet::Bindings &descriptorSets)
94{
Ben Claytonac43aa72020-04-04 00:48:13 +010095 auto routine = routineCache->lookup(state);
Nicolas Capens157ba262019-12-10 17:49:14 -050096
Ben Claytonfccfc562019-12-17 20:37:31 +000097 if(!routine) // Create one
Nicolas Capens157ba262019-12-10 17:49:14 -050098 {
99 VertexRoutine *generator = new VertexProgram(state, pipelineLayout, vertexShader, descriptorSets);
100 generator->generate();
101 routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
102 delete generator;
103
104 routineCache->add(state, routine);
105 }
106
107 return routine;
108}
109
110} // namespace sw