Implement Specialization Constants
* Added support to our local copy of SpirV Reflect (which does not support it). * Pass them on render or compute pipeline creation. * Not implemented in our shaders yet.
This commit is contained in:
parent
fb3961b2ef
commit
b2f6db7aa8
12 changed files with 789 additions and 16 deletions
|
|
@ -221,7 +221,36 @@ Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t
|
|||
return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_post_barrier);
|
||||
}
|
||||
|
||||
RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass) {
|
||||
static Vector<RenderingDevice::PipelineSpecializationConstant> _get_spec_constants(const TypedArray<RDPipelineSpecializationConstant> &p_constants) {
|
||||
Vector<RenderingDevice::PipelineSpecializationConstant> ret;
|
||||
ret.resize(p_constants.size());
|
||||
for (int i = 0; i < p_constants.size(); i++) {
|
||||
Ref<RDPipelineSpecializationConstant> c = p_constants[i];
|
||||
ERR_CONTINUE(c.is_null());
|
||||
RenderingDevice::PipelineSpecializationConstant &sc = ret.write[i];
|
||||
Variant value = c->get_value();
|
||||
switch (value.get_type()) {
|
||||
case Variant::BOOL: {
|
||||
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
|
||||
sc.bool_value = value;
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
|
||||
sc.int_value = value;
|
||||
} break;
|
||||
case Variant::FLOAT: {
|
||||
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
|
||||
sc.float_value = value;
|
||||
} break;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
sc.constant_id = c->get_constant_id();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants) {
|
||||
PipelineRasterizationState rasterization_state;
|
||||
if (p_rasterization_state.is_valid()) {
|
||||
rasterization_state = p_rasterization_state->base;
|
||||
|
|
@ -252,7 +281,11 @@ RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p
|
|||
}
|
||||
}
|
||||
|
||||
return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags, p_for_render_pass);
|
||||
return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags, p_for_render_pass, _get_spec_constants(p_specialization_constants));
|
||||
}
|
||||
|
||||
RID RenderingDevice::_compute_pipeline_create(RID p_shader, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants = TypedArray<RDPipelineSpecializationConstant>()) {
|
||||
return compute_pipeline_create(p_shader, _get_spec_constants(p_specialization_constants));
|
||||
}
|
||||
|
||||
Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray<RID> &p_storage_textures) {
|
||||
|
|
@ -348,10 +381,10 @@ void RenderingDevice::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::buffer_clear, DEFVAL(BARRIER_MASK_ALL));
|
||||
ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags", "for_render_pass", "specialization_constants"), &RenderingDevice::_render_pipeline_create, DEFVAL(0), DEFVAL(0), DEFVAL(TypedArray<RDPipelineSpecializationConstant>()));
|
||||
ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create);
|
||||
ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader", "specialization_constants"), &RenderingDevice::_compute_pipeline_create, DEFVAL(TypedArray<RDPipelineSpecializationConstant>()));
|
||||
ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||
|
|
@ -853,6 +886,10 @@ void RenderingDevice::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL);
|
||||
BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL);
|
||||
|
||||
BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL);
|
||||
BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT);
|
||||
BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT);
|
||||
|
||||
BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS);
|
||||
BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS);
|
||||
BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class RDPipelineMultisampleState;
|
|||
class RDPipelineDepthStencilState;
|
||||
class RDPipelineColorBlendState;
|
||||
class RDFramebufferPass;
|
||||
class RDPipelineSpecializationConstant;
|
||||
|
||||
class RenderingDevice : public Object {
|
||||
GDCLASS(RenderingDevice, Object)
|
||||
|
|
@ -722,6 +723,32 @@ public:
|
|||
virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
|
||||
virtual Vector<uint8_t> buffer_get_data(RID p_buffer) = 0; //this causes stall, only use to retrieve large buffers for saving
|
||||
|
||||
/******************************************/
|
||||
/**** PIPELINE SPECIALIZATION CONSTANT ****/
|
||||
/******************************************/
|
||||
|
||||
enum PipelineSpecializationConstantType {
|
||||
PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL,
|
||||
PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT,
|
||||
PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT,
|
||||
};
|
||||
|
||||
struct PipelineSpecializationConstant {
|
||||
PipelineSpecializationConstantType type;
|
||||
uint32_t constant_id;
|
||||
union {
|
||||
uint32_t int_value;
|
||||
float float_value;
|
||||
bool bool_value;
|
||||
};
|
||||
|
||||
PipelineSpecializationConstant() {
|
||||
type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
|
||||
constant_id = 0;
|
||||
int_value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*************************/
|
||||
/**** RENDER PIPELINE ****/
|
||||
/*************************/
|
||||
|
|
@ -978,13 +1005,13 @@ public:
|
|||
};
|
||||
|
||||
virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
|
||||
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0) = 0;
|
||||
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0;
|
||||
|
||||
/**************************/
|
||||
/**** COMPUTE PIPELINE ****/
|
||||
/**************************/
|
||||
|
||||
virtual RID compute_pipeline_create(RID p_shader) = 0;
|
||||
virtual RID compute_pipeline_create(RID p_shader, const Vector<PipelineSpecializationConstant> &p_specialization_constants = Vector<PipelineSpecializationConstant>()) = 0;
|
||||
virtual bool compute_pipeline_is_valid(RID p_pipeline) = 0;
|
||||
|
||||
/****************/
|
||||
|
|
@ -1173,7 +1200,8 @@ protected:
|
|||
|
||||
Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
|
||||
|
||||
RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0);
|
||||
RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags, uint32_t p_for_render_pass, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
|
||||
RID _compute_pipeline_create(RID p_shader, const TypedArray<RDPipelineSpecializationConstant> &p_specialization_constants);
|
||||
|
||||
Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const TypedArray<RID> &p_storage_textures = TypedArray<RID>());
|
||||
void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
|
||||
|
|
@ -1205,6 +1233,7 @@ VARIANT_ENUM_CAST(RenderingDevice::LogicOperation)
|
|||
VARIANT_ENUM_CAST(RenderingDevice::BlendFactor)
|
||||
VARIANT_ENUM_CAST(RenderingDevice::BlendOperation)
|
||||
VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags)
|
||||
VARIANT_ENUM_CAST(RenderingDevice::PipelineSpecializationConstantType)
|
||||
VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
|
||||
VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
|
||||
VARIANT_ENUM_CAST(RenderingDevice::Limit)
|
||||
|
|
|
|||
|
|
@ -452,6 +452,41 @@ protected:
|
|||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids");
|
||||
}
|
||||
};
|
||||
|
||||
class RDPipelineSpecializationConstant : public RefCounted {
|
||||
GDCLASS(RDPipelineSpecializationConstant, RefCounted)
|
||||
friend class RenderingDevice;
|
||||
|
||||
Variant value = false;
|
||||
uint32_t constant_id;
|
||||
|
||||
public:
|
||||
void set_value(const Variant &p_value) {
|
||||
ERR_FAIL_COND(p_value.get_type() != Variant::BOOL && p_value.get_type() != Variant::INT && p_value.get_type() != Variant::FLOAT);
|
||||
value = p_value;
|
||||
}
|
||||
Variant get_value() const { return value; }
|
||||
|
||||
void set_constant_id(uint32_t p_id) {
|
||||
constant_id = p_id;
|
||||
}
|
||||
uint32_t get_constant_id() const {
|
||||
return constant_id;
|
||||
}
|
||||
|
||||
protected:
|
||||
static void _bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_value", "value"), &RDPipelineSpecializationConstant::set_value);
|
||||
ClassDB::bind_method(D_METHOD("get_value"), &RDPipelineSpecializationConstant::get_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_constant_id", "constant_id"), &RDPipelineSpecializationConstant::set_constant_id);
|
||||
ClassDB::bind_method(D_METHOD("get_constant_id"), &RDPipelineSpecializationConstant::get_constant_id);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_value", "get_value");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "constant_id", PROPERTY_HINT_RANGE, "0,65535,0"), "set_constant_id", "get_constant_id");
|
||||
}
|
||||
};
|
||||
|
||||
class RDPipelineRasterizationState : public RefCounted {
|
||||
GDCLASS(RDPipelineRasterizationState, RefCounted)
|
||||
friend class RenderingDevice;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue