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) {
//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) {

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_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;

View File

@ -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;

View File

@ -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) {

View File

@ -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>();

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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() {

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"
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

View File

@ -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++) {

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 = 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;
}

View File

@ -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

View File

@ -7,13 +7,13 @@ class RenderingDevice : public Object {
GDCLASS(RenderingDevice, Object)
static RenderingDevice *singleton;
public:
//base numeric ID for all types
enum {
INVALID_ID = -1
};
/*****************/
/**** GENERIC ****/
/*****************/
@ -264,7 +264,6 @@ public:
/**** TEXTURE ****/
/*****************/
enum TextureType {
TEXTURE_TYPE_1D,
TEXTURE_TYPE_2D,
@ -319,7 +318,7 @@ public:
TextureType type;
TextureSamples samples;
uint32_t usage_bits;
Vector<DataFormat> shareable_formats;
TextureFormat() {
format = DATA_FORMAT_R8_UNORM;
@ -342,7 +341,7 @@ public:
TextureSwizzle swizzle_a;
TextureView() {
format_override=DATA_FORMAT_MAX; //means, use same as format
format_override = DATA_FORMAT_MAX; //means, use same as format
swizzle_r = TEXTURE_SWIZZLE_R;
swizzle_g = TEXTURE_SWIZZLE_G;
swizzle_b = TEXTURE_SWIZZLE_B;
@ -350,12 +349,11 @@ public:
}
};
virtual RID texture_create(const TextureFormat &p_format,const TextureView& p_view, const Vector<PoolVector<uint8_t> >&p_data = Vector<PoolVector<uint8_t> >()) = 0;
virtual RID texture_create_shared(const TextureView& p_view, RID p_with_texture) = 0;
virtual Error texture_update(RID p_texture,uint32_t p_layer,const PoolVector<uint8_t>&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 bool texture_is_format_supported_for_usage(DataFormat p_format,uint32_t p_usage) const = 0;
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >()) = 0;
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0;
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &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 bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0;
/*********************/
/**** FRAMEBUFFER ****/
@ -370,9 +368,9 @@ public:
typedef int64_t FramebufferFormatID;
// This ID is warranted to be unique for the same formats, does not need to be freed
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat>& p_format) =0;
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format) = 0;
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments,FramebufferFormatID p_format_check=INVALID_ID) = 0;
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID) = 0;
virtual FramebufferFormatID framebuffer_get_format(RID p_framebuffer) = 0;
@ -422,21 +420,21 @@ public:
bool unnormalized_uvw;
SamplerState() {
mag_filter=SAMPLER_FILTER_NEAREST;
min_filter=SAMPLER_FILTER_NEAREST;
mip_filter=SAMPLER_FILTER_NEAREST;
repeat_u=SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
repeat_v=SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
repeat_w=SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
lod_bias=0;
use_anisotropy=false;
anisotropy_max=1.0;
enable_compare=false;
compare_op=COMPARE_OP_ALWAYS;
min_lod=0;
max_lod=1e20; //something very large should do
border_color=SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
unnormalized_uvw=false;
mag_filter = SAMPLER_FILTER_NEAREST;
min_filter = SAMPLER_FILTER_NEAREST;
mip_filter = SAMPLER_FILTER_NEAREST;
repeat_u = SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
repeat_v = SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
repeat_w = SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
lod_bias = 0;
use_anisotropy = false;
anisotropy_max = 1.0;
enable_compare = false;
compare_op = COMPARE_OP_ALWAYS;
min_lod = 0;
max_lod = 1e20; //something very large should do
border_color = SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
unnormalized_uvw = false;
}
};
@ -458,11 +456,11 @@ public:
uint32_t stride;
VertexFrequency frequency;
VertexDescription() {
location=0;
offset=0;
stride=0;
format=DATA_FORMAT_MAX;
frequency=VERTEX_FREQUENCY_VERTEX;
location = 0;
offset = 0;
stride = 0;
format = DATA_FORMAT_MAX;
frequency = VERTEX_FREQUENCY_VERTEX;
}
};
virtual RID vertex_buffer_create(uint32_t p_size_bytes, const PoolVector<uint8_t> &p_data = PoolVector<uint8_t>()) = 0;
@ -471,15 +469,15 @@ public:
// This ID is warranted to be unique for the same formats, does not need to be freed
virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) = 0;
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format,const Vector<RID>& p_src_buffers) = 0;
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0;
enum IndexBufferFormat {
INDEX_BUFFER_FORMAT_UINT16,
INDEX_BUFFER_FORMAT_UINT32,
};
virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const PoolVector<uint8_t> &p_data = PoolVector<uint8_t>(),bool p_use_restart_indices=false) = 0;
virtual RID index_array_create(RID p_index_buffer, uint32_t p_index_offset, uint32_t p_index_count) =0;
virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const PoolVector<uint8_t> &p_data = PoolVector<uint8_t>(), bool p_use_restart_indices = false) = 0;
virtual RID index_array_create(RID p_index_buffer, uint32_t p_index_offset, uint32_t p_index_count) = 0;
/****************/
/**** SHADER ****/
@ -503,14 +501,13 @@ public:
ShaderStage shader_stage;
String shader_source;
ShaderStageSource() {
shader_stage=SHADER_STAGE_VERTEX;
shader_stage = SHADER_STAGE_VERTEX;
}
};
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;
/******************/
/**** UNIFORMS ****/
/******************/
@ -529,9 +526,9 @@ public:
UNIFORM_TYPE_MAX
};
virtual RID uniform_buffer_create(uint32_t p_size_bytes,const PoolVector<uint8_t>& p_data=PoolVector<uint8_t>()) =0;
virtual RID storage_buffer_create(uint32_t p_size,const PoolVector<uint8_t>& p_data=PoolVector<uint8_t>()) =0;
virtual RID texture_buffer_create(uint32_t p_size_elements,DataFormat p_format,const PoolVector<uint8_t>& p_data=PoolVector<uint8_t>()) =0;
virtual RID uniform_buffer_create(uint32_t p_size_bytes, const PoolVector<uint8_t> &p_data = PoolVector<uint8_t>()) = 0;
virtual RID storage_buffer_create(uint32_t p_size, const PoolVector<uint8_t> &p_data = PoolVector<uint8_t>()) = 0;
virtual RID texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const PoolVector<uint8_t> &p_data = PoolVector<uint8_t>()) = 0;
struct Uniform {
UniformType type;
@ -545,16 +542,15 @@ public:
Vector<RID> ids;
Uniform() {
type=UNIFORM_TYPE_IMAGE;
binding=0;
type = UNIFORM_TYPE_IMAGE;
binding = 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 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 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
/*************************/
/**** RENDER PIPELINE ****/
@ -675,7 +671,7 @@ public:
depth_bias_clamp = 0;
depth_bias_slope_factor = 0;
line_width = 1.0;
patch_control_points=1;
patch_control_points = 1;
}
};
@ -771,20 +767,20 @@ public:
}
};
static PipelineColorBlendState create_disabled(int p_attachments=1) {
static PipelineColorBlendState create_disabled(int p_attachments = 1) {
PipelineColorBlendState bs;
for(int i=0;i<p_attachments;i++) {
for (int i = 0; i < p_attachments; i++) {
bs.attachments.push_back(Attachment());
}
return bs;
}
static PipelineColorBlendState create_blend(int p_attachments=1) {
static PipelineColorBlendState create_blend(int p_attachments = 1) {
PipelineColorBlendState bs;
for(int i=0;i<p_attachments;i++) {
for (int i = 0; i < p_attachments; i++) {
Attachment ba;
ba.enable_blend=true;
ba.enable_blend = true;
ba.src_color_blend_factor = BLEND_FACTOR_SRC_ALPHA;
ba.dst_color_blend_factor = BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
ba.src_alpha_blend_factor = BLEND_FACTOR_SRC_ALPHA;
@ -814,7 +810,7 @@ public:
DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6),
};
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format,RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags=0) = 0;
virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0;
/****************/
/**** SCREEN ****/
@ -828,7 +824,6 @@ public:
/**** DRAW LISTS ****/
/********************/
enum InitialAction {
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)
@ -847,40 +842,38 @@ public:
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(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 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 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 void draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline) = 0;
virtual void draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index) =0;
virtual void draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index) = 0;
virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0;
virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array) = 0;
virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data,uint32_t p_data_size) =0;
virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) = 0;
virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances=1) = 0;
virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1) = 0;
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2& p_rect) = 0;
virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect) = 0;
virtual void draw_list_disable_scissor(DrawListID p_list) = 0;
virtual void draw_list_end() =0;
virtual void draw_list_end() = 0;
/***************/
/**** FREE! ****/
/***************/
virtual void free(RID p_id) =0;
virtual void free(RID p_id) = 0;
//methods below not exposed, used by RenderingDeviceRD
virtual void finalize_frame() =0;
virtual void advance_frame() =0;
virtual void finalize_frame() = 0;
virtual void advance_frame() = 0;
static RenderingDevice *get_singleton();
RenderingDevice();
};
typedef RenderingDevice RD;
#endif // RENDERING_DEVICE_H