blob: ffe328b0d0be3831b7a947a2bed0cad1a7e357b5 [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"
18
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040019#include <vector>
20
21nxt::Device device;
22
23nxt::Buffer indexBuffer;
24nxt::Buffer vertexBuffer;
25
26nxt::Texture texture;
27nxt::Sampler sampler;
28
29nxt::Queue queue;
30nxt::Pipeline pipeline;
Kai Ninomiya68df8b02017-05-16 14:04:22 -070031nxt::RenderPass renderpass;
32nxt::Framebuffer framebuffer;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040033nxt::BindGroup bindGroup;
34
35void initBuffers() {
36 static const uint32_t indexData[3] = {
37 0, 1, 2,
38 };
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040039 indexBuffer = utils::CreateFrozenBufferFromData(device, indexData, sizeof(indexData), nxt::BufferUsageBit::Index);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040040
41 static const float vertexData[12] = {
42 0.0f, 0.5f, 0.0f, 1.0f,
43 -0.5f, -0.5f, 0.0f, 1.0f,
44 0.5f, -0.5f, 0.0f, 1.0f,
45 };
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040046 vertexBuffer = utils::CreateFrozenBufferFromData(device, vertexData, sizeof(vertexData), nxt::BufferUsageBit::Vertex);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040047}
48
49void initTextures() {
50 texture = device.CreateTextureBuilder()
51 .SetDimension(nxt::TextureDimension::e2D)
52 .SetExtent(1024, 1024, 1)
53 .SetFormat(nxt::TextureFormat::R8G8B8A8Unorm)
54 .SetMipLevels(1)
55 .SetAllowedUsage(nxt::TextureUsageBit::TransferDst | nxt::TextureUsageBit::Sampled)
56 .GetResult();
57
58 sampler = device.CreateSamplerBuilder()
59 .SetFilterMode(nxt::FilterMode::Linear, nxt::FilterMode::Linear, nxt::FilterMode::Linear)
60 .GetResult();
61
62 // Initialize the texture with arbitrary data until we can load images
63 std::vector<uint8_t> data(4 * 1024 * 1024, 0);
64 for (size_t i = 0; i < data.size(); ++i) {
65 data[i] = i % 253;
66 }
67
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040068
Corentin Wallez83e779d2017-07-10 21:44:06 -040069 nxt::Buffer stagingBuffer = utils::CreateFrozenBufferFromData(device, data.data(), static_cast<uint32_t>(data.size()), nxt::BufferUsageBit::TransferSrc);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040070 nxt::CommandBuffer copy = device.CreateCommandBufferBuilder()
71 .TransitionTextureUsage(texture, nxt::TextureUsageBit::TransferDst)
Corentin Wallez7f433a52017-05-09 16:57:52 +020072 .CopyBufferToTexture(stagingBuffer, 0, texture, 0, 0, 0, 1024, 1024, 1, 0)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040073 .GetResult();
74
75 queue.Submit(1, &copy);
76 texture.FreezeUsage(nxt::TextureUsageBit::Sampled);
77}
78
79void init() {
Corentin Wallez583e9a82017-05-29 11:30:29 -070080 device = CreateCppNXTDevice();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040081
82 queue = device.CreateQueueBuilder().GetResult();
83
84 initBuffers();
85 initTextures();
86
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040087 nxt::ShaderModule vsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040088 #version 450
89 layout(location = 0) in vec4 pos;
90 void main() {
91 gl_Position = pos;
92 })"
93 );
94
Corentin Wallez5ee7afd2017-06-19 13:09:41 -040095 nxt::ShaderModule fsModule = utils::CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040096 #version 450
97 layout(set = 0, binding = 0) uniform sampler mySampler;
98 layout(set = 0, binding = 1) uniform texture2D myTexture;
99
100 out vec4 fragColor;
101 void main() {
102 fragColor = texture(sampler2D(myTexture, mySampler), gl_FragCoord.xy / vec2(640.0, 480.0));
103 })"
104 );
105
106 auto inputState = device.CreateInputStateBuilder()
107 .SetAttribute(0, 0, nxt::VertexFormat::FloatR32G32B32A32, 0)
108 .SetInput(0, 4 * sizeof(float), nxt::InputStepMode::Vertex)
109 .GetResult();
110
111 nxt::BindGroupLayout bgl = device.CreateBindGroupLayoutBuilder()
112 .SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::Sampler, 0, 1)
113 .SetBindingsType(nxt::ShaderStageBit::Fragment, nxt::BindingType::SampledTexture, 1, 1)
114 .GetResult();
115
116 nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
117 .SetBindGroupLayout(0, bgl)
118 .GetResult();
119
Corentin Wallez5ee7afd2017-06-19 13:09:41 -0400120 utils::CreateDefaultRenderPass(device, &renderpass, &framebuffer);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400121 pipeline = device.CreatePipelineBuilder()
Kai Ninomiya68df8b02017-05-16 14:04:22 -0700122 .SetSubpass(renderpass, 0)
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400123 .SetLayout(pl)
124 .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
125 .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
126 .SetInputState(inputState)
127 .GetResult();
128
129 nxt::TextureView view = texture.CreateTextureViewBuilder().GetResult();
130
131 bindGroup = device.CreateBindGroupBuilder()
132 .SetLayout(bgl)
133 .SetUsage(nxt::BindGroupUsage::Frozen)
134 .SetSamplers(0, 1, &sampler)
135 .SetTextureViews(1, 1, &view)
136 .GetResult();
137}
138
139struct {uint32_t a; float b;} s;
140void frame() {
141 s.a = (s.a + 1) % 256;
Corentin Wallez83e779d2017-07-10 21:44:06 -0400142 s.b += 0.02f;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400143 if (s.b >= 1.0f) {s.b = 0.0f;}
144 static const uint32_t vertexBufferOffsets[1] = {0};
145 nxt::CommandBuffer commands = device.CreateCommandBufferBuilder()
Kai Ninomiya68df8b02017-05-16 14:04:22 -0700146 .BeginRenderPass(renderpass, framebuffer)
Kai Ninomiyafa37f222017-06-29 23:53:08 -0700147 .BeginRenderSubpass()
Kai Ninomiya68df8b02017-05-16 14:04:22 -0700148 .SetPipeline(pipeline)
149 .SetBindGroup(0, bindGroup)
150 .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
151 .SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32)
152 .DrawElements(3, 1, 0, 0)
Kai Ninomiyafa37f222017-06-29 23:53:08 -0700153 .EndRenderSubpass()
Kai Ninomiya68df8b02017-05-16 14:04:22 -0700154 .EndRenderPass()
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400155 .GetResult();
156
157 queue.Submit(1, &commands);
Corentin Wallez583e9a82017-05-29 11:30:29 -0700158 DoSwapBuffers();
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400159}
160
161int main(int argc, const char* argv[]) {
Corentin Wallez9347e8f2017-06-19 13:15:13 -0400162 if (!InitSample(argc, argv)) {
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400163 return 1;
164 }
165 init();
166
167 while (!ShouldQuit()) {
168 frame();
Corentin Wallez583e9a82017-05-29 11:30:29 -0700169 USleep(16000);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400170 }
171
172 // TODO release stuff
173}