WIP: Vulkan: Initial Immediate Mode Support. #106954

Closed
Jeroen Bakker wants to merge 27 commits from Jeroen-Bakker:vulkan-immediate into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
10 changed files with 85 additions and 12 deletions
Showing only changes of commit 1e0b6a4707 - Show all commits

View File

@ -14,7 +14,7 @@
namespace blender::gpu::tests {
const size_t Size = 512;
static void test_offscreen_draw_batch()
static void test_offscreen_draw_batch_quad()
{
GPUOffScreen *offscreen = GPU_offscreen_create(Size, Size, false, GPU_RGBA16F, nullptr);
BLI_assert(offscreen != nullptr);
@ -38,6 +38,31 @@ static void test_offscreen_draw_batch()
GPU_offscreen_free(offscreen);
DRW_shape_cache_free();
}
GPU_TEST(offscreen_draw_batch);
GPU_TEST(offscreen_draw_batch_quad);
static void test_offscreen_draw_batch_sphere()
{
GPUOffScreen *offscreen = GPU_offscreen_create(Size, Size, false, GPU_RGBA16F, nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
GPUBatch *batch = DRW_cache_sphere_get(DRW_LOD_MEDIUM);
float4 color(1.0f, 0.5f, 0.0f, 1.0f);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GPU_batch_uniform_4fv(batch, "color", color);
GPU_matrix_push();
GPU_matrix_scale_1f(0.5f);
GPU_matrix_rotate_2d(45.0f);
GPU_batch_draw(batch);
GPU_offscreen_unbind(offscreen, false);
GPU_flush();
GPU_matrix_pop();
GPU_offscreen_free(offscreen);
DRW_shape_cache_free();
}
GPU_TEST(offscreen_draw_batch_sphere);
} // namespace blender::gpu::tests

View File

@ -24,7 +24,7 @@ void VKBatch::draw(int v_first, int v_count, int i_first, int i_count)
VKContext &context = *VKContext::get();
VKVertexAttributeObject &vao = vao_cache_.vao_get(this);
vao.update_bindings(context, *this);
context.bind_graphics_pipeline(vao);
context.bind_graphics_pipeline(*this, vao);
vao.bind(context);
VKIndexBuffer *index_buffer = index_buffer_get();

View File

@ -484,4 +484,38 @@ VkIndexType to_vk_index_type(const GPUIndexBufType index_type)
return VK_INDEX_TYPE_UINT16;
}
VkPrimitiveTopology to_vk_primitive_topology(const GPUPrimType prim_type)
{
switch (prim_type) {
case GPU_PRIM_POINTS:
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case GPU_PRIM_LINES:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case GPU_PRIM_TRIS:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case GPU_PRIM_LINE_STRIP:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case GPU_PRIM_LINE_LOOP:
/* TODO: Line loop should add an additional index?*/
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case GPU_PRIM_TRI_STRIP:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
case GPU_PRIM_TRI_FAN:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case GPU_PRIM_LINES_ADJ:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
case GPU_PRIM_TRIS_ADJ:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
case GPU_PRIM_LINE_STRIP_ADJ:
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
case GPU_PRIM_NONE:
break;
}
BLI_assert_unreachable();
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
}
} // namespace blender::gpu

View File

@ -28,5 +28,6 @@ VkImageViewType to_vk_image_view_type(const eGPUTextureType type);
VkImageType to_vk_image_type(const eGPUTextureType type);
VkClearColorValue to_vk_clear_color_value(const eGPUDataFormat format, const void *data);
VkIndexType to_vk_index_type(const GPUIndexBufType index_type);
VkPrimitiveTopology to_vk_primitive_topology(const GPUPrimType prim_type);
} // namespace blender::gpu

View File

@ -182,11 +182,12 @@ void VKContext::deactivate_framebuffer()
/** \name Graphics pipeline
* \{ */
void VKContext::bind_graphics_pipeline(const VKVertexAttributeObject &vertex_attribute_object)
void VKContext::bind_graphics_pipeline(const VKBatch &batch,
const VKVertexAttributeObject &vertex_attribute_object)
{
VKShader *shader = unwrap(this->shader);
BLI_assert(shader);
shader->update_graphics_pipeline(*this, vertex_attribute_object);
shader->update_graphics_pipeline(*this, batch, vertex_attribute_object);
command_buffer_get().bind(shader->pipeline_get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
shader->pipeline_get().push_constants_get().update(*this);
}

View File

@ -15,6 +15,7 @@
namespace blender::gpu {
class VKFrameBuffer;
class VKVertexAttributeObject;
class VKBatch;
class VKContext : public Context {
private:
@ -62,7 +63,8 @@ class VKContext : public Context {
void deactivate_framebuffer();
VKFrameBuffer *active_framebuffer_get() const;
void bind_graphics_pipeline(const VKVertexAttributeObject &vertex_attribute_object);
void bind_graphics_pipeline(const VKBatch &batch,
const VKVertexAttributeObject &vertex_attribute_object);
static VKContext *get(void)
{

View File

@ -6,6 +6,7 @@
*/
#include "vk_pipeline.hh"
#include "vk_batch.hh"
#include "vk_context.hh"
#include "vk_framebuffer.hh"
#include "vk_memory.hh"
@ -92,6 +93,7 @@ void VKPipeline::finalize(VKContext &context,
VkShaderModule vertex_module,
VkShaderModule fragment_module,
VkPipelineLayout &pipeline_layout,
const VKBatch &batch,
const VKVertexAttributeObject &vertex_attribute_object)
{
BLI_assert(vertex_module != VK_NULL_HANDLE);
@ -137,16 +139,18 @@ void VKPipeline::finalize(VKContext &context,
VkPipelineVertexInputStateCreateInfo vertex_input_state = {};
vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertex_input_state.vertexBindingDescriptionCount = 0;
vertex_input_state.vertexBindingDescriptionCount = 1;//vertex_attribute_object.bindings.size();
vertex_input_state.vertexBindingDescriptionCount =
1; // vertex_attribute_object.bindings.size();
vertex_input_state.pVertexBindingDescriptions = vertex_attribute_object.bindings.data();
vertex_input_state.vertexAttributeDescriptionCount = 1;//vertex_attribute_object.attributes.size();
vertex_input_state.vertexAttributeDescriptionCount =
1; // vertex_attribute_object.attributes.size();
vertex_input_state.pVertexAttributeDescriptions = vertex_attribute_object.attributes.data();
pipeline_create_info.pVertexInputState = &vertex_input_state;
/* Input assembly state. */
VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly = {};
pipeline_input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
pipeline_input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
pipeline_input_assembly.topology = to_vk_primitive_topology(batch.prim_type);
pipeline_create_info.pInputAssemblyState = &pipeline_input_assembly;
VkPipelineRasterizationStateCreateInfo rasterization_state = {};

View File

@ -20,6 +20,7 @@ namespace blender::gpu {
class VKContext;
class VKShader;
class VKVertexAttributeObject;
class VKBatch;
/**
* Pipeline can be a compute pipeline or a graphic pipeline.
@ -77,7 +78,8 @@ class VKPipeline : NonCopyable {
VkShaderModule vertex_module,
VkShaderModule fragment_module,
VkPipelineLayout &pipeline_layout,
const VKVertexAttributeObject &vertex_attribute_object);
const VKBatch &batch,
const VKVertexAttributeObject &vertex_attribute_object);
};
} // namespace blender::gpu

View File

@ -932,10 +932,13 @@ bool VKShader::transform_feedback_enable(GPUVertBuf *)
void VKShader::transform_feedback_disable() {}
void VKShader::update_graphics_pipeline(VKContext &context, const VKVertexAttributeObject &vertex_attribute_object)
void VKShader::update_graphics_pipeline(VKContext &context,
const VKBatch &batch,
const VKVertexAttributeObject &vertex_attribute_object)
{
BLI_assert(is_graphics_shader());
pipeline_get().finalize(context, vertex_module_, fragment_module_, pipeline_layout_, vertex_attribute_object);
pipeline_get().finalize(
context, vertex_module_, fragment_module_, pipeline_layout_, batch, vertex_attribute_object);
}
void VKShader::bind()

View File

@ -71,6 +71,7 @@ class VKShader : public Shader {
const VKShaderInterface &interface_get() const;
void update_graphics_pipeline(VKContext &context,
const VKBatch &batch,
const VKVertexAttributeObject &vertex_attribute_object);
private: