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:
if (alloc_count == max_alloc) {
//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
chunks = (T **)memrealloc(chunks, sizeof(T *) * (chunk_count + 1));
......@@ -140,8 +140,8 @@ public:
chunks[idx_chunk][idx_element].~T();
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--;
free_list_chunks[alloc_count / elements_in_chunk][alloc_count % elements_in_chunk] = idx;
}
void get_owned_list(List<RID> *p_owned) {
......
......@@ -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_D16_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_SRGB_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_SRGB_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_PVRTC2_4BPP_UNORM_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_PVRTC2_2BPP_UNORM_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: {
}
}
......@@ -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 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;
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.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) {
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.usage_flags = p_format.usage_bits;
texture.samples = p_format.samples;
texture.allowed_shared_formats = p_format.shareable_formats;
//set bound and unbound layouts
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];
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];
} else {
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];
}
......@@ -1877,6 +1903,13 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
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 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,
"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);
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;
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 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);
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);
uint8_t *write_ptr;
......@@ -2937,7 +2970,7 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
bindings.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));
#endif
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++) {
if (program.getPipeInput(i).getType()->getQualifier().hasLocation()) {
int location = program.getPipeInput(i).getType()->getQualifier().layoutLocation;
print_line("found vertex location: " + itos(location));
if (vertex_input_locations.find(location) == -1) {
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();
const Uniform *uniforms = p_uniforms.ptr();
print_line("uniform count: " + itos(uniform_count));
uint32_t set_uniform_count = set.uniform_info.size();
const Shader::UniformInfo *set_uniforms = set.uniform_info.ptr();
print_line("set_uniform count: " + itos(set_uniform_count));
Vector<VkWriteDescriptorSet> writes;
DescriptorPoolKey pool_key;
......
......@@ -101,6 +101,8 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t mipmaps;
uint32_t usage_flags;
Vector<DataFormat> allowed_shared_formats;
VkImageLayout bound_layout; //layout used when bound to framebuffer being drawn
VkImageLayout unbound_layout; //layout used otherwise
uint32_t aspect_mask;
......
......@@ -18,6 +18,12 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(VkDebugU
char *message = (char *)malloc(strlen(pCallbackData->pMessage) + 5000);
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) {
strcat(prefix, "VERBOSE : ");
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
......
......@@ -649,6 +649,7 @@ void register_scene_types() {
ClassDB::register_class<World>();
ClassDB::register_class<Environment>();
ClassDB::register_class<World2D>();
ClassDB::register_virtual_class<Texture>();
ClassDB::register_virtual_class<Texture2D>();
ClassDB::register_virtual_class<Sky>();
ClassDB::register_class<PanoramaSky>();
......
......@@ -42,7 +42,15 @@
#include "servers/camera_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);
OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged.
......@@ -332,7 +340,7 @@ public:
LargeTexture();
};
class TextureLayered : public Resource {
class TextureLayered : public Texture {
GDCLASS(TextureLayered, Resource);
......
......@@ -131,7 +131,7 @@ RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(R
u.binding = 2;
RID texture = storage->texture_get_rd_texture(p_normalmap);
if (!texture.is_valid()) {
//use default white texture
//use default normal texture
texture = default_textures.normal_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();
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.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[1] = 0;
push_constant.specular_shininess = 0xFFFFFFFF;
push_constant.pad[0] = 0;
push_constant.pad[1] = 0;
push_constant.pad[2] = 0;
......@@ -347,7 +346,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//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);
}
......@@ -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);
ERR_CONTINUE(!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);
if (texture_binding->key.texture.is_valid()) {
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
{
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);
}
......@@ -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[1] = texpixel_size.y;
push_constant.ninepatch_repeat = int(np->axis_x) << 16;
push_constant.ninepatch_repeat |= int(np->axis_y);
push_constant.flags |= int(np->axis_x) << FLAGS_NINEPATCH_H_MODE_SHIFT;
push_constant.flags |= int(np->axis_y) << FLAGS_NINEPATCH_V_MODE_SHIFT;
if (np->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) {
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::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);
}
_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();
......@@ -1180,7 +1181,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
RD::AttachmentFormat af;
af.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
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;
formats.push_back(af);
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 };
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] = pipeline;
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);
}
}
......
......@@ -3,6 +3,7 @@
#include "servers/visual/rasterizer/rasterizer.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/rendering_device.h"
......@@ -38,7 +39,9 @@ class RasterizerCanvasRD : public RasterizerCanvas {
FLAGS_USING_PARTICLES = (1 << 13),
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_LINES,
PIPELINE_VARIANT_POINTS,
PIPELINE_VARIANT_TRIANGLES_COMPRESSED,
PIPELINE_VARIANT_LINES_COMPRESSED,
PIPELINE_VARIANT_POINTS_COMPRESSED,
PIPELINE_VARIANT_MAX
};
struct PipelineVariants {
RID variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX];
RenderPipelineVertexFormatCacheRD variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX];
};
struct {
......@@ -177,10 +177,9 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float dst_rect[4];
float src_rect[4];
uint32_t flags;
uint32_t ninepatch_repeat;
float color_texture_pixel_size[2];
uint32_t specular_shininess;
uint32_t pad[3];
float color_texture_pixel_size[2];
uint32_t pad[4];
};
struct SkeletonUniform {
......@@ -194,7 +193,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
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 _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
......
......@@ -3,6 +3,7 @@
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);
for (int i = 0; i < p_amount; i++) {
RID texture = storage->render_target_get_texture(p_render_targets[i].render_target);
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.ids.push_back(copy_viewports_sampler);
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);
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_draw(draw_list, true);
}
RD::get_singleton()->draw_list_end();
}
void RasterizerRD::begin_frame(double frame_step) {
......@@ -48,9 +52,6 @@ void RasterizerRD::end_frame(bool p_swap_buffers) {
}
void RasterizerRD::initialize() {
storage = memnew(RasterizerStorageRD);
canvas = memnew(RasterizerCanvasRD(storage));
scene = memnew(RasterizerSceneForwardRD);
{ //create framebuffer copy shader
RenderingDevice::ShaderStageSource vert;
......@@ -60,9 +61,10 @@ void RasterizerRD::initialize() {
"layout(push_constant, binding = 0, std140) uniform Pos { vec4 dst_rect; } pos;\n"
"layout(location =0) out vec2 uv;\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"
" 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";
RenderingDevice::ShaderStageSource frag;
......@@ -124,4 +126,7 @@ void RasterizerRD::finalize() {
}
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
} break;
case Image::FORMAT_RGB8: {
//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_srgb = RD::DATA_FORMAT_R8G8B8_SRGB;
} else {
......@@ -484,7 +484,7 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
texture.width = p_image->get_width();
texture.height = p_image->get_height();
texture.layers = 1;
texture.mipmaps = p_image->get_mipmap_count();
texture.mipmaps = p_image->get_mipmap_count() + 1;
texture.depth = 1;
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.samples = RD::TEXTURE_SAMPLES_1;
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;
......@@ -701,6 +705,10 @@ void RasterizerStorageRD::_update_render_target(RenderTarget *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.
rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
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.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
{
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;
rd_format.shareable_formats.push_back(rt->color_format);
rd_format.shareable_formats.push_back(rt->color_format_srgb);
}
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);
ERR_FAIL_COND(rt->framebuffer.is_null());
}
rt->dirty = false;
}
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 @@
#include "servers/visual/rendering_device.h"
class RenderPipelineCacheRD {
class RenderPipelineVertexFormatCacheRD {
RID shader;
......@@ -20,10 +20,10 @@ class RenderPipelineCacheRD {
RID pipeline;
};
Version *versions;
uint32_t version_count;
Version *versions[RD::TEXTURE_SAMPLES_MAX];
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();
......@@ -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 update_shader(RID p_shader);
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_format_id) {
for (uint32_t i = 0; i < version_count; i++) {
if (versions[i].format_id == p_format_id) {
return versions[i].pipeline;
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples) {
ERR_FAIL_INDEX_V(p_samples, RD::TEXTURE_SAMPLES_MAX, RID());
for (uint32_t i = 0; i < version_count[p_samples]; i++) {
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();
~RenderPipelineCacheRD();
RenderPipelineVertexFormatCacheRD();
~RenderPipelineVertexFormatCacheRD();
};
#endif // RENDER_PIPELINE_CACHE_RD_H
......@@ -179,7 +179,7 @@ void ShaderRD::_compile_version(Version *p_version) {
StringBuilder builder;
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());
for (int j = 0; j < p_version->custom_defines.size(); j++) {
builder.append(p_version->custom_defines[j].get_data());
......@@ -212,6 +212,7 @@ void ShaderRD::_compile_version(Version *p_version) {
StringBuilder builder;
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());
for (int j = 0; j < p_version->custom_defines.size(); j++) {
......
......@@ -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 = 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);
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);
......@@ -63,7 +63,7 @@ void main() {
#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 (draw_data.flags&FLAGS_INSTANCING_ENABLED) {
......@@ -117,7 +117,7 @@ VERTEX_SHADER_CODE
#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
#if !defined(SKIP_TRANSFORM_USED)
......@@ -175,6 +175,7 @@ VERTEX_SHADER_CODE
}
#endif
uv_interp = uv;
#if !defined(SKIP_TRANSFORM_USED)
gl_Position = (canvas_data.screen_transform * canvas_data.canvas_transform) * vec4(vertex,0.0,1.0);
#else
......@@ -284,20 +285,21 @@ void main() {
vec4 color = color_interp;
vec2 uv = uv_interp;
#ifdef USE_TEXTURE_RECT
#ifndef USE_VERTEX_ARRAYS
#ifdef USE_NINEPATCH
int draw_center = 2;
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.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.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, int(draw_data.flags>>FLAGS_NINEPATCH_V_MODE_SHIFT)&0x3, draw_center));
if (draw_center == 0) {
color.a = 0.0;
}
uv = uv * draw_data.src_rect.zw + draw_data.src_rect.xy; //apply region if needed
#endif
if (bool(draw_data.flags&FLAGS_CLIP_RECT_UV)) {
......@@ -369,4 +371,5 @@ FRAGMENT_SHADER_CODE
#endif
//color.rgb *= color.a;
frag_color = color;
}
......@@ -17,7 +17,10 @@
#define FLAGS_USING_PARTICLES (1 << 13)
#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 {
mat2x4 world;
......@@ -26,8 +29,13 @@ layout(push_constant, binding = 0, std140) uniform DrawData {
vec4 dst_rect; //for built-in rect and UV
vec4 src_rect;
uint flags;
uint ninepatch_repeat;
uint specular_shininess;
vec2 color_texture_pixel_size;
uint pad0;
uint pad1;
uint pad2;
uint pad3;
} draw_data;
// 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