blob: 647ff3a34ef2d661f676305383865083f0ae439d [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 Capens68a82382018-10-02 13:16:55 -040076 void VertexProgram::program(UInt &index)
77 {
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);
Ben Clayton47747612019-04-04 16:27:35 +010082 routine.getVariable(it->second.Id)[it->second.FirstComponent] =
Chris Forbesd4e5e9e2019-04-15 12:43:38 -070083 As<Float4>(Int4(As<Int>(index) + *Pointer<Int>(data + OFFSET(DrawData, baseVertex))) + Int4(0, 1, 2, 3));
Chris Forbesd0077202019-02-10 19:52:08 +000084 }
Nicolas Capens68a82382018-10-02 13:16:55 -040085
Ben Claytonc0cf68b2019-03-21 17:46:08 +000086 auto activeLaneMask = SIMD::Int(0xFFFFFFFF); // TODO: Control this.
Nicolas Capens09591b82019-04-08 22:51:08 -040087 spirvShader->emit(&routine, activeLaneMask, descriptorSets);
Chris Forbesc61271e2019-02-19 17:01:28 -080088
89 spirvShader->emitEpilog(&routine);
Nicolas Capens68a82382018-10-02 13:16:55 -040090 }
Nicolas Capens68a82382018-10-02 13:16:55 -040091}