gpu: Hook up immutable samplers to shaders
Define an array with a compile-time-constant variable size for the immutable samplers. A bunch of work is necessary to ensure that at least one element is in the sampler array, because the GLSL code sampler2D immutable_textures[0]; is invalid.
This commit is contained in:
@@ -743,6 +743,7 @@ typedef struct _GskVulkanShaderSpecialization GskVulkanShaderSpecialization;
|
||||
struct _GskVulkanShaderSpecialization
|
||||
{
|
||||
guint32 clip;
|
||||
guint32 n_immutable_samplers;
|
||||
};
|
||||
|
||||
VkPipeline
|
||||
@@ -784,17 +785,23 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.module = gdk_display_get_vk_shader_module (display, vertex_shader_name),
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = &(VkSpecializationInfo) {
|
||||
.mapEntryCount = 1,
|
||||
.pMapEntries = (VkSpecializationMapEntry[1]) {
|
||||
.mapEntryCount = 2,
|
||||
.pMapEntries = (VkSpecializationMapEntry[2]) {
|
||||
{
|
||||
.constantID = 0,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, clip),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
{
|
||||
.constantID = 1,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_immutable_samplers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
},
|
||||
.dataSize = sizeof (GskVulkanShaderSpecialization),
|
||||
.pData = &(GskVulkanShaderSpecialization) {
|
||||
.clip = clip,
|
||||
.n_immutable_samplers = layout->n_samplers,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -804,17 +811,23 @@ gsk_vulkan_device_get_vk_pipeline (GskVulkanDevice *self,
|
||||
.module = gdk_display_get_vk_shader_module (display, fragment_shader_name),
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = &(VkSpecializationInfo) {
|
||||
.mapEntryCount = 1,
|
||||
.pMapEntries = (VkSpecializationMapEntry[1]) {
|
||||
.mapEntryCount = 2,
|
||||
.pMapEntries = (VkSpecializationMapEntry[2]) {
|
||||
{
|
||||
.constantID = 0,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, clip),
|
||||
.size = sizeof (guint32),
|
||||
}
|
||||
},
|
||||
{
|
||||
.constantID = 1,
|
||||
.offset = G_STRUCT_OFFSET (GskVulkanShaderSpecialization, n_immutable_samplers),
|
||||
.size = sizeof (guint32),
|
||||
},
|
||||
},
|
||||
.dataSize = sizeof (GskVulkanShaderSpecialization),
|
||||
.pData = &(GskVulkanShaderSpecialization) {
|
||||
.clip = clip,
|
||||
.n_immutable_samplers = layout->n_samplers,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -899,6 +912,16 @@ gsk_vulkan_device_acquire_pipeline_layout (GskVulkanDevice *self,
|
||||
gsize n_immutable_samplers)
|
||||
{
|
||||
GskVulkanPipelineLayout *layout;
|
||||
VkSampler fallback[2];
|
||||
|
||||
/* It's mandatory to have at least 1 sampler, because GLSL can't deal with 0-sized arrays */
|
||||
if (n_immutable_samplers == 0)
|
||||
{
|
||||
fallback[0] = gsk_vulkan_device_get_vk_sampler (self, GSK_GPU_SAMPLER_DEFAULT);
|
||||
fallback[1] = NULL;
|
||||
immutable_samplers = fallback;
|
||||
n_immutable_samplers = 1;
|
||||
}
|
||||
|
||||
/* We require null-termination for the hash table lookup */
|
||||
g_assert (immutable_samplers[n_immutable_samplers] == NULL);
|
||||
|
||||
@@ -155,6 +155,7 @@ gsk_vulkan_frame_add_image (GskVulkanFrame *self,
|
||||
|
||||
result = gsk_descriptor_image_infos_get_size (&self->descriptor_images);
|
||||
g_assert (result < gsk_vulkan_device_get_max_descriptors (device));
|
||||
result = result << 1;
|
||||
|
||||
gsk_descriptor_image_infos_append (&self->descriptor_images,
|
||||
&(VkDescriptorImageInfo) {
|
||||
@@ -292,7 +293,7 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame,
|
||||
}
|
||||
|
||||
self->pipeline_layout = gsk_vulkan_device_acquire_pipeline_layout (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)),
|
||||
(VkSampler[1]) { NULL },
|
||||
NULL,
|
||||
0);
|
||||
GSK_VK_CHECK (vkBeginCommandBuffer, self->vk_command_buffer,
|
||||
&(VkCommandBufferBeginInfo) {
|
||||
|
||||
@@ -9,6 +9,7 @@ layout(push_constant) uniform PushConstants {
|
||||
} push;
|
||||
|
||||
layout(constant_id=0) const uint GSK_SHADER_CLIP = GSK_GPU_SHADER_CLIP_NONE;
|
||||
layout(constant_id=1) const uint GSK_IMMUTABLE_SAMPLERS = 1;
|
||||
|
||||
#define GSK_GLOBAL_MVP push.mvp
|
||||
#define GSK_GLOBAL_CLIP push.clip
|
||||
@@ -28,6 +29,7 @@ layout(constant_id=0) const uint GSK_SHADER_CLIP = GSK_GPU_SHADER_CLIP_NONE;
|
||||
#define PASS(_loc) layout(location = _loc) in
|
||||
#define PASS_FLAT(_loc) layout(location = _loc) flat in
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D immutable_textures[GSK_IMMUTABLE_SAMPLERS];
|
||||
layout(set = 0, binding = 1) uniform sampler2D textures[50000];
|
||||
layout(set = 1, binding = 0) readonly buffer FloatBuffers {
|
||||
float floats[];
|
||||
@@ -35,7 +37,16 @@ layout(set = 1, binding = 0) readonly buffer FloatBuffers {
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
#define gsk_texture(id, pos) texture (textures[nonuniformEXT (id)], pos)
|
||||
vec4
|
||||
gsk_texture (uint id,
|
||||
vec2 pos)
|
||||
{
|
||||
if ((id & 1) != 0)
|
||||
return texture (immutable_textures[nonuniformEXT (id >> 1)], pos);
|
||||
|
||||
return texture (textures[nonuniformEXT (id >> 1)], pos);
|
||||
}
|
||||
|
||||
#define gsk_get_buffer(id) buffers[nonuniformEXT (id)]
|
||||
#define gsk_get_float(id) gsk_get_buffer(0).floats[id]
|
||||
#define gsk_get_int(id) (floatBitsToInt(gsk_get_float(id)))
|
||||
|
||||
Reference in New Issue
Block a user