Basic 2D engine is more or less working, needs more work for editor to be usable.

This commit is contained in:
Juan Linietsky 2019-06-19 17:03:19 -03:00 committed by Juan Linietsky
parent 9b0dd4f571
commit 42b44f43ee
17 changed files with 264 additions and 191 deletions

View File

@ -45,7 +45,7 @@ public:
if (alloc_count == max_alloc) { if (alloc_count == max_alloc) {
//allocate a new chunk //allocate a new chunk
uint32_t chunk_count = alloc_count == 0 ? 0 : (max_alloc / elements_in_chunk + 1); uint32_t chunk_count = alloc_count == 0 ? 0 : (max_alloc / elements_in_chunk);
//grow chunks //grow chunks
chunks = (T **)memrealloc(chunks, sizeof(T *) * (chunk_count + 1)); chunks = (T **)memrealloc(chunks, sizeof(T *) * (chunk_count + 1));
@ -140,8 +140,8 @@ public:
chunks[idx_chunk][idx_element].~T(); chunks[idx_chunk][idx_element].~T();
validator_chunks[idx_chunk][idx_element] = 0xFFFFFFFF; // go invalid validator_chunks[idx_chunk][idx_element] = 0xFFFFFFFF; // go invalid
free_list_chunks[alloc_count / elements_in_chunk][alloc_count % elements_in_chunk] = idx;
alloc_count--; alloc_count--;
free_list_chunks[alloc_count / elements_in_chunk][alloc_count % elements_in_chunk] = idx;
} }
void get_owned_list(List<RID> *p_owned) { void get_owned_list(List<RID> *p_owned) {

View File

@ -721,7 +721,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_S8_UINT: return 1; case DATA_FORMAT_S8_UINT: return 1;
case DATA_FORMAT_D16_UNORM_S8_UINT: return 4; case DATA_FORMAT_D16_UNORM_S8_UINT: return 4;
case DATA_FORMAT_D24_UNORM_S8_UINT: return 4; case DATA_FORMAT_D24_UNORM_S8_UINT: return 4;
case DATA_FORMAT_D32_SFLOAT_S8_UINT: return 5; //? case DATA_FORMAT_D32_SFLOAT_S8_UINT:
return 5; //?
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK: case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK: case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
@ -965,7 +966,8 @@ uint32_t RenderingDeviceVulkan::get_compressed_image_format_block_byte_size(Data
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK: case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK: case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK: case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK: return 8; //wrong case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
return 8; //wrong
case DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: case DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
@ -973,7 +975,8 @@ uint32_t RenderingDeviceVulkan::get_compressed_image_format_block_byte_size(Data
case DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: case DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return 8; //what varies is resolution case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
return 8; //what varies is resolution
default: { default: {
} }
} }
@ -1027,7 +1030,6 @@ uint32_t RenderingDeviceVulkan::get_image_format_required_size(DataFormat p_form
uint32_t bw = w % blockw != 0 ? w + (blockw - w % blockw) : w; uint32_t bw = w % blockw != 0 ? w + (blockw - w % blockw) : w;
uint32_t bh = h % blockh != 0 ? h + (blockh - h % blockh) : h; uint32_t bh = h % blockh != 0 ? h + (blockh - h % blockh) : h;
print_line("bw " + itos(bw) + " bh " + itos(bh) + " pixsize " + itos(pixel_size) + " shift " + itos(pixel_rshift));
uint32_t s = bw * bh; uint32_t s = bw * bh;
s *= pixel_size; s *= pixel_size;
@ -1466,6 +1468,26 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.pNext = NULL; image_create_info.pNext = NULL;
image_create_info.flags = 0; image_create_info.flags = 0;
VkImageFormatListCreateInfoKHR format_list_create_info;
Vector<VkFormat> allowed_formats;
if (p_format.shareable_formats.size()) {
image_create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
for (int i = 0; i < p_format.shareable_formats.size(); i++) {
allowed_formats.push_back(vulkan_formats[p_format.shareable_formats[i]]);
}
format_list_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
format_list_create_info.pNext = NULL;
format_list_create_info.viewFormatCount = allowed_formats.size();
format_list_create_info.pViewFormats = allowed_formats.ptr();
image_create_info.pNext = &format_list_create_info;
ERR_FAIL_COND_V_MSG(p_format.shareable_formats.find(p_format.format) == -1, RID(),
"If supplied a list of shareable formats, the current format must be present in the list");
ERR_FAIL_COND_V_MSG(p_view.format_override != DATA_FORMAT_MAX && p_format.shareable_formats.find(p_view.format_override) == -1, RID(),
"If supplied a list of shareable formats, the current view format override must be present in the list");
}
if (p_format.type == TEXTURE_TYPE_CUBE || p_format.type == TEXTURE_TYPE_CUBE_ARRAY) { if (p_format.type == TEXTURE_TYPE_CUBE || p_format.type == TEXTURE_TYPE_CUBE_ARRAY) {
image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
} }
@ -1647,6 +1669,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
texture.mipmaps = image_create_info.mipLevels; texture.mipmaps = image_create_info.mipLevels;
texture.usage_flags = p_format.usage_bits; texture.usage_flags = p_format.usage_bits;
texture.samples = p_format.samples; texture.samples = p_format.samples;
texture.allowed_shared_formats = p_format.shareable_formats;
//set bound and unbound layouts //set bound and unbound layouts
if (p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { if (p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
@ -1803,10 +1826,13 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
}; };
image_view_create_info.viewType = view_types[texture.type]; image_view_create_info.viewType = view_types[texture.type];
if (p_view.format_override == DATA_FORMAT_MAX) { if (p_view.format_override == DATA_FORMAT_MAX || p_view.format_override == texture.format) {
image_view_create_info.format = vulkan_formats[texture.format]; image_view_create_info.format = vulkan_formats[texture.format];
} else { } else {
ERR_FAIL_INDEX_V(p_view.format_override, DATA_FORMAT_MAX, RID()); ERR_FAIL_INDEX_V(p_view.format_override, DATA_FORMAT_MAX, RID());
ERR_FAIL_COND_V_MSG(texture.allowed_shared_formats.find(p_view.format_override) == -1, RID(),
"Format override is not in the list of allowed shareable formats for original texture.");
image_view_create_info.format = vulkan_formats[p_view.format_override]; image_view_create_info.format = vulkan_formats[p_view.format_override];
} }
@ -1877,6 +1903,13 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
uint32_t width, height; uint32_t width, height;
uint32_t image_size = get_image_format_required_size(texture->format, texture->width, texture->height, 1, texture->mipmaps, &width, &height); uint32_t image_size = get_image_format_required_size(texture->format, texture->width, texture->height, 1, texture->mipmaps, &width, &height);
uint32_t required_size = image_size * texture->depth; uint32_t required_size = image_size * texture->depth;
uint32_t required_align = get_compressed_image_format_block_byte_size(texture->format);
if (required_align == 1) {
required_align = get_image_format_pixel_size(texture->format);
}
if ((required_align % 4) != 0) { //alignment rules are really strange
required_align *= 4;
}
ERR_FAIL_COND_V_MSG(required_size != (uint32_t)p_data.size(), ERR_INVALID_PARAMETER, ERR_FAIL_COND_V_MSG(required_size != (uint32_t)p_data.size(), ERR_INVALID_PARAMETER,
"Required size for texture update (" + itos(required_size) + ") does not match data supplied size (" + itos(p_data.size()) + ")."); "Required size for texture update (" + itos(required_size) + ") does not match data supplied size (" + itos(p_data.size()) + ").");
@ -1914,12 +1947,12 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
uint32_t image_total = get_image_format_required_size(texture->format, texture->width, texture->height, 1, mm_i + 1, &width, &height); uint32_t image_total = get_image_format_required_size(texture->format, texture->width, texture->height, 1, mm_i + 1, &width, &height);
const uint8_t *read_ptr = r.ptr() + mipmap_offset; const uint8_t *read_ptr_mipmap = r.ptr() + mipmap_offset;
image_size = image_total - mipmap_offset; image_size = image_total - mipmap_offset;
for (uint32_t z = 0; z < texture->depth; z++) { //for 3D textures, depth may be > 0 for (uint32_t z = 0; z < texture->depth; z++) { //for 3D textures, depth may be > 0
read_ptr += image_size; const uint8_t *read_ptr = read_ptr_mipmap + image_size * z;
for (uint32_t x = 0; x < width; x += region_size) { for (uint32_t x = 0; x < width; x += region_size) {
for (uint32_t y = 0; y < height; y += region_size) { for (uint32_t y = 0; y < height; y += region_size) {
@ -1932,7 +1965,7 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
to_allocate >>= get_compressed_image_format_pixel_rshift(texture->format); to_allocate >>= get_compressed_image_format_pixel_rshift(texture->format);
uint32_t alloc_offset, alloc_size; uint32_t alloc_offset, alloc_size;
Error err = _staging_buffer_allocate(to_allocate, 32, alloc_offset, alloc_size, false, p_sync_with_draw); Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false, p_sync_with_draw);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE); ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
uint8_t *write_ptr; uint8_t *write_ptr;
@ -2937,7 +2970,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
bindings.resize(set + 1); bindings.resize(set + 1);
uniform_infos.resize(set + 1); uniform_infos.resize(set + 1);
} }
#if 1 #if 0
print_line("stage: " + String(shader_stage_names[p_stage]) + " set: " + itos(set) + " binding: " + itos(info.binding) + " type:" + shader_uniform_names[info.type] + " length: " + itos(info.length)); print_line("stage: " + String(shader_stage_names[p_stage]) + " set: " + itos(set) + " binding: " + itos(info.binding) + " type:" + shader_uniform_names[info.type] + " length: " + itos(info.length));
#endif #endif
bindings.write[set].push_back(layout_binding); bindings.write[set].push_back(layout_binding);
@ -3087,7 +3120,7 @@ RID RenderingDeviceVulkan::shader_create_from_source(const Vector<ShaderStageSou
for (int j = 0; j < program.getNumPipeInputs(); j++) { for (int j = 0; j < program.getNumPipeInputs(); j++) {
if (program.getPipeInput(i).getType()->getQualifier().hasLocation()) { if (program.getPipeInput(i).getType()->getQualifier().hasLocation()) {
int location = program.getPipeInput(i).getType()->getQualifier().layoutLocation; int location = program.getPipeInput(i).getType()->getQualifier().layoutLocation;
print_line("found vertex location: " + itos(location));
if (vertex_input_locations.find(location) == -1) { if (vertex_input_locations.find(location) == -1) {
vertex_input_locations.push_back(location); vertex_input_locations.push_back(location);
} }
@ -3470,13 +3503,10 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
uint32_t uniform_count = p_uniforms.size(); uint32_t uniform_count = p_uniforms.size();
const Uniform *uniforms = p_uniforms.ptr(); const Uniform *uniforms = p_uniforms.ptr();
print_line("uniform count: " + itos(uniform_count));
uint32_t set_uniform_count = set.uniform_info.size(); uint32_t set_uniform_count = set.uniform_info.size();
const Shader::UniformInfo *set_uniforms = set.uniform_info.ptr(); const Shader::UniformInfo *set_uniforms = set.uniform_info.ptr();
print_line("set_uniform count: " + itos(set_uniform_count));
Vector<VkWriteDescriptorSet> writes; Vector<VkWriteDescriptorSet> writes;
DescriptorPoolKey pool_key; DescriptorPoolKey pool_key;

View File

@ -101,6 +101,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t mipmaps; uint32_t mipmaps;
uint32_t usage_flags; uint32_t usage_flags;
Vector<DataFormat> allowed_shared_formats;
VkImageLayout bound_layout; //layout used when bound to framebuffer being drawn VkImageLayout bound_layout; //layout used when bound to framebuffer being drawn
VkImageLayout unbound_layout; //layout used otherwise VkImageLayout unbound_layout; //layout used otherwise
uint32_t aspect_mask; uint32_t aspect_mask;

View File

@ -18,6 +18,12 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(VkDebugU
char *message = (char *)malloc(strlen(pCallbackData->pMessage) + 5000); char *message = (char *)malloc(strlen(pCallbackData->pMessage) + 5000);
ERR_FAIL_COND_V(!message, false); ERR_FAIL_COND_V(!message, false);
//This error needs to be ignored because the AMD allocator will mix up memory types on IGP processors
if (strstr(pCallbackData->pMessage, "Mapping an image with layout") != NULL &&
strstr(pCallbackData->pMessage, "can result in undefined behavior if this memory is used by the device") != NULL) {
return VK_FALSE;
}
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
strcat(prefix, "VERBOSE : "); strcat(prefix, "VERBOSE : ");
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { } else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {

View File

@ -649,6 +649,7 @@ void register_scene_types() {
ClassDB::register_class<World>(); ClassDB::register_class<World>();
ClassDB::register_class<Environment>(); ClassDB::register_class<Environment>();
ClassDB::register_class<World2D>(); ClassDB::register_class<World2D>();
ClassDB::register_virtual_class<Texture>();
ClassDB::register_virtual_class<Texture2D>(); ClassDB::register_virtual_class<Texture2D>();
ClassDB::register_virtual_class<Sky>(); ClassDB::register_virtual_class<Sky>();
ClassDB::register_class<PanoramaSky>(); ClassDB::register_class<PanoramaSky>();

View File

@ -42,7 +42,15 @@
#include "servers/camera_server.h" #include "servers/camera_server.h"
#include "servers/visual_server.h" #include "servers/visual_server.h"
class Texture2D : public Resource { class Texture : public Resource {
GDCLASS(Texture, Resource);
public:
Texture() {}
};
class Texture2D : public Texture {
GDCLASS(Texture2D, Resource); GDCLASS(Texture2D, Resource);
OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged. OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged.
@ -332,7 +340,7 @@ public:
LargeTexture(); LargeTexture();
}; };
class TextureLayered : public Resource { class TextureLayered : public Texture {
GDCLASS(TextureLayered, Resource); GDCLASS(TextureLayered, Resource);

View File

@ -131,7 +131,7 @@ RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(R
u.binding = 2; u.binding = 2;
RID texture = storage->texture_get_rd_texture(p_normalmap); RID texture = storage->texture_get_rd_texture(p_normalmap);
if (!texture.is_valid()) { if (!texture.is_valid()) {
//use default white texture //use default normal texture
texture = default_textures.normal_texture; texture = default_textures.normal_texture;
} }
u.ids.push_back(texture); u.ids.push_back(texture);
@ -202,7 +202,7 @@ void RasterizerCanvasRD::_dispose_bindings() {
} }
} }
void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, const Color &p_modulate, const Transform2D &p_canvas_transform_inverse) { void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RD::TextureSamples p_samples, const Color &p_modulate, const Transform2D &p_canvas_transform_inverse) {
int cc = p_item->commands.size(); int cc = p_item->commands.size();
const Item::Command *const *commands = p_item->commands.ptr(); const Item::Command *const *commands = p_item->commands.ptr();
@ -217,10 +217,9 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
push_constant.dst_rect[i] = 0; push_constant.dst_rect[i] = 0;
} }
push_constant.flags = 0; push_constant.flags = 0;
push_constant.ninepatch_repeat = 0; push_constant.specular_shininess = 0xFFFFFFFF;
push_constant.color_texture_pixel_size[0] = 0; push_constant.color_texture_pixel_size[0] = 0;
push_constant.color_texture_pixel_size[1] = 0; push_constant.color_texture_pixel_size[1] = 0;
push_constant.specular_shininess = 0xFFFFFFFF;
push_constant.pad[0] = 0; push_constant.pad[0] = 0;
push_constant.pad[1] = 0; push_constant.pad[1] = 0;
push_constant.pad[2] = 0; push_constant.pad[2] = 0;
@ -347,7 +346,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind pipeline //bind pipeline
{ {
RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_QUAD]; RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_samples);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
} }
@ -358,6 +357,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(rect->texture_binding.binding_id); TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(rect->texture_binding.binding_id);
ERR_CONTINUE(!texture_binding_ptr); ERR_CONTINUE(!texture_binding_ptr);
TextureBinding *texture_binding = *texture_binding_ptr; TextureBinding *texture_binding = *texture_binding_ptr;
RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, texture_binding->uniform_set, 0); RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, texture_binding->uniform_set, 0);
if (texture_binding->key.texture.is_valid()) { if (texture_binding->key.texture.is_valid()) {
Size2i tex_size = storage->texture_2d_get_size(texture_binding->key.texture); Size2i tex_size = storage->texture_2d_get_size(texture_binding->key.texture);
@ -449,7 +449,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind pipeline //bind pipeline
{ {
RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_NINEPATCH]; RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_samples);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline); RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
} }
@ -506,8 +506,8 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
push_constant.color_texture_pixel_size[0] = texpixel_size.x; push_constant.color_texture_pixel_size[0] = texpixel_size.x;
push_constant.color_texture_pixel_size[1] = texpixel_size.y; push_constant.color_texture_pixel_size[1] = texpixel_size.y;
push_constant.ninepatch_repeat = int(np->axis_x) << 16; push_constant.flags |= int(np->axis_x) << FLAGS_NINEPATCH_H_MODE_SHIFT;
push_constant.ninepatch_repeat |= int(np->axis_y); push_constant.flags |= int(np->axis_y) << FLAGS_NINEPATCH_V_MODE_SHIFT;
if (np->draw_center) { if (np->draw_center) {
push_constant.flags |= FLAGS_NINEPACH_DRAW_CENTER; push_constant.flags |= FLAGS_NINEPACH_DRAW_CENTER;
@ -926,7 +926,8 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, bool p_clear, con
if (p_clear) { if (p_clear) {
clear_colors.push_back(p_clear_color); clear_colors.push_back(p_clear_color);
} }
#warning TODO obtain from framebuffer format eventually when this is implemented
RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1;
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, p_clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, p_clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.canvas_state_uniform_set, 3); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.canvas_state_uniform_set, 3);
@ -950,12 +951,12 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, bool p_clear, con
} }
} }
if (true) { //not skeleton if (false) { //not skeleton
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, shader.default_material_uniform_set, 1); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, shader.default_material_uniform_set, 1);
} }
_render_item(draw_list, ci, render_target_format, p_modulate, canvas_transform_inverse); _render_item(draw_list, ci, render_target_format, texture_samples, p_modulate, canvas_transform_inverse);
} }
RD::get_singleton()->draw_list_end(); RD::get_singleton()->draw_list_end();
@ -1180,7 +1181,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
RD::AttachmentFormat af; RD::AttachmentFormat af;
af.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; af.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
af.samples = RD::TEXTURE_SAMPLES_1; af.samples = RD::TEXTURE_SAMPLES_1;
af.usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; af.usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
Vector<RD::AttachmentFormat> formats; Vector<RD::AttachmentFormat> formats;
formats.push_back(af); formats.push_back(af);
shader.framebuffer_formats[RENDER_TARGET_FORMAT_8_BIT_INT] = RD::get_singleton()->framebuffer_format_create(formats); shader.framebuffer_formats[RENDER_TARGET_FORMAT_8_BIT_INT] = RD::get_singleton()->framebuffer_format_create(formats);
@ -1198,8 +1199,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
ShaderVariant shader_variants[PIPELINE_VARIANT_MAX] = { SHADER_VARIANT_QUAD, SHADER_VARIANT_NINEPATCH, SHADER_VARIANT_VERTICES, SHADER_VARIANT_VERTICES, SHADER_VARIANT_POINTS }; ShaderVariant shader_variants[PIPELINE_VARIANT_MAX] = { SHADER_VARIANT_QUAD, SHADER_VARIANT_NINEPATCH, SHADER_VARIANT_VERTICES, SHADER_VARIANT_VERTICES, SHADER_VARIANT_POINTS };
RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[j]); RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[j]);
RID pipeline = RD::get_singleton()->render_pipeline_create(shader_variant, fb_format, RD::INVALID_ID, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), j == PIPELINE_VARIANT_LINES ? RD::DYNAMIC_STATE_LINE_WIDTH : 0); shader.pipeline_variants.variants[i][j].setup(shader_variant, fb_format, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), j == PIPELINE_VARIANT_LINES ? RD::DYNAMIC_STATE_LINE_WIDTH : 0);
shader.pipeline_variants.variants[i][j] = pipeline;
} }
} }

View File

@ -3,6 +3,7 @@
#include "servers/visual/rasterizer/rasterizer.h" #include "servers/visual/rasterizer/rasterizer.h"
#include "servers/visual/rasterizer/rasterizer_storage_rd.h" #include "servers/visual/rasterizer/rasterizer_storage_rd.h"
#include "servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h"
#include "servers/visual/rasterizer/shaders/canvas.glsl.gen.h" #include "servers/visual/rasterizer/shaders/canvas.glsl.gen.h"
#include "servers/visual/rendering_device.h" #include "servers/visual/rendering_device.h"
@ -38,7 +39,9 @@ class RasterizerCanvasRD : public RasterizerCanvas {
FLAGS_USING_PARTICLES = (1 << 13), FLAGS_USING_PARTICLES = (1 << 13),
FLAGS_USE_PIXEL_SNAP = (1 << 14), FLAGS_USE_PIXEL_SNAP = (1 << 14),
FLAGS_USE_SKELETON = (1 << 16) FLAGS_USE_SKELETON = (1 << 15),
FLAGS_NINEPATCH_H_MODE_SHIFT = 16,
FLAGS_NINEPATCH_V_MODE_SHIFT = 18
}; };
/****************/ /****************/
@ -51,13 +54,10 @@ class RasterizerCanvasRD : public RasterizerCanvas {
PIPELINE_VARIANT_TRIANGLES, PIPELINE_VARIANT_TRIANGLES,
PIPELINE_VARIANT_LINES, PIPELINE_VARIANT_LINES,
PIPELINE_VARIANT_POINTS, PIPELINE_VARIANT_POINTS,
PIPELINE_VARIANT_TRIANGLES_COMPRESSED,
PIPELINE_VARIANT_LINES_COMPRESSED,
PIPELINE_VARIANT_POINTS_COMPRESSED,
PIPELINE_VARIANT_MAX PIPELINE_VARIANT_MAX
}; };
struct PipelineVariants { struct PipelineVariants {
RID variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX]; RenderPipelineVertexFormatCacheRD variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX];
}; };
struct { struct {
@ -177,10 +177,9 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float dst_rect[4]; float dst_rect[4];
float src_rect[4]; float src_rect[4];
uint32_t flags; uint32_t flags;
uint32_t ninepatch_repeat;
float color_texture_pixel_size[2];
uint32_t specular_shininess; uint32_t specular_shininess;
uint32_t pad[3]; float color_texture_pixel_size[2];
uint32_t pad[4];
}; };
struct SkeletonUniform { struct SkeletonUniform {
@ -194,7 +193,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
Item *items[MAX_RENDER_ITEMS]; Item *items[MAX_RENDER_ITEMS];
void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, const Color &p_modulate, const Transform2D &p_canvas_transform_inverse); void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RenderingDevice::TextureSamples p_samples, const Color &p_modulate, const Transform2D &p_canvas_transform_inverse);
void _render_items(RID p_to_render_target, bool p_clear, const Color &p_clear_color, int p_item_count, const Color &p_modulate, const Transform2D &p_transform); void _render_items(RID p_to_render_target, bool p_clear, const Color &p_clear_color, int p_item_count, const Color &p_modulate, const Transform2D &p_transform);
void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4); void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);

View File

@ -3,6 +3,7 @@
void RasterizerRD::blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) { void RasterizerRD::blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) {
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen);
for (int i = 0; i < p_amount; i++) { for (int i = 0; i < p_amount; i++) {
RID texture = storage->render_target_get_texture(p_render_targets[i].render_target); RID texture = storage->render_target_get_texture(p_render_targets[i].render_target);
ERR_CONTINUE(texture.is_null()); ERR_CONTINUE(texture.is_null());
@ -15,6 +16,7 @@ void RasterizerRD::blit_render_targets_to_screen(int p_screen, const BlitToScree
u.binding = 0; u.binding = 0;
u.ids.push_back(copy_viewports_sampler); u.ids.push_back(copy_viewports_sampler);
u.ids.push_back(rd_texture); u.ids.push_back(rd_texture);
uniforms.push_back(u);
RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, copy_viewports_rd_shader, 0); RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, copy_viewports_rd_shader, 0);
render_target_descriptors[rd_texture] = uniform_set; render_target_descriptors[rd_texture] = uniform_set;
@ -35,6 +37,8 @@ void RasterizerRD::blit_render_targets_to_screen(int p_screen, const BlitToScree
RD::get_singleton()->draw_list_set_push_constant(draw_list, push_constant, 4 * sizeof(float)); RD::get_singleton()->draw_list_set_push_constant(draw_list, push_constant, 4 * sizeof(float));
RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_draw(draw_list, true);
} }
RD::get_singleton()->draw_list_end();
} }
void RasterizerRD::begin_frame(double frame_step) { void RasterizerRD::begin_frame(double frame_step) {
@ -48,9 +52,6 @@ void RasterizerRD::end_frame(bool p_swap_buffers) {
} }
void RasterizerRD::initialize() { void RasterizerRD::initialize() {
storage = memnew(RasterizerStorageRD);
canvas = memnew(RasterizerCanvasRD(storage));
scene = memnew(RasterizerSceneForwardRD);
{ //create framebuffer copy shader { //create framebuffer copy shader
RenderingDevice::ShaderStageSource vert; RenderingDevice::ShaderStageSource vert;
@ -60,9 +61,10 @@ void RasterizerRD::initialize() {
"layout(push_constant, binding = 0, std140) uniform Pos { vec4 dst_rect; } pos;\n" "layout(push_constant, binding = 0, std140) uniform Pos { vec4 dst_rect; } pos;\n"
"layout(location =0) out vec2 uv;\n" "layout(location =0) out vec2 uv;\n"
"void main() { \n" "void main() { \n"
" vec2 base_arr[4] = float[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));\n" " vec2 base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));\n"
" uv = base_arr[gl_VertexIndex];\n" " uv = base_arr[gl_VertexIndex];\n"
" gl_Position = vec4(dst_rect.xy,uv*dst_rect.zw);\n" " vec2 vtx = pos.dst_rect.xy+uv*pos.dst_rect.zw;\n"
" gl_Position = vec4(vtx * 2.0 - 1.0,0.0,1.0);\n"
"}\n"; "}\n";
RenderingDevice::ShaderStageSource frag; RenderingDevice::ShaderStageSource frag;
@ -124,4 +126,7 @@ void RasterizerRD::finalize() {
} }
RasterizerRD::RasterizerRD() { RasterizerRD::RasterizerRD() {
storage = memnew(RasterizerStorageRD);
canvas = memnew(RasterizerCanvasRD(storage));
scene = memnew(RasterizerSceneForwardRD);
} }

View File

@ -35,7 +35,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
} break; } break;
case Image::FORMAT_RGB8: { case Image::FORMAT_RGB8: {
//this format is not mandatory for specification, check if supported first //this format is not mandatory for specification, check if supported first
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT) && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_SRGB, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { if (false && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT) && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_SRGB, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_R8G8B8_UNORM; r_format.format = RD::DATA_FORMAT_R8G8B8_UNORM;
r_format.format_srgb = RD::DATA_FORMAT_R8G8B8_SRGB; r_format.format_srgb = RD::DATA_FORMAT_R8G8B8_SRGB;
} else { } else {
@ -484,7 +484,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
texture.width = p_image->get_width(); texture.width = p_image->get_width();
texture.height = p_image->get_height(); texture.height = p_image->get_height();
texture.layers = 1; texture.layers = 1;
texture.mipmaps = p_image->get_mipmap_count(); texture.mipmaps = p_image->get_mipmap_count() + 1;
texture.depth = 1; texture.depth = 1;
texture.rd_type = RD::TEXTURE_TYPE_2D; texture.rd_type = RD::TEXTURE_TYPE_2D;
@ -503,6 +503,10 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
rd_format.type = texture.rd_type; rd_format.type = texture.rd_type;
rd_format.samples = RD::TEXTURE_SAMPLES_1; rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
rd_format.shareable_formats.push_back(texture.rd_format);
rd_format.shareable_formats.push_back(texture.rd_format_srgb);
}
} }
{ {
rd_view.swizzle_r = ret_format.swizzle_r; rd_view.swizzle_r = ret_format.swizzle_r;
@ -701,6 +705,10 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
_clear_render_target(rt); _clear_render_target(rt);
if (rt->size.width == 0 || rt->size.height == 0) {
rt->dirty = false;
return;
}
//until we implement suport for HDR monitors (and render target is attached to screen), this is enough. //until we implement suport for HDR monitors (and render target is attached to screen), this is enough.
rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM; rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
@ -718,12 +726,8 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
rd_format.type = RD::TEXTURE_TYPE_2D; rd_format.type = RD::TEXTURE_TYPE_2D;
rd_format.samples = RD::TEXTURE_SAMPLES_1; rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
} rd_format.shareable_formats.push_back(rt->color_format);
{ rd_format.shareable_formats.push_back(rt->color_format_srgb);
rd_view.swizzle_r = RD::TEXTURE_SWIZZLE_R;
rd_view.swizzle_g = RD::TEXTURE_SWIZZLE_R;
rd_view.swizzle_b = RD::TEXTURE_SWIZZLE_R;
rd_view.swizzle_a = rt->flags[RENDER_TARGET_TRANSPARENT] ? RD::TEXTURE_SWIZZLE_A : RD::TEXTURE_SWIZZLE_ONE;
} }
rt->color = RD::get_singleton()->texture_create(rd_format, rd_view); rt->color = RD::get_singleton()->texture_create(rd_format, rd_view);
@ -744,6 +748,8 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
_clear_render_target(rt); _clear_render_target(rt);
ERR_FAIL_COND(rt->framebuffer.is_null()); ERR_FAIL_COND(rt->framebuffer.is_null());
} }
rt->dirty = false;
} }
RID RasterizerStorageRD::render_target_create() { RID RasterizerStorageRD::render_target_create() {

View File

@ -1,51 +0,0 @@
#include "render_pipeline_cache_rd.h"
#include "core/os/memory.h"
RID RenderPipelineCacheRD::_generate_version(RD::VertexFormatID p_format_id) {
RID pipeline = RD::get_singleton()->render_pipeline_create(shader, framebuffer_format, p_format_id, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
ERR_FAIL_COND_V(pipeline.is_null(), RID());
versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
versions[version_count].format_id = p_format_id;
versions[version_count].pipeline = pipeline;
version_count++;
return pipeline;
}
void RenderPipelineCacheRD::_clear() {
if (versions) {
for (uint32_t i = 0; i < version_count; i++) {
RD::get_singleton()->free(versions[i].pipeline);
}
version_count = 0;
memfree(versions);
versions = NULL;
}
}
void RenderPipelineCacheRD::setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
ERR_FAIL_COND(p_shader.is_null());
shader = p_shader;
framebuffer_format = p_framebuffer_format;
render_primitive = p_primitive;
rasterization_state = p_rasterization_state;
multisample_state = p_multisample;
depth_stencil_state = p_depth_stencil_state;
blend_state = p_blend_state;
dynamic_state_flags = p_dynamic_state_flags;
}
void RenderPipelineCacheRD::update_shader(RID p_shader) {
ERR_FAIL_COND(p_shader.is_null());
_clear();
setup(p_shader, framebuffer_format, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
}
RenderPipelineCacheRD::RenderPipelineCacheRD() {
version_count = 0;
versions = NULL;
}
RenderPipelineCacheRD::~RenderPipelineCacheRD() {
_clear();
}

View File

@ -0,0 +1,61 @@
#include "render_pipeline_vertex_format_cache_rd.h"
#include "core/os/memory.h"
RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_format_id, RenderingDevice::TextureSamples p_samples) {
RD::PipelineMultisampleState multisample_state_version;
if (p_samples != RD::TEXTURE_SAMPLES_1) {
multisample_state_version = multisample_state;
multisample_state_version.sample_count = p_samples;
}
RID pipeline = RD::get_singleton()->render_pipeline_create(shader, framebuffer_format, p_format_id, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
ERR_FAIL_COND_V(pipeline.is_null(), RID());
versions[p_samples] = (Version *)memrealloc(versions[p_samples], sizeof(Version) * (version_count[p_samples] + 1));
versions[p_samples][version_count[p_samples]].format_id = p_format_id;
versions[p_samples][version_count[p_samples]].pipeline = pipeline;
version_count[p_samples]++;
return pipeline;
}
void RenderPipelineVertexFormatCacheRD::_clear() {
for (int v = 0; v < RD::TEXTURE_SAMPLES_MAX; v++) {
if (versions[v]) {
for (uint32_t i = 0; i < version_count[v]; i++) {
RD::get_singleton()->free(versions[v][i].pipeline);
}
version_count[v] = 0;
memfree(versions[v]);
versions[v] = NULL;
}
}
}
void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
ERR_FAIL_COND(p_shader.is_null());
shader = p_shader;
framebuffer_format = p_framebuffer_format;
render_primitive = p_primitive;
rasterization_state = p_rasterization_state;
multisample_state = p_multisample;
depth_stencil_state = p_depth_stencil_state;
blend_state = p_blend_state;
dynamic_state_flags = p_dynamic_state_flags;
}
void RenderPipelineVertexFormatCacheRD::update_shader(RID p_shader) {
ERR_FAIL_COND(p_shader.is_null());
_clear();
setup(p_shader, framebuffer_format, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
}
RenderPipelineVertexFormatCacheRD::RenderPipelineVertexFormatCacheRD() {
for (int i = 0; i < RD::TEXTURE_SAMPLES_MAX; i++) {
version_count[i] = 0;
versions[i] = NULL;
}
}
RenderPipelineVertexFormatCacheRD::~RenderPipelineVertexFormatCacheRD() {
_clear();
}

View File

@ -3,7 +3,7 @@
#include "servers/visual/rendering_device.h" #include "servers/visual/rendering_device.h"
class RenderPipelineCacheRD { class RenderPipelineVertexFormatCacheRD {
RID shader; RID shader;
@ -20,10 +20,10 @@ class RenderPipelineCacheRD {
RID pipeline; RID pipeline;
}; };
Version *versions; Version *versions[RD::TEXTURE_SAMPLES_MAX];
uint32_t version_count; uint32_t version_count[RD::TEXTURE_SAMPLES_MAX];
RID _generate_version(RD::VertexFormatID p_format_id); RID _generate_version(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples);
void _clear(); void _clear();
@ -31,17 +31,18 @@ public:
void setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0); void setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
void update_shader(RID p_shader); void update_shader(RID p_shader);
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_format_id) { _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples) {
for (uint32_t i = 0; i < version_count; i++) { ERR_FAIL_INDEX_V(p_samples, RD::TEXTURE_SAMPLES_MAX, RID());
if (versions[i].format_id == p_format_id) { for (uint32_t i = 0; i < version_count[p_samples]; i++) {
return versions[i].pipeline; if (versions[p_samples][i].format_id == p_format_id) {
return versions[p_samples][i].pipeline;
} }
} }
return _generate_version(p_format_id); return _generate_version(p_format_id, p_samples);
} }
RenderPipelineCacheRD(); RenderPipelineVertexFormatCacheRD();
~RenderPipelineCacheRD(); ~RenderPipelineVertexFormatCacheRD();
}; };
#endif // RENDER_PIPELINE_CACHE_RD_H #endif // RENDER_PIPELINE_CACHE_RD_H

View File

@ -179,7 +179,7 @@ void ShaderRD::_compile_version(Version *p_version) {
StringBuilder builder; StringBuilder builder;
builder.append(vertex_codev.get_data()); // version info (if exists) builder.append(vertex_codev.get_data()); // version info (if exists)
builder.append("\n"); //make sure defines begin at newline
builder.append(variant_defines[i].get_data()); builder.append(variant_defines[i].get_data());
for (int j = 0; j < p_version->custom_defines.size(); j++) { for (int j = 0; j < p_version->custom_defines.size(); j++) {
builder.append(p_version->custom_defines[j].get_data()); builder.append(p_version->custom_defines[j].get_data());
@ -212,6 +212,7 @@ void ShaderRD::_compile_version(Version *p_version) {
StringBuilder builder; StringBuilder builder;
builder.append(fragment_codev.get_data()); // version info (if exists) builder.append(fragment_codev.get_data()); // version info (if exists)
builder.append("\n"); //make sure defines begin at newline
builder.append(variant_defines[i].get_data()); builder.append(variant_defines[i].get_data());
for (int j = 0; j < p_version->custom_defines.size(); j++) { for (int j = 0; j < p_version->custom_defines.size(); j++) {

View File

@ -55,7 +55,7 @@ void main() {
vec2 vertex_base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0)); vec2 vertex_base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));
vec2 vertex_base = vertex_base_arr[gl_VertexIndex]; vec2 vertex_base = vertex_base_arr[gl_VertexIndex];
vec2 uv = draw_data.src_rect.xy + draw_data.src_rect.zw * ((draw_data.flags&FLAGS_TRANSPOSE_RECT)!=0 ? vertex_base.xy : vertex_base.yx); vec2 uv = draw_data.src_rect.xy + draw_data.src_rect.zw * ((draw_data.flags&FLAGS_TRANSPOSE_RECT)!=0 ? vertex_base.yx : vertex_base.xy);
vec4 color = vec4(1.0); vec4 color = vec4(1.0);
vec2 vertex = draw_data.dst_rect.xy + abs(draw_data.dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data.src_rect.zw, vec2(0.0, 0.0))); vec2 vertex = draw_data.dst_rect.xy + abs(draw_data.dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data.src_rect.zw, vec2(0.0, 0.0)));
uvec4 bone_indices = uvec4(0,0,0,0); uvec4 bone_indices = uvec4(0,0,0,0);
@ -63,7 +63,7 @@ void main() {
#endif #endif
mat4 world_matrix = mat4(draw_data.world[0],draw_data.world[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0)); mat4 world_matrix = transpose(mat4(draw_data.world[0],draw_data.world[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0)));
#if 0 #if 0
if (draw_data.flags&FLAGS_INSTANCING_ENABLED) { if (draw_data.flags&FLAGS_INSTANCING_ENABLED) {
@ -117,7 +117,7 @@ VERTEX_SHADER_CODE
#ifdef USE_NINEPATCH #ifdef USE_NINEPATCH
pixel_size_interp = abs(draw_data.dst_rect.zw) * vertex; pixel_size_interp = abs(draw_data.dst_rect.zw) * vertex_base;
#endif #endif
#if !defined(SKIP_TRANSFORM_USED) #if !defined(SKIP_TRANSFORM_USED)
@ -175,6 +175,7 @@ VERTEX_SHADER_CODE
} }
#endif #endif
uv_interp = uv;
#if !defined(SKIP_TRANSFORM_USED) #if !defined(SKIP_TRANSFORM_USED)
gl_Position = (canvas_data.screen_transform * canvas_data.canvas_transform) * vec4(vertex,0.0,1.0); gl_Position = (canvas_data.screen_transform * canvas_data.canvas_transform) * vec4(vertex,0.0,1.0);
#else #else
@ -284,20 +285,21 @@ void main() {
vec4 color = color_interp; vec4 color = color_interp;
vec2 uv = uv_interp; vec2 uv = uv_interp;
#ifdef USE_TEXTURE_RECT #ifndef USE_VERTEX_ARRAYS
#ifdef USE_NINEPATCH #ifdef USE_NINEPATCH
int draw_center = 2; int draw_center = 2;
uv = vec2( uv = vec2(
map_ninepatch_axis(pixel_size_interp.x, abs(draw_data.dst_rect.z), draw_data.color_texture_pixel_size.x, draw_data.ninepatch_margins.x, draw_data.ninepatch_margins.z, (draw_data.ninepatch_repeat>>16), draw_center), map_ninepatch_axis(pixel_size_interp.x, abs(draw_data.dst_rect.z), draw_data.color_texture_pixel_size.x, draw_data.ninepatch_margins.x, draw_data.ninepatch_margins.z, int(draw_data.flags>>FLAGS_NINEPATCH_H_MODE_SHIFT)&0x3, draw_center),
map_ninepatch_axis(pixel_size_interp.y, abs(draw_data.dst_rect.w), draw_data.color_texture_pixel_size.y, draw_data.ninepatch_margins.y, draw_data.ninepatch_margins.w, (draw_data.ninepatch_repeat&0xFFFF), draw_center)); map_ninepatch_axis(pixel_size_interp.y, abs(draw_data.dst_rect.w), draw_data.color_texture_pixel_size.y, draw_data.ninepatch_margins.y, draw_data.ninepatch_margins.w, int(draw_data.flags>>FLAGS_NINEPATCH_V_MODE_SHIFT)&0x3, draw_center));
if (draw_center == 0) { if (draw_center == 0) {
color.a = 0.0; color.a = 0.0;
} }
uv = uv * draw_data.src_rect.zw + draw_data.src_rect.xy; //apply region if needed uv = uv * draw_data.src_rect.zw + draw_data.src_rect.xy; //apply region if needed
#endif #endif
if (bool(draw_data.flags&FLAGS_CLIP_RECT_UV)) { if (bool(draw_data.flags&FLAGS_CLIP_RECT_UV)) {
@ -369,4 +371,5 @@ FRAGMENT_SHADER_CODE
#endif #endif
//color.rgb *= color.a; //color.rgb *= color.a;
frag_color = color; frag_color = color;
} }

View File

@ -17,7 +17,10 @@
#define FLAGS_USING_PARTICLES (1 << 13) #define FLAGS_USING_PARTICLES (1 << 13)
#define FLAGS_USE_PIXEL_SNAP (1 << 14) #define FLAGS_USE_PIXEL_SNAP (1 << 14)
#define FLAGS_USE_SKELETON (1 << 16) #define FLAGS_USE_SKELETON (1 << 15)
#define FLAGS_NINEPATCH_H_MODE_SHIFT 16
#define FLAGS_NINEPATCH_V_MODE_SHIFT 18
layout(push_constant, binding = 0, std140) uniform DrawData { layout(push_constant, binding = 0, std140) uniform DrawData {
mat2x4 world; mat2x4 world;
@ -26,8 +29,13 @@ layout(push_constant, binding = 0, std140) uniform DrawData {
vec4 dst_rect; //for built-in rect and UV vec4 dst_rect; //for built-in rect and UV
vec4 src_rect; vec4 src_rect;
uint flags; uint flags;
uint ninepatch_repeat; uint specular_shininess;
vec2 color_texture_pixel_size; vec2 color_texture_pixel_size;
uint pad0;
uint pad1;
uint pad2;
uint pad3;
} draw_data; } draw_data;
// The values passed per draw primitives are cached within it // The values passed per draw primitives are cached within it

View File

@ -7,13 +7,13 @@ class RenderingDevice : public Object {
GDCLASS(RenderingDevice, Object) GDCLASS(RenderingDevice, Object)
static RenderingDevice *singleton; static RenderingDevice *singleton;
public: public:
//base numeric ID for all types //base numeric ID for all types
enum { enum {
INVALID_ID = -1 INVALID_ID = -1
}; };
/*****************/ /*****************/
/**** GENERIC ****/ /**** GENERIC ****/
/*****************/ /*****************/
@ -264,7 +264,6 @@ public:
/**** TEXTURE ****/ /**** TEXTURE ****/
/*****************/ /*****************/
enum TextureType { enum TextureType {
TEXTURE_TYPE_1D, TEXTURE_TYPE_1D,
TEXTURE_TYPE_2D, TEXTURE_TYPE_2D,
@ -319,7 +318,7 @@ public:
TextureType type; TextureType type;
TextureSamples samples; TextureSamples samples;
uint32_t usage_bits; uint32_t usage_bits;
Vector<DataFormat> shareable_formats;
TextureFormat() { TextureFormat() {
format = DATA_FORMAT_R8_UNORM; format = DATA_FORMAT_R8_UNORM;
@ -356,7 +355,6 @@ public:
virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0; virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0;
/*********************/ /*********************/
/**** FRAMEBUFFER ****/ /**** FRAMEBUFFER ****/
/*********************/ /*********************/
@ -510,7 +508,6 @@ public:
virtual RID shader_create_from_source(const Vector<ShaderStageSource> &p_stages, String *r_error = NULL, ShaderStage *r_error_stage = NULL, bool p_allow_cache = true) = 0; virtual RID shader_create_from_source(const Vector<ShaderStageSource> &p_stages, String *r_error = NULL, ShaderStage *r_error_stage = NULL, bool p_allow_cache = true) = 0;
virtual Vector<int> shader_get_vertex_input_locations_used(RID p_shader) = 0; virtual Vector<int> shader_get_vertex_input_locations_used(RID p_shader) = 0;
/******************/ /******************/
/**** UNIFORMS ****/ /**** UNIFORMS ****/
/******************/ /******************/
@ -553,7 +550,6 @@ public:
virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0; virtual RID uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) = 0;
virtual bool uniform_set_is_valid(RID p_uniform_set) = 0; virtual bool uniform_set_is_valid(RID p_uniform_set) = 0;
virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, void *p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
/*************************/ /*************************/
@ -828,7 +824,6 @@ public:
/**** DRAW LISTS ****/ /**** DRAW LISTS ****/
/********************/ /********************/
enum InitialAction { enum InitialAction {
INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params) INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params)
INITIAL_ACTION_KEEP_COLOR, //start rendering, but keep attached color texture contents (depth will be cleared) INITIAL_ACTION_KEEP_COLOR, //start rendering, but keep attached color texture contents (depth will be cleared)
@ -847,7 +842,6 @@ public:
typedef int64_t DrawListID; typedef int64_t DrawListID;
virtual DrawListID draw_list_begin_for_screen(int p_screen = 0, const Color &p_clear_color = Color()) = 0; virtual DrawListID draw_list_begin_for_screen(int p_screen = 0, const Color &p_clear_color = Color()) = 0;
virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), const Rect2 &p_region = Rect2()) = 0; virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), const Rect2 &p_region = Rect2()) = 0;
virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), const Rect2 &p_region = Rect2()) = 0; virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), const Rect2 &p_region = Rect2()) = 0;
@ -880,7 +874,6 @@ public:
RenderingDevice(); RenderingDevice();
}; };
typedef RenderingDevice RD; typedef RenderingDevice RD;
#endif // RENDERING_DEVICE_H #endif // RENDERING_DEVICE_H