blob: e240e7ff5d77c145c98057b82c6e65ff4cf0428e [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 Capens68a82382018-10-02 13:16:55 -040025namespace sw
26{
Ben Clayton76e9bc02019-02-26 15:02:18 +000027 VertexProgram::VertexProgram(
28 const VertexProcessor::State &state,
29 vk::PipelineLayout const *pipelineLayout,
Nicolas Capens09591b82019-04-08 22:51:08 -040030 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 {
Chris Forbes26f1a862019-02-02 15:23:01 -080035 auto it = spirvShader->inputBuiltins.find(spv::BuiltInInstanceIndex);
36 if (it != spirvShader->inputBuiltins.end())
37 {
38 // TODO: we could do better here; we know InstanceIndex is uniform across all lanes
39 assert(it->second.SizeInComponents == 1);
Ben Clayton47747612019-04-04 16:27:35 +010040 routine.getVariable(it->second.Id)[it->second.FirstComponent] =
Chris Forbes26f1a862019-02-02 15:23:01 -080041 As<Float4>(Int4((*Pointer<Int>(data + OFFSET(DrawData, instanceID)))));
42 }
Chris Forbesa30de542019-03-18 18:51:55 -070043
Ben Clayton225a1302019-04-02 12:28:22 +010044 routine.descriptorSets = data + OFFSET(DrawData, descriptorSets);
45 routine.descriptorDynamicOffsets = data + OFFSET(DrawData, descriptorDynamicOffsets);
Chris Forbesa30de542019-03-18 18:51:55 -070046 routine.pushConstants = data + OFFSET(DrawData, pushConstants);
Chris Forbes548e3662019-04-25 10:00:06 -070047 routine.constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData, constants));
Chris Forbes84c3a942019-04-16 09:48:00 -070048
49 it = spirvShader->inputBuiltins.find(spv::BuiltInSubgroupSize);
50 if (it != spirvShader->inputBuiltins.end())
51 {
52 ASSERT(it->second.SizeInComponents == 1);
Chris Forbes793050e2019-04-27 14:48:09 -070053 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<SIMD::Float>(SIMD::Int(SIMD::Width));
Chris Forbes84c3a942019-04-16 09:48:00 -070054 }
55
56 it = spirvShader->inputBuiltins.find(spv::BuiltInSubgroupLocalInvocationId);
57 if (it != spirvShader->inputBuiltins.end())
58 {
59 ASSERT(it->second.SizeInComponents == 1);
60 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 1, 2, 3));
61 }
Ben Clayton2cd983d2019-05-10 11:30:09 +010062
63 it = spirvShader->inputBuiltins.find(spv::BuiltInDeviceIndex);
64 if (it != spirvShader->inputBuiltins.end())
65 {
66 ASSERT(it->second.SizeInComponents == 1);
67 // Only a single physical device is supported.
68 routine.getVariable(it->second.Id)[it->second.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
69 }
Nicolas Capens68a82382018-10-02 13:16:55 -040070 }
71
72 VertexProgram::~VertexProgram()
73 {
74 }
75
Nicolas Capens4a105592018-01-02 23:41:25 -050076 void VertexProgram::program(Pointer<UInt> &batch)
Nicolas Capens68a82382018-10-02 13:16:55 -040077 {
Chris Forbesd0077202019-02-10 19:52:08 +000078 auto it = spirvShader->inputBuiltins.find(spv::BuiltInVertexIndex);
79 if (it != spirvShader->inputBuiltins.end())
80 {
81 assert(it->second.SizeInComponents == 1);
Nicolas Capens4a105592018-01-02 23:41:25 -050082
83 Int4 indices;
84 indices = Insert(indices, As<Int>(batch[0]), 0);
85 indices = Insert(indices, As<Int>(batch[1]), 1);
86 indices = Insert(indices, As<Int>(batch[2]), 2);
87 indices = Insert(indices, As<Int>(batch[3]), 3);
Ben Clayton47747612019-04-04 16:27:35 +010088 routine.getVariable(it->second.Id)[it->second.FirstComponent] =
Nicolas Capens4a105592018-01-02 23:41:25 -050089 As<Float4>(indices + Int4(*Pointer<Int>(data + OFFSET(DrawData, baseVertex))));
Chris Forbesd0077202019-02-10 19:52:08 +000090 }
Nicolas Capens68a82382018-10-02 13:16:55 -040091
Nicolas Capens4a105592018-01-02 23:41:25 -050092 auto activeLaneMask = SIMD::Int(0xFFFFFFFF);
Nicolas Capens09591b82019-04-08 22:51:08 -040093 spirvShader->emit(&routine, activeLaneMask, descriptorSets);
Chris Forbesc61271e2019-02-19 17:01:28 -080094
95 spirvShader->emitEpilog(&routine);
Nicolas Capens68a82382018-10-02 13:16:55 -040096 }
Nicolas Capens68a82382018-10-02 13:16:55 -040097}