52c7c2dab6
- Determine sizing and alignments of pointers to types as distinct from the size and alignment of the types themselves. - Declare all buffer pointers in the MSL device address space. - Support struct pointer recursion, where structs can contain pointers to themselves or to a parent struct. - Add SPIRType::was_forward_referenced to track if a type was forward referenced, to help emit MSL structs in the correct dependency order. - Handle pointers to pointers that are not just arrays of arrays.
84 lines
3.1 KiB
GLSL
84 lines
3.1 KiB
GLSL
/* Copyright (c) 2021, Arm Limited and Contributors
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 the "License";
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#version 450
|
|
|
|
// Allows buffer_reference.
|
|
#extension GL_EXT_buffer_reference : require
|
|
|
|
// Since we did not enable vertexPipelineStoresAndAtomics, we must mark everything readonly.
|
|
layout(std430, buffer_reference, buffer_reference_align = 8) readonly buffer Position
|
|
{
|
|
vec2 positions[];
|
|
};
|
|
|
|
layout(std430, buffer_reference, buffer_reference_align = 8) readonly buffer PositionReferences
|
|
{
|
|
// Represents an array of pointers, where each pointer points to its own VBO (Position).
|
|
// The size of a pointer (VkDeviceAddress) is always 8 in Vulkan.
|
|
Position buffers[];
|
|
};
|
|
|
|
layout(push_constant) uniform Registers
|
|
{
|
|
mat4 view_projection;
|
|
|
|
// This is a pointer to an array of pointers, essentially:
|
|
// const VBO * const *vbos
|
|
PositionReferences references;
|
|
} registers;
|
|
|
|
// Flat shading looks a little cooler here :)
|
|
layout(location = 0) flat out vec4 out_color;
|
|
|
|
void main()
|
|
{
|
|
int slice = gl_InstanceIndex;
|
|
|
|
// One VBO per instance, load the VBO pointer.
|
|
// The cool thing here is that a compute shader could hypothetically
|
|
// write the pointer list where vertices are stored.
|
|
// With vertex attributes we do not have the luxury to modify VBO bindings on the GPU.
|
|
// The best we can do is to just modify the vertexOffset in an indirect draw call,
|
|
// but that's not always flexible enough, and enforces a very specific engine design to work.
|
|
// We can even modify the attribute layout per slice here, since we can just cast the pointer
|
|
// to something else if we want.
|
|
restrict Position positions = registers.references.buffers[slice];
|
|
|
|
// Load the vertex based on VertexIndex instead of an attribute. Fully flexible.
|
|
// Only downside is that we do not get format conversion for free like we do with normal vertex attributes.
|
|
vec2 pos = positions.positions[gl_VertexIndex] * 2.5;
|
|
|
|
// Place the quad meshes on screen and center it.
|
|
pos += 3.0 * (vec2(slice % 8, slice / 8) - 3.5);
|
|
|
|
// Normal projection.
|
|
gl_Position = registers.view_projection * vec4(pos, 0.0, 1.0);
|
|
|
|
// Color the vertex. Use a combination of a wave and checkerboard, completely arbitrary.
|
|
int index_x = gl_VertexIndex % 16;
|
|
int index_y = gl_VertexIndex / 16;
|
|
|
|
float r = 0.5 + 0.3 * sin(float(index_x));
|
|
float g = 0.5 + 0.3 * sin(float(index_y));
|
|
|
|
int checkerboard = (index_x ^ index_y) & 1;
|
|
r *= float(checkerboard) * 0.8 + 0.2;
|
|
g *= float(checkerboard) * 0.8 + 0.2;
|
|
|
|
out_color = vec4(r, g, 0.15, 1.0);
|
|
}
|