blob: d770bdf146e9eeaf057fd29bbd96fcc58db4b094 [file] [log] [blame]
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04001// Copyright 2017 The NXT Authors
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
Corentin Wallez9347e8f2017-06-19 13:15:13 -040015#include "SampleUtils.h"
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040016
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040017#include "utils/NXTHelpers.h"
Corentin Wallez134e0802017-07-17 17:13:57 -040018#include "utils/SystemUtils.h"
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040019
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040020#include <cstdlib>
21#include <cstdio>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040022#include <vector>
23
24nxt::Device device;
25nxt::Queue queue;
Corentin Wallez66ff4472017-07-14 11:32:57 -040026nxt::RenderPipeline pipeline;
Kai Ninomiya68df8b02017-05-16 14:04:22 -070027nxt::RenderPass renderpass;
28nxt::Framebuffer framebuffer;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040029
30float RandomFloat(float min, float max) {
31 float zeroOne = rand() / float(RAND_MAX);
32 return zeroOne * (max - min) + min;
33}
34
35struct ShaderData {
36 float scale;
37 float time;
38 float offsetX;
39 float offsetY;
40 float scalar;
41 float scalarOffset;
42};
43
44static std::vector<ShaderData> shaderData;
45
46void init() {
Corentin Wallez583e9a82017-05-29 11:30:29 -070047 device = CreateCppNXTDevice();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040048
49 queue = device.CreateQueueBuilder().GetResult();
50
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040051 nxt::ShaderModule vsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040052 #version 450
53
54 layout(push_constant) uniform ConstantsBlock {
55 float scale;
56 float time;
57 float offsetX;
58 float offsetY;
59 float scalar;
60 float scalarOffset;
61 } c;
62
Corentin Wallezca9af202017-06-05 16:23:18 -040063 layout(location = 0) out vec4 v_color;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040064
65 const vec4 positions[3] = vec4[3](
66 vec4( 0.0f, 0.1f, 0.0f, 1.0f),
67 vec4(-0.1f, -0.1f, 0.0f, 1.0f),
68 vec4( 0.1f, -0.1f, 0.0f, 1.0f)
69 );
70
71 const vec4 colors[3] = vec4[3](
72 vec4(1.0f, 0.0f, 0.0f, 1.0f),
73 vec4(0.0f, 1.0f, 0.0f, 1.0f),
74 vec4(0.0f, 0.0f, 1.0f, 1.0f)
75 );
76
77 void main() {
78 vec4 position = positions[gl_VertexIndex];
79 vec4 color = colors[gl_VertexIndex];
80
81 float fade = mod(c.scalarOffset + c.time * c.scalar / 10.0, 1.0);
82 if (fade < 0.5) {
83 fade = fade * 2.0;
84 } else {
85 fade = (1.0 - fade) * 2.0;
86 }
87 float xpos = position.x * c.scale;
88 float ypos = position.y * c.scale;
89 float angle = 3.14159 * 2.0 * fade;
90 float xrot = xpos * cos(angle) - ypos * sin(angle);
91 float yrot = xpos * sin(angle) + ypos * cos(angle);
92 xpos = xrot + c.offsetX;
93 ypos = yrot + c.offsetY;
94 v_color = vec4(fade, 1.0 - fade, 0.0, 1.0) + color;
95 gl_Position = vec4(xpos, ypos, 0.0, 1.0);
96 })"
97 );
98
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040099 nxt::ShaderModule fsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400100 #version 450
101 out vec4 fragColor;
Corentin Wallezca9af202017-06-05 16:23:18 -0400102 layout(location = 0) in vec4 v_color;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400103 void main() {
104 fragColor = v_color;
105 })"
106 );
107
Corentin Wallez5ee7afd2017-06-19 13:09:41 -0400108 utils::CreateDefaultRenderPass(device, &renderpass, &framebuffer);
Corentin Wallez66ff4472017-07-14 11:32:57 -0400109 pipeline = device.CreateRenderPipelineBuilder()
Kai Ninomiya68df8b02017-05-16 14:04:22 -0700110 .SetSubpass(renderpass, 0)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400111 .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
112 .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
113 .GetResult();
114
115 shaderData.resize(10000);
116 for (auto& data : shaderData) {
Corentin Wallez83e779d2017-07-10 21:44:06 -0400117 data.scale = RandomFloat(0.2f, 0.4f);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400118 data.time = 0.0;
Corentin Wallez83e779d2017-07-10 21:44:06 -0400119 data.offsetX = RandomFloat(-0.9f, 0.9f);
120 data.offsetY = RandomFloat(-0.9f, 0.9f);
121 data.scalar = RandomFloat(0.5f, 2.0f);
122 data.scalarOffset = RandomFloat(0.0f, 10.0f);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400123 }
124}
125
126void frame() {
127 static int f = 0;
128 f++;
129
130 size_t i = 0;
131
132 std::vector<nxt::CommandBuffer> commands(50);
133 for (int j = 0; j < 50; j++) {
134
135 nxt::CommandBufferBuilder builder = device.CreateCommandBufferBuilder()
Kai Ninomiya68df8b02017-05-16 14:04:22 -0700136 .BeginRenderPass(renderpass, framebuffer)
Kai Ninomiyafa37f222017-06-29 23:53:08 -0700137 .BeginRenderSubpass()
Corentin Wallez66ff4472017-07-14 11:32:57 -0400138 .SetRenderPipeline(pipeline)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400139 .Clone();
140
141 for (int k = 0; k < 200; k++) {
142
143 shaderData[i].time = f / 60.0f;
144 builder.SetPushConstants(nxt::ShaderStageBit::Vertex, 0, 6, reinterpret_cast<uint32_t*>(&shaderData[i]))
145 .DrawArrays(3, 1, 0, 0);
146 i++;
147 }
148
Kai Ninomiyafa37f222017-06-29 23:53:08 -0700149 builder.EndRenderSubpass();
Kai Ninomiya68df8b02017-05-16 14:04:22 -0700150 builder.EndRenderPass();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400151 commands[j] = builder.GetResult();
152 }
153
154 queue.Submit(50, commands.data());
Corentin Wallez583e9a82017-05-29 11:30:29 -0700155 DoSwapBuffers();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400156 fprintf(stderr, "frame %i\n", f);
157}
158
159int main(int argc, const char* argv[]) {
Corentin Wallez9347e8f2017-06-19 13:15:13 -0400160 if (!InitSample(argc, argv)) {
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400161 return 1;
162 }
163 init();
164
165 while (!ShouldQuit()) {
166 frame();
Corentin Wallez134e0802017-07-17 17:13:57 -0400167 utils::USleep(16000);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400168 }
169
170 // TODO release stuff
171}