Batch GLES2 draw calls
Adds GLES2 draw calls batching for the same render list item that uses multiple rasterizer commands (e.g. Label node; a node with multiple GDScript draw_* calls).
This commit is contained in:
parent
eef9c1f5b5
commit
f55039b194
7 changed files with 617 additions and 475 deletions
File diff suppressed because it is too large
Load diff
|
@ -50,23 +50,44 @@ public:
|
|||
Color final_modulate;
|
||||
|
||||
float time;
|
||||
|
||||
Size2 texpixel_size;
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
Vector2 v;
|
||||
Color c;
|
||||
Vector2 uv;
|
||||
};
|
||||
|
||||
struct Data {
|
||||
|
||||
GLuint canvas_quad_vertices;
|
||||
GLuint polygon_buffer;
|
||||
GLuint polygon_index_buffer;
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
|
||||
uint32_t polygon_buffer_size;
|
||||
uint32_t vertex_buffer_size;
|
||||
uint32_t index_buffer_size;
|
||||
|
||||
GLuint ninepatch_vertices;
|
||||
GLuint ninepatch_elements;
|
||||
int ninepatch_elements[3 * 2 * 9];
|
||||
|
||||
int *mem_index_buffer;
|
||||
uint32_t mem_index_buffer_offset;
|
||||
uint32_t mem_index_buffer_size;
|
||||
|
||||
Vertex *mem_vertex_buffer;
|
||||
uint32_t mem_vertex_buffer_offset;
|
||||
uint32_t mem_vertex_buffer_size;
|
||||
|
||||
GLuint primitive;
|
||||
GLuint texture;
|
||||
} data;
|
||||
|
||||
struct State {
|
||||
Uniforms uniforms;
|
||||
Uniforms prev_uniforms;
|
||||
|
||||
bool tiled;
|
||||
|
||||
bool canvas_texscreen_used;
|
||||
CanvasShaderGLES2 canvas_shader;
|
||||
// CanvasShadowShaderGLES3 canvas_shadow_shader;
|
||||
|
@ -99,9 +120,16 @@ public:
|
|||
|
||||
_FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable, bool p_ninepatch = false);
|
||||
|
||||
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs);
|
||||
_FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
|
||||
_FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
|
||||
|
||||
_FORCE_INLINE_ void _begin(const GLuint p_primitive);
|
||||
_FORCE_INLINE_ void _prepare(const int p_vertex_count, const int p_index_count);
|
||||
_FORCE_INLINE_ void _commit(const int p_vertex_count, const int p_index_count);
|
||||
|
||||
_FORCE_INLINE_ void _flush();
|
||||
_FORCE_INLINE_ void _draw(const GLuint p_primitive, const int p_vertex_count, const Vertex *p_vertices, const int p_index_count, const int *p_indices);
|
||||
|
||||
_FORCE_INLINE_ void _untile();
|
||||
|
||||
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material);
|
||||
_FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect);
|
||||
|
@ -114,8 +142,8 @@ public:
|
|||
virtual void reset_canvas();
|
||||
|
||||
RasterizerStorageGLES2::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map);
|
||||
_FORCE_INLINE_ void _bind_shader(RasterizerStorageGLES2::Material *p_material);
|
||||
|
||||
void _bind_quad_buffer();
|
||||
void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src);
|
||||
|
||||
void initialize();
|
||||
|
|
|
@ -345,9 +345,6 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re
|
|||
RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
|
||||
canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
|
||||
canvas->state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||
|
||||
canvas->state.canvas_shader.set_custom_shader(0);
|
||||
canvas->state.canvas_shader.bind();
|
||||
|
||||
|
@ -359,7 +356,7 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re
|
|||
|
||||
// TODO normals
|
||||
|
||||
canvas->draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1));
|
||||
canvas->draw_generic_textured_rect(p_screen_rect, Rect2(0, 1, 1, -1));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
canvas->canvas_end();
|
||||
|
|
|
@ -252,7 +252,7 @@ public:
|
|||
int mipmaps;
|
||||
|
||||
bool active;
|
||||
GLenum tex_id;
|
||||
GLuint tex_id;
|
||||
|
||||
uint16_t stored_cube_sides;
|
||||
|
||||
|
@ -429,6 +429,8 @@ public:
|
|||
bool uses_screen_texture;
|
||||
bool uses_screen_uv;
|
||||
bool uses_time;
|
||||
bool uses_modelview_matrix;
|
||||
bool uses_vertex;
|
||||
|
||||
} canvas_item;
|
||||
|
||||
|
|
|
@ -122,13 +122,11 @@ GLint ShaderGLES2::get_uniform_location(int p_index) const {
|
|||
}
|
||||
|
||||
bool ShaderGLES2::bind() {
|
||||
|
||||
if (active != this || !version || new_conditional_version.key != conditional_version.key) {
|
||||
conditional_version = new_conditional_version;
|
||||
version = get_current_version();
|
||||
} else {
|
||||
if (!is_dirty())
|
||||
return false;
|
||||
}
|
||||
|
||||
conditional_version = new_conditional_version;
|
||||
version = get_current_version();
|
||||
|
||||
ERR_FAIL_COND_V(!version, false);
|
||||
|
||||
|
@ -1109,3 +1107,7 @@ ShaderGLES2::ShaderGLES2() {
|
|||
ShaderGLES2::~ShaderGLES2() {
|
||||
finish();
|
||||
}
|
||||
|
||||
bool ShaderGLES2::is_dirty() const {
|
||||
return active != this || !version || new_conditional_version.key != conditional_version.key;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ public:
|
|||
GLint get_uniform_location(int p_index) const;
|
||||
|
||||
static _FORCE_INLINE_ ShaderGLES2 *get_active() { return active; }
|
||||
bool is_dirty() const;
|
||||
bool bind();
|
||||
void unbind();
|
||||
void bind_uniforms();
|
||||
|
|
|
@ -20,13 +20,6 @@ varying vec4 color_interp;
|
|||
|
||||
uniform highp vec2 color_texpixel_size;
|
||||
|
||||
#ifdef USE_TEXTURE_RECT
|
||||
|
||||
uniform vec4 dst_rect;
|
||||
uniform vec4 src_rect;
|
||||
|
||||
#endif
|
||||
|
||||
uniform highp float time;
|
||||
|
||||
VERTEX_SHADER_GLOBALS
|
||||
|
@ -44,35 +37,9 @@ void main() {
|
|||
|
||||
vec4 color = color_attrib;
|
||||
|
||||
#ifdef USE_TEXTURE_RECT
|
||||
|
||||
if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
|
||||
uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.yx;
|
||||
} else {
|
||||
uv_interp = src_rect.xy + abs(src_rect.zw) * vertex;
|
||||
}
|
||||
|
||||
vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// This is what is done in the GLES 3 bindings and should
|
||||
// take care of flipped rects.
|
||||
//
|
||||
// But it doesn't.
|
||||
// I don't know why, will need to investigate further.
|
||||
|
||||
outvec.xy = dst_rect.xy + abs(dst_rect.zw) * select(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0)));
|
||||
|
||||
// outvec.xy = dst_rect.xy + abs(dst_rect.zw) * vertex;
|
||||
#else
|
||||
vec4 outvec = vec4(vertex.xy, 0.0, 1.0);
|
||||
|
||||
#ifdef USE_UV_ATTRIBUTE
|
||||
uv_interp = uv_attrib;
|
||||
#else
|
||||
uv_interp = vertex.xy;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
{
|
||||
vec2 src_vtx=outvec.xy;
|
||||
|
|
Loading…
Reference in a new issue