blob: 4972ef285d36b8bcf537bec4bc90e806893103c7 [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 "VertexProgram.hpp"
16
Nicolas Capens68a82382018-10-02 13:16:55 -040017#include "SamplerCore.hpp"
Nicolas Capens1d8c8db2018-11-05 16:30:42 -050018#include "Device/Renderer.hpp"
19#include "Device/Vertex.hpp"
20#include "System/Half.hpp"
Chris Forbesebe5f7f2019-01-16 10:38:34 -080021#include "Vulkan/VkDebug.hpp"
Nicolas Capens68a82382018-10-02 13:16:55 -040022
Chris Forbesc2968062019-03-19 16:48:03 -070023#include "Vulkan/VkPipelineLayout.hpp"
24
Nicolas Capens157ba262019-12-10 17:49:14 -050025namespace sw {
26
27VertexProgram::VertexProgram(
Ben Claytonbc1c067be2019-12-17 20:37:37 +000028 const VertexProcessor::State &state,
29 vk::PipelineLayout const *pipelineLayout,
30 SpirvShader const *spirvShader,
31 const vk::DescriptorSet::Bindings &descriptorSets)
32 : VertexRoutine(state, pipelineLayout, spirvShader)
33 , descriptorSets(descriptorSets)
Nicolas Capens68a82382018-10-02 13:16:55 -040034{
Nicolas Capens157ba262019-12-10 17:49:14 -050035 routine.setImmutableInputBuiltins(spirvShader);
36
Ben Clayton5beaef92019-12-03 12:23:35 +000037 // TODO(b/146486064): Consider only assigning these to the SpirvRoutine iff
38 // they are ever going to be read.
39 routine.viewID = *Pointer<Int>(data + OFFSET(DrawData, viewID));
40 routine.instanceID = *Pointer<Int>(data + OFFSET(DrawData, instanceID));
41
Ben Claytonbc1c067be2019-12-17 20:37:37 +000042 routine.setInputBuiltin(spirvShader, spv::BuiltInViewIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
Nicolas Capens157ba262019-12-10 17:49:14 -050043 assert(builtin.SizeInComponents == 1);
Ben Clayton5beaef92019-12-03 12:23:35 +000044 value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine.viewID));
Nicolas Capens157ba262019-12-10 17:49:14 -050045 });
Ben Clayton30ee92e2019-08-13 14:21:44 +010046
Ben Claytonbc1c067be2019-12-17 20:37:37 +000047 routine.setInputBuiltin(spirvShader, spv::BuiltInInstanceIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
Nicolas Capens157ba262019-12-10 17:49:14 -050048 // TODO: we could do better here; we know InstanceIndex is uniform across all lanes
49 assert(builtin.SizeInComponents == 1);
Ben Clayton5beaef92019-12-03 12:23:35 +000050 value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(routine.instanceID));
Nicolas Capens157ba262019-12-10 17:49:14 -050051 });
Nicolas Capens68a82382018-10-02 13:16:55 -040052
Ben Claytonbc1c067be2019-12-17 20:37:37 +000053 routine.setInputBuiltin(spirvShader, spv::BuiltInSubgroupSize, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
Nicolas Capens157ba262019-12-10 17:49:14 -050054 ASSERT(builtin.SizeInComponents == 1);
55 value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(SIMD::Width));
56 });
Nicolas Capens4a105592018-01-02 23:41:25 -050057
Nicolas Capens157ba262019-12-10 17:49:14 -050058 routine.descriptorSets = data + OFFSET(DrawData, descriptorSets);
59 routine.descriptorDynamicOffsets = data + OFFSET(DrawData, descriptorDynamicOffsets);
60 routine.pushConstants = data + OFFSET(DrawData, pushConstants);
61 routine.constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, constants));
Nicolas Capens68a82382018-10-02 13:16:55 -040062}
Nicolas Capens157ba262019-12-10 17:49:14 -050063
64VertexProgram::~VertexProgram()
65{
66}
67
Ben Claytonbc1c067be2019-12-17 20:37:37 +000068void VertexProgram::program(Pointer<UInt> &batch, UInt &vertexCount)
Nicolas Capens157ba262019-12-10 17:49:14 -050069{
Ben Clayton5beaef92019-12-03 12:23:35 +000070 routine.vertexIndex = *Pointer<SIMD::Int>(As<Pointer<SIMD::Int>>(batch)) +
71 SIMD::Int(*Pointer<Int>(data + OFFSET(DrawData, baseVertex)));
72
Nicolas Capens157ba262019-12-10 17:49:14 -050073 auto it = spirvShader->inputBuiltins.find(spv::BuiltInVertexIndex);
Nicolas Capens81bc9d92019-12-16 15:05:57 -050074 if(it != spirvShader->inputBuiltins.end())
Nicolas Capens157ba262019-12-10 17:49:14 -050075 {
76 assert(it->second.SizeInComponents == 1);
Nicolas Capens157ba262019-12-10 17:49:14 -050077 routine.getVariable(it->second.Id)[it->second.FirstComponent] =
Ben Clayton5beaef92019-12-03 12:23:35 +000078 As<SIMD::Float>(routine.vertexIndex);
Nicolas Capens157ba262019-12-10 17:49:14 -050079 }
80
81 auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
82 Int4 storesAndAtomicsMask = CmpGE(UInt4(vertexCount), UInt4(1, 2, 3, 4));
83 spirvShader->emit(&routine, activeLaneMask, storesAndAtomicsMask, descriptorSets);
84
85 spirvShader->emitEpilog(&routine);
86}
87
Ben Claytonbc1c067be2019-12-17 20:37:37 +000088} // namespace sw