2019-06-22 18:34:26 +02:00
/*************************************************************************/
/* rasterizer_canvas_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
2020-02-11 14:01:43 +01:00
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
2019-06-22 18:34:26 +02:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2019-06-11 20:43:37 +02:00
# ifndef RASTERIZER_CANVAS_RD_H
# define RASTERIZER_CANVAS_RD_H
2020-03-27 19:21:27 +01:00
# include "servers/rendering/rasterizer.h"
# include "servers/rendering/rasterizer_rd/rasterizer_storage_rd.h"
# include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
# include "servers/rendering/rasterizer_rd/shader_compiler_rd.h"
# include "servers/rendering/rasterizer_rd/shaders/canvas.glsl.gen.h"
# include "servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl.gen.h"
# include "servers/rendering/rendering_device.h"
2019-06-11 20:43:37 +02:00
class RasterizerCanvasRD : public RasterizerCanvas {
2019-06-16 04:45:24 +02:00
RasterizerStorageRD * storage ;
2020-10-24 17:15:43 +02:00
enum {
BASE_UNIFORM_SET = 0 ,
MATERIAL_UNIFORM_SET = 1 ,
TRANSFORMS_UNIFORM_SET = 2 ,
CANVAS_TEXTURE_UNIFORM_SET = 3 ,
} ;
2019-06-16 04:45:24 +02:00
enum ShaderVariant {
SHADER_VARIANT_QUAD ,
SHADER_VARIANT_NINEPATCH ,
2019-06-24 21:13:06 +02:00
SHADER_VARIANT_PRIMITIVE ,
SHADER_VARIANT_PRIMITIVE_POINTS ,
SHADER_VARIANT_ATTRIBUTES ,
SHADER_VARIANT_ATTRIBUTES_POINTS ,
2019-07-10 22:44:55 +02:00
SHADER_VARIANT_QUAD_LIGHT ,
SHADER_VARIANT_NINEPATCH_LIGHT ,
SHADER_VARIANT_PRIMITIVE_LIGHT ,
SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT ,
SHADER_VARIANT_ATTRIBUTES_LIGHT ,
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT ,
2019-06-16 04:45:24 +02:00
SHADER_VARIANT_MAX
} ;
enum {
FLAGS_INSTANCING_STRIDE_MASK = 0xF ,
FLAGS_INSTANCING_ENABLED = ( 1 < < 4 ) ,
FLAGS_INSTANCING_HAS_COLORS = ( 1 < < 5 ) ,
FLAGS_INSTANCING_COLOR_8BIT = ( 1 < < 6 ) ,
FLAGS_INSTANCING_HAS_CUSTOM_DATA = ( 1 < < 7 ) ,
FLAGS_INSTANCING_CUSTOM_DATA_8_BIT = ( 1 < < 8 ) ,
FLAGS_CLIP_RECT_UV = ( 1 < < 9 ) ,
FLAGS_TRANSPOSE_RECT = ( 1 < < 10 ) ,
2019-07-05 03:54:32 +02:00
2019-06-16 04:45:24 +02:00
FLAGS_NINEPACH_DRAW_CENTER = ( 1 < < 12 ) ,
FLAGS_USING_PARTICLES = ( 1 < < 13 ) ,
2019-06-19 22:03:19 +02:00
FLAGS_USE_SKELETON = ( 1 < < 15 ) ,
FLAGS_NINEPATCH_H_MODE_SHIFT = 16 ,
2019-07-05 03:54:32 +02:00
FLAGS_NINEPATCH_V_MODE_SHIFT = 18 ,
FLAGS_LIGHT_COUNT_SHIFT = 20 ,
FLAGS_DEFAULT_NORMAL_MAP_USED = ( 1 < < 26 ) ,
FLAGS_DEFAULT_SPECULAR_MAP_USED = ( 1 < < 27 )
} ;
enum {
LIGHT_FLAGS_TEXTURE_MASK = 0xFFFF ,
LIGHT_FLAGS_BLEND_SHIFT = 16 ,
LIGHT_FLAGS_BLEND_MASK = ( 3 < < 16 ) ,
LIGHT_FLAGS_BLEND_MODE_ADD = ( 0 < < 16 ) ,
LIGHT_FLAGS_BLEND_MODE_SUB = ( 1 < < 16 ) ,
LIGHT_FLAGS_BLEND_MODE_MIX = ( 2 < < 16 ) ,
2019-07-07 06:49:40 +02:00
LIGHT_FLAGS_BLEND_MODE_MASK = ( 3 < < 16 ) ,
LIGHT_FLAGS_HAS_SHADOW = ( 1 < < 20 ) ,
LIGHT_FLAGS_FILTER_SHIFT = 22
2019-07-05 03:54:32 +02:00
} ;
enum {
MAX_RENDER_ITEMS = 256 * 1024 ,
MAX_LIGHT_TEXTURES = 1024 ,
2020-10-24 17:15:43 +02:00
MAX_LIGHTS_PER_ITEM = 16 ,
2019-07-10 22:44:55 +02:00
DEFAULT_MAX_LIGHTS_PER_RENDER = 256
2019-06-16 04:45:24 +02:00
} ;
/****************/
/**** SHADER ****/
/****************/
enum PipelineVariant {
PIPELINE_VARIANT_QUAD ,
PIPELINE_VARIANT_NINEPATCH ,
2019-06-24 21:13:06 +02:00
PIPELINE_VARIANT_PRIMITIVE_TRIANGLES ,
PIPELINE_VARIANT_PRIMITIVE_LINES ,
PIPELINE_VARIANT_PRIMITIVE_POINTS ,
PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES ,
2019-08-19 00:40:52 +02:00
PIPELINE_VARIANT_ATTRIBUTE_TRIANGLE_STRIP ,
2019-06-24 21:13:06 +02:00
PIPELINE_VARIANT_ATTRIBUTE_LINES ,
2019-08-19 00:40:52 +02:00
PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP ,
2019-06-24 21:13:06 +02:00
PIPELINE_VARIANT_ATTRIBUTE_POINTS ,
2019-06-16 04:45:24 +02:00
PIPELINE_VARIANT_MAX
} ;
2019-07-10 22:44:55 +02:00
enum PipelineLightMode {
PIPELINE_LIGHT_MODE_DISABLED ,
PIPELINE_LIGHT_MODE_ENABLED ,
PIPELINE_LIGHT_MODE_MAX
} ;
2019-06-16 04:45:24 +02:00
struct PipelineVariants {
2019-07-10 22:44:55 +02:00
RenderPipelineVertexFormatCacheRD variants [ PIPELINE_LIGHT_MODE_MAX ] [ PIPELINE_VARIANT_MAX ] ;
2019-06-16 04:45:24 +02:00
} ;
struct {
CanvasShaderRD canvas_shader ;
RID default_version ;
RID default_version_rd_shader ;
2019-06-24 21:13:06 +02:00
RID quad_index_buffer ;
2019-06-16 04:45:24 +02:00
RID quad_index_array ;
PipelineVariants pipeline_variants ;
// default_skeleton uniform set
2019-07-10 22:44:55 +02:00
RID default_skeleton_uniform_buffer ;
RID default_skeleton_texture_buffer ;
2019-06-16 04:45:24 +02:00
2019-07-21 16:31:30 +02:00
ShaderCompilerRD compiler ;
2019-06-16 04:45:24 +02:00
} shader ;
2019-07-21 16:31:30 +02:00
struct ShaderData : public RasterizerStorageRD : : ShaderData {
enum BlendMode { //used internally
BLEND_MODE_MIX ,
BLEND_MODE_ADD ,
BLEND_MODE_SUB ,
BLEND_MODE_MUL ,
BLEND_MODE_PMALPHA ,
BLEND_MODE_DISABLED ,
} ;
enum LightMode {
LIGHT_MODE_NORMAL ,
LIGHT_MODE_UNSHADED ,
LIGHT_MODE_LIGHT_ONLY
} ;
bool valid ;
RID version ;
PipelineVariants pipeline_variants ;
String path ;
Map < StringName , ShaderLanguage : : ShaderNode : : Uniform > uniforms ;
Vector < ShaderCompilerRD : : GeneratedCode : : Texture > texture_uniforms ;
Vector < uint32_t > ubo_offsets ;
uint32_t ubo_size ;
String code ;
Map < StringName , RID > default_texture_params ;
bool uses_screen_texture ;
virtual void set_code ( const String & p_Code ) ;
virtual void set_default_texture_param ( const StringName & p_name , RID p_texture ) ;
virtual void get_param_list ( List < PropertyInfo > * p_param_list ) const ;
2020-04-17 04:52:00 +02:00
virtual void get_instance_param_list ( List < RasterizerStorage : : InstanceShaderParam > * p_param_list ) const ;
2019-07-21 16:31:30 +02:00
virtual bool is_param_texture ( const StringName & p_param ) const ;
virtual bool is_animated ( ) const ;
virtual bool casts_shadows ( ) const ;
virtual Variant get_default_parameter ( const StringName & p_parameter ) const ;
ShaderData ( ) ;
virtual ~ ShaderData ( ) ;
} ;
RasterizerStorageRD : : ShaderData * _create_shader_func ( ) ;
static RasterizerStorageRD : : ShaderData * _create_shader_funcs ( ) {
return static_cast < RasterizerCanvasRD * > ( singleton ) - > _create_shader_func ( ) ;
}
struct MaterialData : public RasterizerStorageRD : : MaterialData {
2019-07-29 20:29:43 +02:00
uint64_t last_frame ;
2019-07-21 16:31:30 +02:00
ShaderData * shader_data ;
RID uniform_buffer ;
RID uniform_set ;
Vector < RID > texture_cache ;
Vector < uint8_t > ubo_data ;
virtual void set_render_priority ( int p_priority ) { }
virtual void set_next_pass ( RID p_pass ) { }
virtual void update_parameters ( const Map < StringName , Variant > & p_parameters , bool p_uniform_dirty , bool p_textures_dirty ) ;
virtual ~ MaterialData ( ) ;
} ;
RasterizerStorageRD : : MaterialData * _create_material_func ( ShaderData * p_shader ) ;
static RasterizerStorageRD : : MaterialData * _create_material_funcs ( RasterizerStorageRD : : ShaderData * p_shader ) {
return static_cast < RasterizerCanvasRD * > ( singleton ) - > _create_material_func ( static_cast < ShaderData * > ( p_shader ) ) ;
}
2019-06-16 04:45:24 +02:00
/**************************/
2020-10-24 17:15:43 +02:00
/**** CANVAS TEXTURES *****/
2019-06-16 04:45:24 +02:00
/**************************/
struct {
2020-03-27 19:21:27 +01:00
RS : : CanvasItemTextureFilter default_filter ;
RS : : CanvasItemTextureRepeat default_repeat ;
2019-06-16 04:45:24 +02:00
} default_samplers ;
2019-06-24 21:13:06 +02:00
/******************/
/**** POLYGONS ****/
/******************/
struct PolygonBuffers {
RD : : VertexFormatID vertex_format_id ;
RID vertex_buffer ;
RID vertex_array ;
RID index_buffer ;
RID indices ;
} ;
struct {
HashMap < PolygonID , PolygonBuffers > polygons ;
PolygonID last_id ;
} polygon_buffers ;
/********************/
/**** PRIMITIVES ****/
/********************/
struct {
RID index_array [ 4 ] ;
} primitive_arrays ;
2019-06-16 04:45:24 +02:00
/*******************/
/**** MATERIALS ****/
/*******************/
2019-06-26 20:11:52 +02:00
/******************/
/**** LIGHTING ****/
/******************/
2019-07-05 03:54:32 +02:00
struct CanvasLight {
RID texture ;
struct {
2020-10-24 17:15:43 +02:00
bool enabled = false ;
float z_far ;
float y_offset ;
2020-11-03 20:51:53 +01:00
Transform2D directional_xform ;
2019-07-05 03:54:32 +02:00
} shadow ;
2019-06-26 20:11:52 +02:00
} ;
2019-07-05 03:54:32 +02:00
RID_Owner < CanvasLight > canvas_light_owner ;
struct ShadowRenderPushConstant {
float projection [ 16 ] ;
2019-07-07 06:49:40 +02:00
float modelview [ 8 ] ;
float direction [ 2 ] ;
2020-10-24 17:15:43 +02:00
float z_far ;
float pad ;
2019-07-07 06:49:40 +02:00
} ;
2019-07-05 03:54:32 +02:00
struct OccluderPolygon {
2020-03-27 19:21:27 +01:00
RS : : CanvasOccluderPolygonCullMode cull_mode ;
2019-07-05 03:54:32 +02:00
int point_count ;
RID vertex_buffer ;
RID vertex_array ;
RID index_buffer ;
RID index_array ;
} ;
struct LightUniform {
float matrix [ 8 ] ; //light to texture coordinate matrix
2019-07-07 06:49:40 +02:00
float shadow_matrix [ 8 ] ; //light to shadow coordinate matrix
2019-07-05 03:54:32 +02:00
float color [ 4 ] ;
2020-10-24 17:15:43 +02:00
uint8_t shadow_color [ 4 ] ;
2019-07-05 03:54:32 +02:00
uint32_t flags ; //index to light texture
float shadow_pixel_size ;
2020-10-24 17:15:43 +02:00
float height ;
float position [ 2 ] ;
float shadow_z_far_inv ;
float shadow_y_ofs ;
float atlas_rect [ 4 ] ;
2019-07-05 03:54:32 +02:00
} ;
RID_Owner < OccluderPolygon > occluder_polygon_owner ;
2019-06-26 20:11:52 +02:00
struct {
2019-07-05 03:54:32 +02:00
CanvasOcclusionShaderRD shader ;
RID shader_version ;
RID render_pipelines [ 3 ] ;
RD : : VertexFormatID vertex_format ;
RD : : FramebufferFormatID framebuffer_format ;
} shadow_render ;
2019-06-26 20:11:52 +02:00
2019-06-16 04:45:24 +02:00
/***************/
/**** STATE ****/
/***************/
//state that does not vary across rendering all items
struct State {
//state buffer
struct Buffer {
float canvas_transform [ 16 ] ;
float screen_transform [ 16 ] ;
2019-07-05 03:54:32 +02:00
float canvas_normal_transform [ 16 ] ;
float canvas_modulate [ 4 ] ;
2020-11-03 20:51:53 +01:00
2019-07-27 15:23:24 +02:00
float screen_pixel_size [ 2 ] ;
2019-07-21 16:31:30 +02:00
float time ;
2020-10-29 22:09:16 +01:00
uint32_t use_pixel_snap ;
2019-07-27 15:23:24 +02:00
2020-11-03 20:51:53 +01:00
uint32_t directional_light_count ;
uint32_t pad [ 3 ] ;
2019-06-16 04:45:24 +02:00
} ;
2019-07-05 03:54:32 +02:00
2019-07-10 22:44:55 +02:00
LightUniform * light_uniforms ;
2019-07-05 03:54:32 +02:00
RID lights_uniform_buffer ;
2019-06-16 04:45:24 +02:00
RID canvas_state_buffer ;
2019-07-08 14:53:40 +02:00
RID shadow_sampler ;
2020-10-24 17:15:43 +02:00
RID shadow_texture ;
RID shadow_depth_texture ;
RID shadow_fb ;
int shadow_texture_size = 2048 ;
RID default_transforms_uniform_set ;
2019-06-16 04:45:24 +02:00
2019-07-10 22:44:55 +02:00
uint32_t max_lights_per_render ;
uint32_t max_lights_per_item ;
2019-07-21 16:31:30 +02:00
double time ;
2020-11-03 20:51:53 +01:00
2019-06-16 04:45:24 +02:00
} state ;
struct PushConstant {
2019-06-24 21:13:06 +02:00
float world [ 6 ] ;
2019-06-16 04:45:24 +02:00
uint32_t flags ;
uint32_t specular_shininess ;
2019-06-24 21:13:06 +02:00
union {
//rect
struct {
float modulation [ 4 ] ;
float ninepatch_margins [ 4 ] ;
float dst_rect [ 4 ] ;
float src_rect [ 4 ] ;
2019-06-26 20:11:52 +02:00
float pad [ 2 ] ;
2019-06-24 21:13:06 +02:00
} ;
//primitive
struct {
2019-07-05 03:54:32 +02:00
float points [ 6 ] ; // vec2 points[3]
float uvs [ 6 ] ; // vec2 points[3]
2019-06-26 20:11:52 +02:00
uint32_t colors [ 6 ] ; // colors encoded as half
2019-06-24 21:13:06 +02:00
} ;
} ;
2019-06-26 20:11:52 +02:00
float color_texture_pixel_size [ 2 ] ;
uint32_t lights [ 4 ] ;
2019-06-16 04:45:24 +02:00
} ;
struct SkeletonUniform {
float skeleton_transform [ 16 ] ;
float skeleton_inverse [ 16 ] ;
} ;
Item * items [ MAX_RENDER_ITEMS ] ;
2020-11-03 20:51:53 +01:00
bool using_directional_lights = false ;
2020-10-24 17:15:43 +02:00
RID default_canvas_texture ;
2020-10-28 19:34:27 +01:00
RID default_canvas_group_shader ;
RID default_canvas_group_material ;
2020-10-24 17:15:43 +02:00
RS : : CanvasItemTextureFilter default_filter = RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR ;
RS : : CanvasItemTextureRepeat default_repeat = RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ;
RID _create_base_uniform_set ( RID p_to_render_target , bool p_backbuffer ) ;
inline void _bind_canvas_texture ( RD : : DrawListID p_draw_list , RID p_texture , RS : : CanvasItemTextureFilter p_base_filter , RS : : CanvasItemTextureRepeat p_base_repeat , RID & r_last_texture , PushConstant & push_constant , Size2 & r_texpixel_size ) ; //recursive, so regular inline used instead.
2019-07-21 16:31:30 +02:00
void _render_item ( RenderingDevice : : DrawListID p_draw_list , const Item * p_item , RenderingDevice : : FramebufferFormatID p_framebuffer_format , const Transform2D & p_canvas_transform_inverse , Item * & current_clip , Light * p_lights , PipelineVariants * p_pipeline_variants ) ;
2020-10-28 19:34:27 +01:00
void _render_items ( RID p_to_render_target , int p_item_count , const Transform2D & p_canvas_transform_inverse , Light * p_lights , bool p_to_backbuffer = false ) ;
2019-06-16 04:45:24 +02:00
2019-07-05 03:54:32 +02:00
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4 ( const Transform2D & p_transform , float * p_mat2x4 ) ;
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3 ( const Transform2D & p_transform , float * p_mat2x3 ) ;
2019-06-16 04:45:24 +02:00
2019-07-05 03:54:32 +02:00
_FORCE_INLINE_ void _update_transform_2d_to_mat4 ( const Transform2D & p_transform , float * p_mat4 ) ;
_FORCE_INLINE_ void _update_transform_to_mat4 ( const Transform & p_transform , float * p_mat4 ) ;
2020-11-03 20:51:53 +01:00
void _update_shadow_atlas ( ) ;
2019-06-11 20:43:37 +02:00
public :
2019-06-24 21:13:06 +02:00
PolygonID request_polygon ( const Vector < int > & p_indices , const Vector < Point2 > & p_points , const Vector < Color > & p_colors , const Vector < Point2 > & p_uvs = Vector < Point2 > ( ) , const Vector < int > & p_bones = Vector < int > ( ) , const Vector < float > & p_weights = Vector < float > ( ) ) ;
void free_polygon ( PolygonID p_polygon ) ;
2019-07-05 03:54:32 +02:00
RID light_create ( ) ;
void light_set_texture ( RID p_rid , RID p_texture ) ;
2020-10-24 17:15:43 +02:00
void light_set_use_shadow ( RID p_rid , bool p_enable ) ;
void light_update_shadow ( RID p_rid , int p_shadow_index , const Transform2D & p_light_xform , int p_light_mask , float p_near , float p_far , LightOccluderInstance * p_occluders ) ;
2020-11-03 20:51:53 +01:00
void light_update_directional_shadow ( RID p_rid , int p_shadow_index , const Transform2D & p_light_xform , int p_light_mask , float p_cull_distance , const Rect2 & p_clip_rect , LightOccluderInstance * p_occluders ) ;
2019-07-05 03:54:32 +02:00
RID occluder_polygon_create ( ) ;
2020-02-17 22:06:54 +01:00
void occluder_polygon_set_shape_as_lines ( RID p_occluder , const Vector < Vector2 > & p_lines ) ;
2020-03-27 19:21:27 +01:00
void occluder_polygon_set_cull_mode ( RID p_occluder , RS : : CanvasOccluderPolygonCullMode p_mode ) ;
2019-06-11 20:43:37 +02:00
2020-11-03 20:51:53 +01:00
void canvas_render_items ( RID p_to_render_target , Item * p_item_list , const Color & p_modulate , Light * p_light_list , Light * p_directional_light_list , const Transform2D & p_canvas_transform , RS : : CanvasItemTextureFilter p_default_filter , RS : : CanvasItemTextureRepeat p_default_repeat , bool p_snap_2d_vertices_to_pixel ) ;
2019-06-11 20:43:37 +02:00
2020-05-12 17:01:17 +02:00
void canvas_debug_viewport_shadows ( Light * p_lights_with_shadow ) { }
2019-06-11 20:43:37 +02:00
void draw_window_margins ( int * p_margins , RID * p_margin_textures ) { }
2020-10-24 17:15:43 +02:00
virtual void set_shadow_texture_size ( int p_size ) ;
2019-07-21 16:31:30 +02:00
void set_time ( double p_time ) ;
2019-06-16 04:45:24 +02:00
void update ( ) ;
2019-07-05 03:54:32 +02:00
bool free ( RID p_rid ) ;
2019-06-16 04:45:24 +02:00
RasterizerCanvasRD ( RasterizerStorageRD * p_storage ) ;
2019-06-24 21:13:06 +02:00
~ RasterizerCanvasRD ( ) ;
2019-06-11 20:43:37 +02:00
} ;
# endif // RASTERIZER_CANVAS_RD_H