Commit 42b44f43 by Juan Linietsky Committed by Juan Linietsky

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

parent 9b0dd4f5
...@@ -45,7 +45,7 @@ public: ...@@ -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: ...@@ -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) {
......
...@@ -721,7 +721,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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;
......
...@@ -101,6 +101,8 @@ class RenderingDeviceVulkan : public RenderingDevice { ...@@ -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;
......
...@@ -18,6 +18,12 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(VkDebugU ...@@ -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) {
......
...@@ -649,6 +649,7 @@ void register_scene_types() { ...@@ -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>();
......
...@@ -42,7 +42,15 @@ ...@@ -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: ...@@ -332,7 +340,7 @@ public:
LargeTexture(); LargeTexture();
}; };
class TextureLayered : public Resource { class TextureLayered : public Texture {
GDCLASS(TextureLayered, Resource); GDCLASS(TextureLayered, Resource);
......
...@@ -131,7 +131,7 @@ RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(R ...@@ -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() { ...@@ -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_ ...@@ -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_ ...@@ -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_ ...@@ -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_ ...@@ -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_ ...@@ -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 ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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;
} }
} }
......
...@@ -3,6 +3,7 @@ ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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);
......
...@@ -3,6 +3,7 @@ ...@@ -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 ...@@ -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 ...@@ -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) { ...@@ -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() { ...@@ -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() { ...@@ -124,4 +126,7 @@ void RasterizerRD::finalize() {
} }
RasterizerRD::RasterizerRD() { RasterizerRD::RasterizerRD() {
storage = memnew(RasterizerStorageRD);
canvas = memnew(RasterizerCanvasRD(storage));
scene = memnew(RasterizerSceneForwardRD);
} }
...@@ -35,7 +35,7 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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() {
......
#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();
}
#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();
}
...@@ -3,7 +3,7 @@ ...@@ -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 { ...@@ -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: ...@@ -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
...@@ -179,7 +179,7 @@ void ShaderRD::_compile_version(Version *p_version) { ...@@ -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) { ...@@ -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++) {
......
...@@ -55,7 +55,7 @@ void main() { ...@@ -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() { ...@@ -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 ...@@ -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 ...@@ -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() { ...@@ -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 ...@@ -369,4 +371,5 @@ FRAGMENT_SHADER_CODE
#endif #endif
//color.rgb *= color.a; //color.rgb *= color.a;
frag_color = color; frag_color = color;
} }
...@@ -17,7 +17,10 @@ ...@@ -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 { ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment