Vulkan: Added Push Constants for Common Scene include

This commit is contained in:
korenkonder
2024-08-28 20:19:16 +03:00
parent bae9fe5366
commit e6675e19ad
8 changed files with 169 additions and 65 deletions
+4 -3
View File
@@ -32,7 +32,8 @@ namespace Vulkan {
DescriptorPipeline::DescriptorPipeline(VkDevice device, VkDescriptorPool descriptor_pool,
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
const VkDescriptorSetLayoutBinding* bindings) {
const VkDescriptorSetLayoutBinding* bindings,
uint32_t push_constant_range_count, VkPushConstantRange* push_constant_ranges) {
this->device = device;
this->descriptor_pool = descriptor_pool;
@@ -92,8 +93,8 @@ namespace Vulkan {
pipeline_layout_create_info.flags = 0;
pipeline_layout_create_info.setLayoutCount = set_layout_count;
pipeline_layout_create_info.pSetLayouts = descriptor_set_layouts;
pipeline_layout_create_info.pushConstantRangeCount = 0;
pipeline_layout_create_info.pPushConstantRanges = 0;
pipeline_layout_create_info.pushConstantRangeCount = push_constant_range_count;
pipeline_layout_create_info.pPushConstantRanges = push_constant_ranges;
if (vkCreatePipelineLayout(device, &pipeline_layout_create_info, 0, &pipeline_layout) == VK_SUCCESS)
return;
+2 -1
View File
@@ -34,7 +34,8 @@ namespace Vulkan {
public:
DescriptorPipeline(VkDevice device, VkDescriptorPool descriptor_pool,
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
const VkDescriptorSetLayoutBinding* bindings);
const VkDescriptorSetLayoutBinding* bindings,
uint32_t push_constant_range_count, VkPushConstantRange* push_constant_ranges);
~DescriptorPipeline();
DescriptorSetCollection* GetDescriptorSetCollection(uint32_t frame, uint64_t hash);
+25 -48
View File
@@ -14,29 +14,6 @@
#include <unordered_map>
namespace Vulkan {
enum gl_buffer_flags {
GL_BUFFER_FLAG_NONE = 0x00,
GL_BUFFER_FLAG_MAPPED = 0x01,
GL_BUFFER_FLAG_IMMUTABLE_STORAGE = 0x02,
GL_BUFFER_FLAG_UPDATE_DATA = 0x04,
GL_BUFFER_FLAG_MAP_READ_BIT = 0x08,
GL_BUFFER_FLAG_MAP_WRITE_BIT = 0x10,
GL_BUFFER_FLAG_DYNAMIC_STORAGE_BIT = 0x20,
};
struct gl_buffer {
GLenum target;
gl_buffer_flags flags;
std::vector<uint8_t> data;
gl_buffer();
~gl_buffer();
gl_buffer& operator=(const gl_buffer& other);
static gl_buffer* get(GLuint buffer);
};
struct gl_texture_data {
struct tex_data {
std::vector<uint8_t> data;
@@ -229,6 +206,31 @@ namespace Vulkan {
static void gl_wrap_manager_vertex_attrib_pointer(GLuint index, GLint size,
GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
gl_buffer::gl_buffer() : target(), flags() {
}
gl_buffer::~gl_buffer() {
}
gl_buffer& gl_buffer::operator=(const gl_buffer& other) {
target = other.target;
flags = other.flags;
data.assign(other.data.begin(), other.data.end());
return *this;
}
gl_buffer* gl_buffer::get(GLuint buffer) {
if (!buffer)
return 0;
auto elem = gl_wrap_manager_ptr->gl_buffers.find(buffer);
if (elem != gl_wrap_manager_ptr->gl_buffers.end())
return &elem->second;
return 0;
}
gl_framebuffer::gl_framebuffer() : render_pass(), color_attachments(),
color_attachment_levels(), depth_attachment(), depth_attachment_level(),
draw_buffers(), update_color_attachment(), update_depth_attachment(), update_framebuffer() {
@@ -1286,31 +1288,6 @@ namespace Vulkan {
}
}
gl_buffer::gl_buffer() : target(), flags() {
}
gl_buffer::~gl_buffer() {
}
gl_buffer& gl_buffer::operator=(const gl_buffer& other) {
target = other.target;
flags = other.flags;
data.assign(other.data.begin(), other.data.end());
return *this;
}
gl_buffer* gl_buffer::get(GLuint buffer) {
if (!buffer)
return 0;
auto elem = gl_wrap_manager_ptr->gl_buffers.find(buffer);
if (elem != gl_wrap_manager_ptr->gl_buffers.end())
return &elem->second;
return 0;
}
gl_texture_data::tex_data::tex_data() {
}
+23
View File
@@ -27,6 +27,29 @@ namespace Vulkan {
constexpr uint32_t MAX_COLOR_ATTACHMENTS = 8;
constexpr uint32_t MAX_DRAW_BUFFERS = 8;
constexpr uint32_t MAX_VERTEX_ATTRIB_COUNT = 16;
enum gl_buffer_flags {
GL_BUFFER_FLAG_NONE = 0x00,
GL_BUFFER_FLAG_MAPPED = 0x01,
GL_BUFFER_FLAG_IMMUTABLE_STORAGE = 0x02,
GL_BUFFER_FLAG_UPDATE_DATA = 0x04,
GL_BUFFER_FLAG_MAP_READ_BIT = 0x08,
GL_BUFFER_FLAG_MAP_WRITE_BIT = 0x10,
GL_BUFFER_FLAG_DYNAMIC_STORAGE_BIT = 0x20,
};
struct gl_buffer {
GLenum target;
gl_buffer_flags flags;
std::vector<uint8_t> data;
gl_buffer();
~gl_buffer();
gl_buffer& operator=(const gl_buffer& other);
static gl_buffer* get(GLuint buffer);
};
struct gl_framebuffer {
Vulkan::Framebuffer framebuffer;
+10 -5
View File
@@ -201,7 +201,8 @@ namespace Vulkan {
prj::shared_ptr<Vulkan::DescriptorPipeline> get_descriptor_pipeline(
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
const VkDescriptorSetLayoutBinding* bindings);
const VkDescriptorSetLayoutBinding* bindings,
uint32_t push_constant_range_count, VkPushConstantRange* push_constant_ranges);
frame_data& get_frame_data();
prj::shared_ptr<Vulkan::Pipeline> get_pipeline(uint32_t stage_count,
const VkPipelineShaderStageCreateInfo* stages,
@@ -265,9 +266,11 @@ namespace Vulkan {
prj::shared_ptr<Vulkan::DescriptorPipeline> manager_get_descriptor_pipeline(
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
const VkDescriptorSetLayoutBinding* bindings) {
const VkDescriptorSetLayoutBinding* bindings,
uint32_t push_constant_range_count, VkPushConstantRange* push_constant_ranges) {
return manager_ptr->get_descriptor_pipeline(vp_desc_hash, fp_desc_hash, unival_hash,
sampler_count, uniform_count, storage_count, bindings);
sampler_count, uniform_count, storage_count, bindings,
push_constant_range_count, push_constant_ranges);
}
uint32_t manager_get_frame() {
@@ -427,14 +430,16 @@ namespace Vulkan {
prj::shared_ptr<Vulkan::DescriptorPipeline> manager::get_descriptor_pipeline(
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
const VkDescriptorSetLayoutBinding* bindings) {
const VkDescriptorSetLayoutBinding* bindings,
uint32_t push_constant_range_count, VkPushConstantRange* push_constant_ranges) {
auto elem = descriptor_pipelines.find({ vp_desc_hash, fp_desc_hash, unival_hash });
if (elem != descriptor_pipelines.end())
return elem->second;
prj::shared_ptr<Vulkan::DescriptorPipeline> descriptor_pipeline(
new Vulkan::DescriptorPipeline(Vulkan::current_device, Vulkan::current_descriptor_pool,
sampler_count, uniform_count, storage_count, bindings));
sampler_count, uniform_count, storage_count,
bindings, push_constant_range_count, push_constant_ranges));
descriptor_pipelines.insert({ { vp_desc_hash, fp_desc_hash, unival_hash }, descriptor_pipeline });
return descriptor_pipeline;
}
+2 -1
View File
@@ -27,7 +27,8 @@ namespace Vulkan {
extern prj::shared_ptr<Vulkan::DescriptorPipeline> manager_get_descriptor_pipeline(
uint64_t vp_desc_hash, uint64_t fp_desc_hash, uint64_t unival_hash,
uint32_t sampler_count, uint32_t uniform_count, uint32_t storage_count,
const VkDescriptorSetLayoutBinding* bindings);
const VkDescriptorSetLayoutBinding* bindings,
uint32_t push_constant_range_count, VkPushConstantRange* push_constant_ranges);
extern uint32_t manager_get_frame();
extern prj::shared_ptr<Vulkan::Pipeline> manager_get_pipeline(uint32_t stage_count,
const VkPipelineShaderStageCreateInfo* stages,
+102 -6
View File
@@ -123,6 +123,16 @@ static void parse_define_inner(std::string& temp, bool vulkan) {
temp.replace(pos, 11, "gl_VertexIndex");
off = pos + 14;
}
off = 0;
while (true) {
size_t pos = temp.find("layout(set = 1, binding = 0) uniform Shader", off);
if (pos == -1)
break;
temp.replace(pos, 43, "layout(push_constant) uniform Shader");
off = pos + 36;
}
}
}
@@ -1373,6 +1383,7 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
uint32_t sampler_count = 0;
uint32_t uniform_count = 0;
uint32_t storage_count = 0;
uint32_t push_constant_range_count = 0;
uint32_t fragment_output_count = 0;
bool enabled_attributes[Vulkan::MAX_VERTEX_ATTRIB_COUNT] = {};
@@ -1394,7 +1405,10 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
sampler_count++;
break;
case SHADER_DESCRIPTION_UNIFORM:
uniform_count++;
if (desc->binding == -1)
push_constant_range_count++;
else
uniform_count++;
break;
case SHADER_DESCRIPTION_STORAGE:
storage_count++;
@@ -1414,7 +1428,10 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
sampler_count++;
break;
case SHADER_DESCRIPTION_UNIFORM:
uniform_count++;
if (desc->binding == -1)
push_constant_range_count++;
else
uniform_count++;
break;
case SHADER_DESCRIPTION_STORAGE:
storage_count++;
@@ -1440,13 +1457,16 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
const uint32_t storage_max_count = storage_count;
VkDescriptorSetLayoutBinding* bindings = force_malloc<VkDescriptorSetLayoutBinding>(
(size_t)sampler_max_count + uniform_max_count + storage_max_count);
(size_t)sampler_max_count + uniform_max_count + storage_max_count + push_constant_range_count);
VkDescriptorSetLayoutBinding* sampler_bindings = bindings;
VkDescriptorSetLayoutBinding* uniform_bindings = bindings + sampler_max_count;
VkDescriptorSetLayoutBinding* uniform_bindings = sampler_bindings + sampler_max_count;
VkDescriptorSetLayoutBinding* storage_bindings = bindings + sampler_max_count + uniform_max_count;
VkPushConstantRange* push_constant_ranges = (VkPushConstantRange*)(bindings
+ sampler_max_count + uniform_max_count + storage_max_count);
VkDescriptorSetLayoutBinding* sampler_binding = sampler_bindings;
VkDescriptorSetLayoutBinding* uniform_binding = uniform_bindings;
VkDescriptorSetLayoutBinding* storage_binding = storage_bindings;
VkPushConstantRange* push_constant_range = push_constant_ranges;
vp_desc = set->vp_desc;
while (vp_desc->type != SHADER_DESCRIPTION_NONE && vp_desc->type != SHADER_DESCRIPTION_END
@@ -1476,6 +1496,24 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
}
break;
case SHADER_DESCRIPTION_UNIFORM:
if (desc->binding == -1) {
push_constant_range_count = (uint32_t)(push_constant_range - push_constant_ranges);
for (uint32_t i = 0; i < push_constant_range_count; i++)
if (push_constant_ranges[i].size == desc->data) {
push_constant_ranges[i].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
found = true;
break;
}
if (!found && !push_constant_range_count) {
push_constant_range->stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
push_constant_range->offset = 0;
push_constant_range->size = desc->data;
push_constant_range++;
}
break;
}
uniform_count = (uint32_t)(uniform_binding - uniform_bindings);
for (uint32_t i = 0; i < uniform_count; i++)
if (uniform_bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
@@ -1543,6 +1581,24 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
}
break;
case SHADER_DESCRIPTION_UNIFORM:
if (desc->binding == -1) {
push_constant_range_count = (uint32_t)(push_constant_range - push_constant_ranges);
for (uint32_t i = 0; i < push_constant_range_count; i++)
if (push_constant_ranges[i].size == desc->data) {
push_constant_ranges[i].stageFlags |= VK_SHADER_STAGE_FRAGMENT_BIT;
found = true;
break;
}
if (!found && !push_constant_range_count) {
push_constant_range->stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
push_constant_range->offset = 0;
push_constant_range->size = desc->data;
push_constant_range++;
}
break;
}
uniform_count = (uint32_t)(uniform_binding - uniform_bindings);
for (uint32_t i = 0; i < uniform_count; i++)
if (uniform_bindings[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
@@ -1586,6 +1642,7 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
sampler_count = (uint32_t)(sampler_binding - sampler_bindings);
uniform_count = (uint32_t)(uniform_binding - uniform_bindings);
storage_count = (uint32_t)(storage_binding - storage_bindings);
push_constant_range_count = (uint32_t)(push_constant_range - push_constant_ranges);
if (uniform_count)
memmove(bindings + sampler_count,
@@ -1595,10 +1652,15 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
memmove(bindings + sampler_count + uniform_count,
bindings + sampler_max_count + uniform_max_count,
storage_count * sizeof(VkDescriptorSetLayoutBinding));
if (push_constant_range_count)
memmove(bindings + sampler_count + uniform_count + storage_count,
bindings + sampler_max_count + uniform_max_count + storage_max_count,
push_constant_range_count * sizeof(VkPushConstantRange));
descriptor_pipeline
= Vulkan::manager_get_descriptor_pipeline(vp_desc_hash, fp_desc_hash, unival_hash,
sampler_count, uniform_count, storage_count, bindings);
sampler_count, uniform_count, storage_count,
bindings, push_constant_range_count, push_constant_ranges);
free_def(bindings);
}
@@ -1781,7 +1843,7 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
free_def(color_blend_attachments);
if (sampler_count + uniform_count + storage_count) {
if (sampler_count + uniform_count + storage_count + push_constant_range_count) {
size_t descriptor_infos_size = sizeof(VkDescriptorImageInfo) * sampler_count
+ sizeof(VkDescriptorBufferInfo) * ((size_t)uniform_count + storage_count)
+ sizeof(uint32_t) * ((size_t)sampler_count + uniform_count + storage_count);
@@ -1805,6 +1867,10 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
uint32_t* storage_info_bindings = (uint32_t*)(uniform_info_bindings + uniform_count);
uint32_t* storage_info_binding = storage_info_bindings;
uint8_t* push_constant_data = 0;
uint32_t push_constant_data_size = 0;
VkShaderStageFlags push_constant_stage_flags = 0;
vp_desc = set->vp_desc;
while (vp_desc->type != SHADER_DESCRIPTION_NONE && vp_desc->type != SHADER_DESCRIPTION_END
&& vp_desc->type != SHADER_DESCRIPTION_MAX) {
@@ -1860,6 +1926,19 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
}
break;
case SHADER_DESCRIPTION_UNIFORM:
if (desc->binding == -1) {
Vulkan::gl_buffer* vk_buf = Vulkan::gl_buffer::get(gl_state.uniform_buffer_bindings[0]);
if (!vk_buf)
break;
if (!push_constant_data) {
push_constant_data = vk_buf->data.data();
push_constant_data_size = (uint32_t)vk_buf->data.size();
}
push_constant_stage_flags |= VK_SHADER_STAGE_VERTEX_BIT;
break;
}
uniform_count = (uint32_t)(uniform_info - uniform_infos);
for (uint32_t i = 0; i < uniform_count; i++)
if (uniform_info_bindings[i] == desc->binding) {
@@ -1965,6 +2044,19 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
}
break;
case SHADER_DESCRIPTION_UNIFORM:
if (desc->binding == -1) {
Vulkan::gl_buffer* vk_buf = Vulkan::gl_buffer::get(gl_state.uniform_buffer_bindings[0]);
if (!vk_buf)
break;
if (!push_constant_data) {
push_constant_data = vk_buf->data.data();
push_constant_data_size = (uint32_t)vk_buf->data.size();
}
push_constant_stage_flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
break;
}
uniform_count = (uint32_t)(uniform_info - uniform_infos);
for (uint32_t i = 0; i < uniform_count; i++)
if (uniform_info_bindings[i] == desc->binding) {
@@ -2108,6 +2200,10 @@ static bool shader_update_data(shader_set_data* set, GLenum mode, GLenum type, c
free_def(descriptor_writes);
}
if (push_constant_stage_flags && push_constant_data_size)
vkCmdPushConstants(Vulkan::current_command_buffer, pipeline_layout,
push_constant_stage_flags, 0, push_constant_data_size, push_constant_data);
free_def(descriptor_infos);
vkCmdBindDescriptorSets(Vulkan::current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
+1 -1
View File
@@ -708,7 +708,7 @@ static const int32_t transparency_fpt_unival_max[] = {
{ SHADER_DESCRIPTION_SAMPLER, 14, 0, U_INVALID, }
#define SHADER_DESCRIPTION_COMMON_SCENE \
{ SHADER_DESCRIPTION_UNIFORM, 0, sizeof(obj_shader_shader_data), U_INVALID, }, \
{ SHADER_DESCRIPTION_UNIFORM, -1, sizeof(obj_shader_shader_data), U_INVALID, }, \
{ SHADER_DESCRIPTION_UNIFORM, 1, sizeof(obj_scene_shader_data), U_INVALID, }, \
{ SHADER_DESCRIPTION_UNIFORM, 2, sizeof(obj_batch_shader_data), U_INVALID, }