Commit ef083a58 by Juan Linietsky

Modified light rendering to make it more compatible.

Modified polygon management to make it more compatible with MoltenVK
parent a3f8ffac
......@@ -1866,6 +1866,93 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
return id;
}
RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, int p_layer, int p_mipmap) {
Texture *src_texture = texture_owner.getornull(p_with_texture);
ERR_FAIL_COND_V(!src_texture, RID());
if (src_texture->owner.is_valid()) { //ahh this is a share
p_with_texture = src_texture->owner;
src_texture = texture_owner.getornull(src_texture->owner);
ERR_FAIL_COND_V(!src_texture, RID()); //this is a bug
}
//create view
Texture texture = *src_texture;
uint32_t array_layer_multiplier = 1;
if (texture.type == TEXTURE_TYPE_CUBE_ARRAY || texture.type == TEXTURE_TYPE_CUBE) {
array_layer_multiplier = 6;
}
VkImageViewCreateInfo image_view_create_info;
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
image_view_create_info.pNext = NULL;
image_view_create_info.flags = 0;
image_view_create_info.image = texture.image;
static const VkImageViewType view_types[TEXTURE_TYPE_MAX] = {
VK_IMAGE_VIEW_TYPE_1D,
VK_IMAGE_VIEW_TYPE_2D,
VK_IMAGE_VIEW_TYPE_2D,
VK_IMAGE_VIEW_TYPE_2D,
VK_IMAGE_VIEW_TYPE_1D,
VK_IMAGE_VIEW_TYPE_2D,
VK_IMAGE_VIEW_TYPE_2D,
};
image_view_create_info.viewType = view_types[texture.type];
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];
}
static const VkComponentSwizzle component_swizzles[TEXTURE_SWIZZLE_MAX] = {
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_ZERO,
VK_COMPONENT_SWIZZLE_ONE,
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B,
VK_COMPONENT_SWIZZLE_A
};
image_view_create_info.components.r = component_swizzles[p_view.swizzle_r];
image_view_create_info.components.g = component_swizzles[p_view.swizzle_g];
image_view_create_info.components.b = component_swizzles[p_view.swizzle_b];
image_view_create_info.components.a = component_swizzles[p_view.swizzle_a];
ERR_FAIL_INDEX_V(p_mipmap, texture.mipmaps, RID());
image_view_create_info.subresourceRange.baseMipLevel = p_mipmap;
image_view_create_info.subresourceRange.levelCount = 1;
image_view_create_info.subresourceRange.layerCount = 1;
image_view_create_info.subresourceRange.baseArrayLayer = p_layer;
if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
} else {
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
VkResult err = vkCreateImageView(device, &image_view_create_info, NULL, &texture.view);
if (err) {
ERR_FAIL_V(RID());
}
texture.owner = p_with_texture;
RID id = texture_owner.make_rid(texture);
_add_dependency(id, p_with_texture);
return id;
}
Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw) {
_THREAD_SAFE_METHOD_
......@@ -2618,10 +2705,18 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
fb_format.E = E;
fb_format.color_attachments = color_references;
fb_format.render_pass = render_pass;
fb_format.samples = p_format[0].samples;
framebuffer_formats[id] = fb_format;
return id;
}
RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_texture_samples(FramebufferFormatID p_format) {
Map<FramebufferFormatID, FramebufferFormat>::Element *E = framebuffer_formats.find(p_format);
ERR_FAIL_COND_V(!E, TEXTURE_SAMPLES_1);
return E->get().samples;
}
/***********************/
/**** RENDER TARGET ****/
/***********************/
......@@ -5689,6 +5784,41 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) {
}
}
int RenderingDeviceVulkan::limit_get(Limit p_limit) {
switch (p_limit) {
case LIMIT_MAX_BOUND_UNIFORM_SETS: return limits.maxBoundDescriptorSets;
case LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS: return limits.maxColorAttachments;
case LIMIT_MAX_TEXTURES_PER_UNIFORM_SET: return limits.maxDescriptorSetSampledImages;
case LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET: return limits.maxDescriptorSetSamplers;
case LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageBuffers;
case LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageImages;
case LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetUniformBuffers;
case LIMIT_MAX_DRAW_INDEXED_INDEX: return limits.maxDrawIndexedIndexValue;
case LIMIT_MAX_FRAMEBUFFER_HEIGHT: return limits.maxFramebufferHeight;
case LIMIT_MAX_FRAMEBUFFER_WIDTH: return limits.maxFramebufferWidth;
case LIMIT_MAX_TEXTURE_ARRAY_LAYERS: return limits.maxImageArrayLayers;
case LIMIT_MAX_TEXTURE_SIZE_1D: return limits.maxImageDimension1D;
case LIMIT_MAX_TEXTURE_SIZE_2D: return limits.maxImageDimension2D;
case LIMIT_MAX_TEXTURE_SIZE_3D: return limits.maxImageDimension3D;
case LIMIT_MAX_TEXTURE_SIZE_CUBE: return limits.maxImageDimensionCube;
case LIMIT_MAX_TEXTURES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSampledImages;
case LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSamplers;
case LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageBuffers;
case LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageImages;
case LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorUniformBuffers;
case LIMIT_MAX_PUSH_CONSTANT_SIZE: return limits.maxPushConstantsSize;
case LIMIT_MAX_UNIFORM_BUFFER_SIZE: return limits.maxUniformBufferRange;
case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET: return limits.maxVertexInputAttributeOffset;
case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES: return limits.maxVertexInputAttributes;
case LIMIT_MAX_VERTEX_INPUT_BINDINGS: return limits.maxVertexInputBindings;
case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE: return limits.maxVertexInputBindingStride;
case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: return limits.minUniformBufferOffsetAlignment;
default: ERR_FAIL_V(0);
}
return 0;
}
void RenderingDeviceVulkan::finalize() {
//free all resources
......
......@@ -234,6 +234,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E;
VkRenderPass render_pass; //here for constructing shaders, never used, see section (7.2. Render Pass Compatibility from Vulkan spec)
int color_attachments; //used for pipeline validation
TextureSamples samples;
};
Map<FramebufferFormatID, FramebufferFormat> framebuffer_formats;
......@@ -714,6 +715,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >());
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, int p_layer, int p_mipmap);
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false);
virtual PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer);
......@@ -725,7 +727,8 @@ public:
/**** FRAMEBUFFER ****/
/*********************/
FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format);
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format);
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format);
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID);
......@@ -814,6 +817,8 @@ public:
virtual void free(RID p_id);
virtual int limit_get(Limit p_limit);
virtual void prepare_screen_for_drawing();
void initialize(VulkanContext *p_context);
void finalize();
......
......@@ -86,6 +86,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(VkDebugU
free(message);
abort();
// Don't bail out, but keep going.
return false;
}
......
......@@ -296,17 +296,6 @@ int Light2D::get_shadow_buffer_size() const {
return shadow_buffer_size;
}
void Light2D::set_shadow_gradient_length(float p_multiplier) {
shadow_gradient_length = p_multiplier;
VS::get_singleton()->canvas_light_set_shadow_gradient_length(canvas_light, p_multiplier);
}
float Light2D::get_shadow_gradient_length() const {
return shadow_gradient_length;
}
void Light2D::set_shadow_filter(ShadowFilter p_filter) {
ERR_FAIL_INDEX(p_filter, SHADOW_FILTER_MAX);
shadow_filter = p_filter;
......@@ -427,9 +416,6 @@ void Light2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth);
ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth);
ClassDB::bind_method(D_METHOD("set_shadow_gradient_length", "multiplier"), &Light2D::set_shadow_gradient_length);
ClassDB::bind_method(D_METHOD("get_shadow_gradient_length"), &Light2D::get_shadow_gradient_length);
ClassDB::bind_method(D_METHOD("set_shadow_filter", "filter"), &Light2D::set_shadow_filter);
ClassDB::bind_method(D_METHOD("get_shadow_filter"), &Light2D::get_shadow_filter);
......@@ -456,7 +442,6 @@ void Light2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow_enabled", "is_shadow_enabled");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13"), "set_shadow_filter", "get_shadow_filter");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask");
......@@ -488,7 +473,6 @@ Light2D::Light2D() {
item_shadow_mask = 1;
mode = MODE_ADD;
shadow_buffer_size = 2048;
shadow_gradient_length = 0;
energy = 1.0;
shadow_color = Color(0, 0, 0, 0);
shadow_filter = SHADOW_FILTER_NONE;
......
......@@ -70,7 +70,6 @@ private:
int item_shadow_mask;
int shadow_buffer_size;
float shadow_smooth;
float shadow_gradient_length;
Mode mode;
Ref<Texture2D> texture;
Vector2 texture_offset;
......@@ -147,9 +146,6 @@ public:
void set_shadow_buffer_size(int p_size);
int get_shadow_buffer_size() const;
void set_shadow_gradient_length(float p_multiplier);
float get_shadow_gradient_length() const;
void set_shadow_filter(ShadowFilter p_filter);
ShadowFilter get_shadow_filter() const;
......
......@@ -618,7 +618,6 @@ public:
RID canvas;
bool use_shadow;
int shadow_buffer_size;
float shadow_gradient_length;
VS::CanvasLightShadowFilter shadow_filter;
Color shadow_color;
float shadow_smooth;
......@@ -638,10 +637,12 @@ public:
Light *mask_next_ptr;
RID light_internal;
uint64_t version;
int32_t render_index_cache;
Light() {
version = 0;
enabled = true;
color = Color(1, 1, 1);
shadow_color = Color(0, 0, 0, 0);
......@@ -661,7 +662,6 @@ public:
filter_next_ptr = NULL;
use_shadow = false;
shadow_buffer_size = 2048;
shadow_gradient_length = 0;
shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE;
shadow_smooth = 0.0;
render_index_cache = -1;
......@@ -1064,6 +1064,13 @@ public:
return command;
}
struct CustomData {
virtual ~CustomData() {}
};
mutable CustomData *custom_data; //implementation dependent
void clear() {
Command *c = commands;
while (c) {
......@@ -1112,6 +1119,7 @@ public:
light_masked = false;
update_when_visible = false;
z_final = 0;
custom_data = NULL;
}
virtual ~Item() {
clear();
......@@ -1119,6 +1127,9 @@ public:
memfree(blocks[i].memory);
}
if (copy_back_buffer) memdelete(copy_back_buffer);
if (custom_data) {
memdelete(custom_data);
}
}
};
......
......@@ -6,7 +6,6 @@
#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_occlusion.glsl.gen.h"
#include "servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl.gen.h"
#include "servers/visual/rendering_device.h"
class RasterizerCanvasRD : public RasterizerCanvas {
......@@ -20,15 +19,15 @@ class RasterizerCanvasRD : public RasterizerCanvas {
SHADER_VARIANT_PRIMITIVE_POINTS,
SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES_POINTS,
SHADER_VARIANT_QUAD_LIGHT,
SHADER_VARIANT_NINEPATCH_LIGHT,
SHADER_VARIANT_PRIMITIVE_LIGHT,
SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT,
SHADER_VARIANT_ATTRIBUTES_LIGHT,
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT,
SHADER_VARIANT_MAX
};
enum RenderTargetFormat {
RENDER_TARGET_FORMAT_8_BIT_INT,
RENDER_TARGET_FORMAT_16_BIT_FLOAT,
RENDER_TARGET_FORMAT_MAX
};
enum {
FLAGS_INSTANCING_STRIDE_MASK = 0xF,
FLAGS_INSTANCING_ENABLED = (1 << 4),
......@@ -71,8 +70,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
enum {
MAX_RENDER_ITEMS = 256 * 1024,
MAX_LIGHT_TEXTURES = 1024,
MAX_LIGHTS_PER_ITEM = 16,
MAX_RENDER_LIGHTS = 256
DEFAULT_MAX_LIGHTS_PER_ITEM = 16,
DEFAULT_MAX_LIGHTS_PER_RENDER = 256
};
/****************/
......@@ -90,22 +89,28 @@ class RasterizerCanvasRD : public RasterizerCanvas {
PIPELINE_VARIANT_ATTRIBUTE_POINTS,
PIPELINE_VARIANT_MAX
};
enum PipelineLightMode {
PIPELINE_LIGHT_MODE_DISABLED,
PIPELINE_LIGHT_MODE_ENABLED,
PIPELINE_LIGHT_MODE_MAX
};
struct PipelineVariants {
RenderPipelineVertexFormatCacheRD variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX];
RenderPipelineVertexFormatCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX];
};
struct {
CanvasShaderRD canvas_shader;
RD::FramebufferFormatID framebuffer_formats[RENDER_TARGET_FORMAT_MAX];
RID default_version;
RID default_version_rd_shader;
RID default_version_rd_shader_light;
RID quad_index_buffer;
RID quad_index_array;
PipelineVariants pipeline_variants;
// default_skeleton uniform set
RID default_skeleton_uniform;
RID default_skeleton_uniform_set;
RID default_skeleton_uniform_buffer;
RID default_skeleton_texture_buffer;
} shader;
......@@ -194,6 +199,10 @@ class RasterizerCanvasRD : public RasterizerCanvas {
struct {
HashMap<PolygonID, PolygonBuffers> polygons;
PolygonID last_id;
RID default_color_buffer;
RID default_uv_buffer;
RID default_bone_buffer;
RID default_weight_buffer;
} polygon_buffers;
/********************/
......@@ -214,7 +223,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
struct CanvasLight {
int32_t texture_index;
RID texture;
struct {
int size;
......@@ -256,9 +264,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float position[2];
uint32_t flags; //index to light texture
float height;
float shadow_softness;
float shadow_pixel_size;
float pad[2];
float pad[3];
};
RID_Owner<OccluderPolygon> occluder_polygon_owner;
......@@ -277,6 +284,36 @@ class RasterizerCanvasRD : public RasterizerCanvas {
//state that does not vary across rendering all items
struct ItemStateData : public Item::CustomData {
struct LightCache {
uint64_t light_version;
Light *light;
};
LightCache light_cache[DEFAULT_MAX_LIGHTS_PER_ITEM];
uint32_t light_cache_count;
RID light_uniform_set;
RID state_uniform_set;
ItemStateData() {
for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) {
light_cache[i].light_version = 0;
light_cache[i].light = NULL;
}
light_cache_count = 0xFFFFFFFF;
}
~ItemStateData() {
if (light_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(light_uniform_set)) {
RD::get_singleton()->free(light_uniform_set);
}
if (state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state_uniform_set)) {
RD::get_singleton()->free(state_uniform_set);
}
}
};
struct State {
//state buffer
......@@ -289,14 +326,14 @@ class RasterizerCanvasRD : public RasterizerCanvas {
//uint32_t pad[3];
};
LightUniform light_uniforms[MAX_RENDER_LIGHTS];
LightUniform *light_uniforms;
RID lights_uniform_buffer;
RID canvas_state_buffer;
RID shadow_sampler;
//uniform set for all the above
RID canvas_state_uniform_set;
uint32_t max_lights_per_render;
uint32_t max_lights_per_item;
} state;
struct PushConstant {
......@@ -331,7 +368,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
Item *items[MAX_RENDER_ITEMS];
Size2i _bind_texture_binding(TextureBindingID p_binding, RenderingDevice::DrawListID p_draw_list, uint32_t &flags);
void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RenderingDevice::TextureSamples p_samples, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights);
void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights);
void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
......@@ -342,8 +379,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
_FORCE_INLINE_ void _update_specular_shininess(const Color &p_transform, uint32_t *r_ss);
void _update_canvas_state_uniform_set();
public:
TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, VS::CanvasItemTextureFilter p_filter, VS::CanvasItemTextureRepeat p_repeat, RID p_multimesh);
void free_texture_binding(TextureBindingID p_binding);
......
#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) {
RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
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);
RD::PipelineMultisampleState multisample_state_version = multisample_state;
multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id);
RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, rasterization_state, multisample_state_version, 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]++;
versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
versions[version_count].framebuffer_id = p_framebuffer_format_id;
versions[version_count].vertex_id= p_vertex_format_id;
versions[version_count].pipeline = pipeline;
version_count++;
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++) {
//shader may be gone, so this may not be valid
if (RD::get_singleton()->render_pipeline_is_valid(versions[v][i].pipeline)) {
RD::get_singleton()->free(versions[v][i].pipeline);
}
if (versions) {
for (uint32_t i = 0; i < version_count; i++) {
//shader may be gone, so this may not be valid
if (RD::get_singleton()->render_pipeline_is_valid(versions[i].pipeline)) {
RD::get_singleton()->free(versions[i].pipeline);
}
version_count[v] = 0;
memfree(versions[v]);
versions[v] = NULL;
}
version_count = 0;
memfree(versions);
versions = 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) {
void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, 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;
......@@ -49,14 +45,12 @@ void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferForma
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);
setup(p_shader, 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;
}
version_count = 0;
versions = NULL;
}
RenderPipelineVertexFormatCacheRD::~RenderPipelineVertexFormatCacheRD() {
......
......@@ -16,29 +16,29 @@ class RenderPipelineVertexFormatCacheRD {
int dynamic_state_flags;
struct Version {
RD::VertexFormatID format_id;
RD::VertexFormatID vertex_id;
RD::FramebufferFormatID framebuffer_id;
RID pipeline;
};
Version *versions[RD::TEXTURE_SAMPLES_MAX];
uint32_t version_count[RD::TEXTURE_SAMPLES_MAX];
Version *versions;
uint32_t version_count;
RID _generate_version(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples);
RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id);
void _clear();
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::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, 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;
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
for (uint32_t i = 0; i < version_count; i++) {
if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) {
return versions[i].pipeline;
}
}
return _generate_version(p_format_id, p_samples);
return _generate_version(p_vertex_format_id, p_framebuffer_format_id);
}
RenderPipelineVertexFormatCacheRD();
......
......@@ -180,7 +180,9 @@ void ShaderRD::_compile_version(Version *p_version) {
builder.append(vertex_codev.get_data()); // version info (if exists)
builder.append("\n"); //make sure defines begin at newline
builder.append(general_defines.get_data());
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());
}
......@@ -214,6 +216,7 @@ void ShaderRD::_compile_version(Version *p_version) {
builder.append(fragment_codev.get_data()); // version info (if exists)
builder.append("\n"); //make sure defines begin at newline
builder.append(general_defines.get_data());
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());
......@@ -307,9 +310,10 @@ bool ShaderRD::version_free(RID p_version) {
return true;
}
void ShaderRD::initialize(const Vector<String> &p_variant_defines) {
void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) {
ERR_FAIL_COND(variant_defines.size());
ERR_FAIL_COND(p_variant_defines.size() == 0);
general_defines = p_general_defines.utf8();
for (int i = 0; i < p_variant_defines.size(); i++) {
variant_defines.push_back(p_variant_defines[i].utf8());
......
......@@ -44,6 +44,7 @@
class ShaderRD {
//versions
CharString general_defines;
Vector<CharString> variant_defines;
int vertex_code_start;
......@@ -114,7 +115,7 @@ public:
bool version_free(RID p_version);
void initialize(const Vector<String> &p_variant_defines);
void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
virtual ~ShaderRD();
};
......
......@@ -5,4 +5,3 @@ Import('env')
if 'RD_GLSL' in env['BUILDERS']:
env.RD_GLSL('canvas.glsl');
env.RD_GLSL('canvas_occlusion.glsl');
env.RD_GLSL('canvas_occlusion_fix.glsl');
......@@ -426,8 +426,11 @@ FRAGMENT_SHADER_CODE
}
color*=canvas_data.canvas_modulation;
for(uint i=0;i<light_count;i++) {
#ifdef USE_LIGHTING
for(uint i=0;i<MAX_LIGHT_TEXTURES;i++) {
if (i>=light_count) {
break;
}
uint light_base;
if (i<8) {
if (i<4) {
......@@ -445,16 +448,8 @@ FRAGMENT_SHADER_CODE
light_base>>=(i&3)*8;
light_base&=0xFF;
#define LIGHT_FLAGS_BLEND_MASK (3<<16)
#define LIGHT_FLAGS_BLEND_MODE_ADD (0<<16)
#define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16)
#define LIGHT_FLAGS_BLEND_MODE_MIX (2<<16)
#define LIGHT_FLAGS_BLEND_MODE_MASK (3<<16)
vec2 tex_uv = (vec4(vertex,0.0,1.0) * mat4(light_array.data[light_base].matrix[0],light_array.data[light_base].matrix[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
uint texture_idx = light_array.data[light_base].flags&LIGHT_FLAGS_TEXTURE_MASK;
vec4 light_color = texture(sampler2D(light_textures[texture_idx],texture_sampler),tex_uv);
vec4 light_color = texture(sampler2D(light_textures[i],texture_sampler),tex_uv);
vec4 light_base_color = light_array.data[light_base].color;
light_color.rgb*=light_base_color.rgb*light_base_color.a;
......@@ -526,32 +521,32 @@ FRAGMENT_SHADER_CODE
vec4 shadow_uv = vec4(tex_ofs,0.0,distance,1.0);
if (shadow_mode==LIGHT_FLAGS_SHADOW_NEAREST) {
shadow = textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
shadow = textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
} else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF5) {
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0);
shadow = 0.0;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
shadow/=5.0;
} else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF13) {
} else { //PCF13
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0);
shadow = 0.0;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x;
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x;
shadow/=13.0;
}
......@@ -577,6 +572,7 @@ FRAGMENT_SHADER_CODE
} break;
}
}
#endif
frag_color = color;
......
/* clang-format off */
[vertex]
/* clang-format on */
#version 450
layout(location = 0) out highp float u;
void main() {
if (gl_VertexIndex==0) {
u=0.0;
gl_Position=vec4(-1.0,-1.0,0.0,1.0);
} else if (gl_VertexIndex==1) {
u=0.0;
gl_Position=vec4(-1.0,1.0,0.0,1.0);
} else if (gl_VertexIndex==2) {
u=1.0;
gl_Position=vec4(1.0,1.0,0.0,1.0);
} else {
u=1.0;
gl_Position=vec4(1.0,-1.0,0.0,1.0);
}
}
/* clang-format off */
[fragment]
/* clang-format on */
#version 450
#define PI 3.14159265359
layout(set=0, binding=0) uniform sampler2D textures[4];
layout(location = 0) in highp float u;
layout(location = 0) out highp float distance;
layout(push_constant, binding = 0, std430) uniform Constants {
mat4 projection;
float far;
float pad[3];
} constants;
void main() {
//0-1 in the texture we are writing to represents a circle, 0-2PI)
//obtain the quarter circle from the source textures
float angle=fract(u+1.0-0.125);
float depth;
#if 0
if (angle<0.25) {
highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[0],vec2(x,0.0)).x;
} else if (angle<0.50) {
highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[1],vec2(x,0.0)).x;
} else if (angle<0.75) {
highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[2],vec2(x,0.0)).x;
} else {
highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[3],vec2(x,0.0)).x;
}
#else
if (angle<0.25) {
highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
float coord = (proj.x/proj.w)*0.5+0.5;
depth=texture(textures[0],vec2(coord,0.0)).x;
} else if (angle<0.50) {
highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
float coord = (proj.x/proj.w)*0.5+0.5;
depth=texture(textures[1],vec2(coord,0.0)).x;
} else if (angle<0.75) {
highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
float coord = (proj.x/proj.w)*0.5+0.5;
depth=texture(textures[2],vec2(coord,0.0)).x;
} else {
highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
float coord = (proj.x/proj.w)*0.5+0.5;
depth=texture(textures[3],vec2(coord,0.0)).x;
}
#endif
distance=depth;
}
/* SET0: Per draw primitive settings */
/* SET0: Draw Primitive */
#define M_PI 3.14159265359
#define MAX_LIGHT_TEXTURES 1024
#define MAX_RENDER_LIGHTS 256
#define FLAGS_INSTANCING_STRIDE_MASK 0xF
#define FLAGS_INSTANCING_ENABLED (1<<4)
#define FLAGS_INSTANCING_HAS_COLORS (1 << 5)
......@@ -64,30 +61,30 @@ layout(set = 0, binding = 5) uniform textureBuffer instancing_buffer;
//
/* SET2: Is the skeleton */
/* SET2: Canvas Item State */
#ifdef USE_ATTRIBUTES
layout(set = 2, binding = 0) uniform textureBuffer skeleton_buffer;
layout(set = 2, binding = 0, std140) uniform CanvasData {
mat4 canvas_transform;
mat4 screen_transform;
mat4 canvas_normal_transform;
vec4 canvas_modulation;
//uint light_count;
} canvas_data;
layout(set = 2, binding = 1, std140) uniform SkeletonData {
layout(set = 2, binding = 1) uniform textureBuffer skeleton_buffer;
layout(set = 2, binding = 2, std140) uniform SkeletonData {
mat4 skeleton_transform; //in world coordinates
mat4 skeleton_transform_inverse;
} skeleton_data;
#endif
/* SET3: Per Scene settings */
layout(set = 3, binding = 0, std140) uniform CanvasData {
mat4 canvas_transform;
mat4 screen_transform;
mat4 canvas_normal_transform;
vec4 canvas_modulation;
//uint light_count;
} canvas_data;
/* SET3: Lighting */
#ifdef USE_LIGHTING
#define LIGHT_FLAGS_TEXTURE_MASK 0xFFFF
#define LIGHT_FLAGS_BLEND_MASK (3<<16)
#define LIGHT_FLAGS_BLEND_MODE_ADD (0<<16)
#define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16)
......@@ -109,17 +106,19 @@ struct Light {
vec2 position;
uint flags; //index to light texture
float height;
float shadow_softness;
float shadow_pixel_size;
float pad0;
float pad1;
float pad2;
};
layout(set = 3, binding = 1, std140) uniform LightData {
Light data[MAX_RENDER_LIGHTS];
layout(set = 3, binding = 0, std140) uniform LightData {
Light data[MAX_LIGHTS];
} light_array;
layout(set = 3, binding = 2) uniform texture2D light_textures[MAX_LIGHT_TEXTURES];
layout(set = 3, binding = 3) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES];
layout(set = 3, binding = 1) uniform texture2D light_textures[MAX_LIGHT_TEXTURES];
layout(set = 3, binding = 2) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES];
layout(set = 3, binding = 4) uniform sampler shadow_sampler;
layout(set = 3, binding = 3) uniform sampler shadow_sampler;
#endif
......@@ -334,6 +334,7 @@ public:
}
};
struct TextureView {
DataFormat format_override;
TextureSwizzle swizzle_r;
......@@ -352,6 +353,8 @@ 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 RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture,int p_layer,int p_mipmap) = 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 PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
......@@ -373,6 +376,7 @@ public:
// 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 TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) =0;
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID) = 0;
......@@ -865,12 +869,49 @@ public:
virtual void draw_list_end() = 0;
/***************/
/**** FREE! ****/
/***************/
virtual void free(RID p_id) = 0;
/****************/
/**** LIMITS ****/
/****************/
enum Limit {
LIMIT_MAX_BOUND_UNIFORM_SETS,
LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS,
LIMIT_MAX_TEXTURES_PER_UNIFORM_SET,
LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET,
LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET,
LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET,
LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET,
LIMIT_MAX_DRAW_INDEXED_INDEX,
LIMIT_MAX_FRAMEBUFFER_HEIGHT,
LIMIT_MAX_FRAMEBUFFER_WIDTH,
LIMIT_MAX_TEXTURE_ARRAY_LAYERS,
LIMIT_MAX_TEXTURE_SIZE_1D,
LIMIT_MAX_TEXTURE_SIZE_2D,
LIMIT_MAX_TEXTURE_SIZE_3D,
LIMIT_MAX_TEXTURE_SIZE_CUBE,
LIMIT_MAX_TEXTURES_PER_SHADER_STAGE,
LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE,
LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE,
LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE,
LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE,
LIMIT_MAX_PUSH_CONSTANT_SIZE,
LIMIT_MAX_UNIFORM_BUFFER_SIZE,
LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET,
LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES,
LIMIT_MAX_VERTEX_INPUT_BINDINGS,
LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE,
LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT ,
};
virtual int limit_get(Limit p_limit) =0;
//methods below not exposed, used by RenderingDeviceRD
virtual void prepare_screen_for_drawing() =0;
virtual void finalize_frame() = 0;
......
......@@ -65,14 +65,13 @@ void VisualServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas
VSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform);
}
void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, const Color p_modulate, VisualServerCanvas::Item **r_items, int &r_index) {
void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, VisualServerCanvas::Item **r_items, int &r_index) {
int child_item_count = p_canvas_item->child_items.size();
VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw();
for (int i = 0; i < child_item_count; i++) {
if (child_items[i]->visible) {
if (r_items) {
r_items[r_index] = child_items[i];
child_items[i]->ysort_modulate = p_modulate;
child_items[i]->ysort_xform = p_transform;
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]);
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : NULL;
......@@ -81,11 +80,7 @@ void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2
r_index++;
if (child_items[i]->sort_y)
_collect_ysort_children(child_items[i],
p_transform * child_items[i]->xform,
child_items[i]->use_parent_material ? p_material_owner : child_items[i],
p_modulate * child_items[i]->modulate,
r_items, r_index);
_collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index);
}
}
}
......@@ -146,14 +141,14 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (ci->ysort_children_count == -1) {
ci->ysort_children_count = 0;
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), NULL, ci->ysort_children_count);
_collect_ysort_children(ci, Transform2D(), p_material_owner, NULL, ci->ysort_children_count);
}
child_item_count = ci->ysort_children_count;
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
int i = 0;
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i);
_collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
SortArray<Item *, ItemPtrSort> sorter;
sorter.sort(child_items, child_item_count);
......@@ -169,7 +164,7 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
continue;
if (ci->sort_y) {
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
} else {
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
}
......@@ -213,7 +208,7 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
continue;
if (ci->sort_y) {
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
} else {
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
}
......@@ -835,7 +830,7 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != vertex_count * 4);
ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != vertex_count * 4);
const Vector<int> &indices = p_indices;
Vector<int> indices = p_indices;
Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
......@@ -1057,6 +1052,7 @@ void VisualServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) {
ERR_FAIL_COND(!clight);
clight->texture = p_texture;
clight->version++;
VSG::canvas_render->light_set_texture(clight->light_internal, p_texture);
}
void VisualServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) {
......@@ -1134,7 +1130,7 @@ void VisualServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_ena
return;
}
clight->use_shadow = p_enabled;
clight->version++;
VSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
}
......@@ -1150,19 +1146,11 @@ void VisualServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_
return;
clight->shadow_buffer_size = next_power_of_2(p_size);
clight->version++;
VSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
}
void VisualServerCanvas::canvas_light_set_shadow_gradient_length(RID p_light, float p_length) {
ERR_FAIL_COND(p_length < 0);
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->shadow_gradient_length = p_length;
}
void VisualServerCanvas::canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
......
......@@ -245,7 +245,6 @@ public:
void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
void canvas_light_set_shadow_gradient_length(RID p_light, float p_length);
void canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter);
void canvas_light_set_shadow_color(RID p_light, const Color &p_color);
void canvas_light_set_shadow_smooth(RID p_light, float p_smooth);
......
......@@ -658,7 +658,6 @@ public:
BIND2(canvas_light_set_shadow_enabled, RID, bool)
BIND2(canvas_light_set_shadow_buffer_size, RID, int)
BIND2(canvas_light_set_shadow_gradient_length, RID, float)
BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
BIND2(canvas_light_set_shadow_color, RID, const Color &)
BIND2(canvas_light_set_shadow_smooth, RID, float)
......
......@@ -571,7 +571,6 @@ public:
FUNC2(canvas_light_set_shadow_enabled, RID, bool)
FUNC2(canvas_light_set_shadow_buffer_size, RID, int)
FUNC2(canvas_light_set_shadow_gradient_length, RID, float)
FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
FUNC2(canvas_light_set_shadow_color, RID, const Color &)
FUNC2(canvas_light_set_shadow_smooth, RID, float)
......
......@@ -1977,7 +1977,6 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_light_set_mode", "light", "mode"), &VisualServer::canvas_light_set_mode);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_enabled", "light", "enabled"), &VisualServer::canvas_light_set_shadow_enabled);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_buffer_size", "light", "size"), &VisualServer::canvas_light_set_shadow_buffer_size);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_gradient_length", "light", "length"), &VisualServer::canvas_light_set_shadow_gradient_length);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_filter", "light", "filter"), &VisualServer::canvas_light_set_shadow_filter);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_color", "light", "color"), &VisualServer::canvas_light_set_shadow_color);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_smooth", "light", "smooth"), &VisualServer::canvas_light_set_shadow_smooth);
......
......@@ -965,7 +965,6 @@ public:
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) = 0;
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size) = 0;
virtual void canvas_light_set_shadow_gradient_length(RID p_light, float p_length) = 0;
virtual void canvas_light_set_shadow_filter(RID p_light, CanvasLightShadowFilter p_filter) = 0;
virtual void canvas_light_set_shadow_color(RID p_light, const Color &p_color) = 0;
virtual void canvas_light_set_shadow_smooth(RID p_light, float p_smooth) = 0;
......
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