Add color pass flags to Forward Clustered renderer
This commit removes a lot of enum values related to the color render pass in favor of a new flag-bases approach. This means instead of hard-coding all the possible option combinations into enums, we can write our logic by checking a bit-mask. The changes in rendering_device_vulkan.cpp add support for unused attachments. That means RenderingDeviceVulkan::framebuffer_create() can take null RIDs in the attachments vector, which will result in VK_ATTACHMENT_UNUSED entries in the render pass. This is used in this same PR to establish fixed locations for the color pass attachments (only color and separate specular so far, but TAA will add motion vectors as well). This way the attachment locations in the shader can stay the same regardless of which attachments are actually used. Right now all the combinations of flags are generated, but we will need to add a way to limit the amount of combinations in the future.
This commit is contained in:
parent
4263f02f28
commit
e69d762dd0
7 changed files with 337 additions and 248 deletions
|
@ -3364,8 +3364,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
attachment_last_pass.resize(p_attachments.size());
|
||||
|
||||
Vector<VkAttachmentDescription> attachments;
|
||||
Vector<int> attachment_remap;
|
||||
|
||||
for (int i = 0; i < p_attachments.size(); i++) {
|
||||
if (p_attachments[i].usage_flags == AttachmentFormat::UNUSED_ATTACHMENT) {
|
||||
attachment_remap.push_back(VK_ATTACHMENT_UNUSED);
|
||||
continue;
|
||||
}
|
||||
|
||||
ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE);
|
||||
ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE);
|
||||
ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)),
|
||||
|
@ -3567,7 +3573,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
}
|
||||
|
||||
attachment_last_pass[i] = -1;
|
||||
|
||||
attachment_remap.push_back(attachments.size());
|
||||
attachments.push_back(description);
|
||||
}
|
||||
|
||||
|
@ -3612,7 +3618,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
} else {
|
||||
ERR_FAIL_COND_V_MSG(texture_samples != p_attachments[attachment].samples, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), if an attachment is marked as multisample, all of them should be multisample and use the same number of samples.");
|
||||
}
|
||||
reference.attachment = attachment;
|
||||
reference.attachment = attachment_remap[attachment];
|
||||
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachment_last_pass[attachment] = i;
|
||||
}
|
||||
|
@ -3631,7 +3637,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), input attachment (" + itos(j) + ").");
|
||||
ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it isn't marked as an input texture.");
|
||||
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
|
||||
reference.attachment = attachment;
|
||||
reference.attachment = attachment_remap[attachment];
|
||||
reference.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
attachment_last_pass[attachment] = i;
|
||||
}
|
||||
|
@ -3657,7 +3663,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
|
||||
bool multisample = p_attachments[attachment].samples > TEXTURE_SAMPLES_1;
|
||||
ERR_FAIL_COND_V_MSG(multisample, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), resolve attachments can't be multisample.");
|
||||
reference.attachment = attachment;
|
||||
reference.attachment = attachment_remap[attachment];
|
||||
reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
attachment_last_pass[attachment] = i;
|
||||
}
|
||||
|
@ -3671,7 +3677,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), depth attachment.");
|
||||
ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as depth, but it's not a depth attachment.");
|
||||
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
|
||||
depth_stencil_reference.attachment = attachment;
|
||||
depth_stencil_reference.attachment = attachment_remap[attachment];
|
||||
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
attachment_last_pass[attachment] = i;
|
||||
|
||||
|
@ -3958,14 +3964,13 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
|
|||
|
||||
for (int i = 0; i < p_texture_attachments.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
|
||||
ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture.");
|
||||
|
||||
ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
|
||||
ERR_FAIL_COND_V_MSG(texture && texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
|
||||
|
||||
if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
if (texture && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
pass.depth_attachment = i;
|
||||
} else {
|
||||
pass.color_attachments.push_back(i);
|
||||
pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3979,29 +3984,35 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
|
|||
_THREAD_SAFE_METHOD_
|
||||
|
||||
Vector<AttachmentFormat> attachments;
|
||||
attachments.resize(p_texture_attachments.size());
|
||||
Size2i size;
|
||||
|
||||
bool size_set = false;
|
||||
for (int i = 0; i < p_texture_attachments.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
|
||||
ERR_FAIL_COND_V_MSG(!texture, RID(), "Texture index supplied for framebuffer (" + itos(i) + ") is not a valid texture.");
|
||||
|
||||
ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
|
||||
|
||||
if (i == 0) {
|
||||
size.width = texture->width;
|
||||
size.height = texture->height;
|
||||
} else {
|
||||
ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
|
||||
"All textures in a framebuffer should be the same size.");
|
||||
}
|
||||
|
||||
AttachmentFormat af;
|
||||
af.format = texture->format;
|
||||
af.samples = texture->samples;
|
||||
af.usage_flags = texture->usage_flags;
|
||||
attachments.push_back(af);
|
||||
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
|
||||
if (!texture) {
|
||||
af.usage_flags = AttachmentFormat::UNUSED_ATTACHMENT;
|
||||
} else {
|
||||
ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
|
||||
|
||||
if (!size_set) {
|
||||
size.width = texture->width;
|
||||
size.height = texture->height;
|
||||
size_set = true;
|
||||
} else {
|
||||
ERR_FAIL_COND_V_MSG((uint32_t)size.width != texture->width || (uint32_t)size.height != texture->height, RID(),
|
||||
"All textures in a framebuffer should be the same size.");
|
||||
}
|
||||
|
||||
af.format = texture->format;
|
||||
af.samples = texture->samples;
|
||||
af.usage_flags = texture->usage_flags;
|
||||
}
|
||||
attachments.write[i] = af;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!size_set, RID(), "All attachments unused.");
|
||||
|
||||
FramebufferFormatID format_id = framebuffer_format_create_multipass(attachments, p_passes, p_view_count);
|
||||
if (format_id == INVALID_ID) {
|
||||
return RID();
|
||||
|
@ -4019,7 +4030,9 @@ RID RenderingDeviceVulkan::framebuffer_create_multipass(const Vector<RID> &p_tex
|
|||
RID id = framebuffer_owner.make_rid(framebuffer);
|
||||
|
||||
for (int i = 0; i < p_texture_attachments.size(); i++) {
|
||||
_add_dependency(id, p_texture_attachments[i]);
|
||||
if (p_texture_attachments[i].is_valid()) {
|
||||
_add_dependency(id, p_texture_attachments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
|
@ -6417,49 +6430,55 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
|
|||
Vector<VkPipelineColorBlendAttachmentState> attachment_states;
|
||||
{
|
||||
const FramebufferPass &pass = fb_format.E->key().passes[p_for_render_pass];
|
||||
|
||||
attachment_states.resize(pass.color_attachments.size());
|
||||
ERR_FAIL_COND_V(p_blend_state.attachments.size() < pass.color_attachments.size(), RID());
|
||||
for (int i = 0; i < pass.color_attachments.size(); i++) {
|
||||
if (pass.color_attachments[i] != FramebufferPass::ATTACHMENT_UNUSED) {
|
||||
int idx = attachment_states.size();
|
||||
VkPipelineColorBlendAttachmentState state;
|
||||
if (pass.color_attachments[i] == FramebufferPass::ATTACHMENT_UNUSED) {
|
||||
state.blendEnable = false;
|
||||
|
||||
ERR_FAIL_INDEX_V(idx, p_blend_state.attachments.size(), RID());
|
||||
VkPipelineColorBlendAttachmentState state;
|
||||
state.blendEnable = p_blend_state.attachments[idx].enable_blend;
|
||||
state.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
state.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
state.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_color_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[idx].src_color_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_color_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_color_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].color_blend_op, BLEND_OP_MAX, RID());
|
||||
state.colorBlendOp = blend_operations[p_blend_state.attachments[idx].color_blend_op];
|
||||
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].src_alpha_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[idx].dst_alpha_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[idx].alpha_blend_op, BLEND_OP_MAX, RID());
|
||||
state.alphaBlendOp = blend_operations[p_blend_state.attachments[idx].alpha_blend_op];
|
||||
state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
state.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
|
||||
state.colorWriteMask = 0;
|
||||
if (p_blend_state.attachments[idx].write_r) {
|
||||
} else {
|
||||
state.blendEnable = p_blend_state.attachments[i].enable_blend;
|
||||
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_color_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.srcColorBlendFactor = blend_factors[p_blend_state.attachments[i].src_color_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_color_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.dstColorBlendFactor = blend_factors[p_blend_state.attachments[i].dst_color_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[i].color_blend_op, BLEND_OP_MAX, RID());
|
||||
state.colorBlendOp = blend_operations[p_blend_state.attachments[i].color_blend_op];
|
||||
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[i].src_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.srcAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].src_alpha_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[i].dst_alpha_blend_factor, BLEND_FACTOR_MAX, RID());
|
||||
state.dstAlphaBlendFactor = blend_factors[p_blend_state.attachments[i].dst_alpha_blend_factor];
|
||||
ERR_FAIL_INDEX_V(p_blend_state.attachments[i].alpha_blend_op, BLEND_OP_MAX, RID());
|
||||
state.alphaBlendOp = blend_operations[p_blend_state.attachments[i].alpha_blend_op];
|
||||
|
||||
state.colorWriteMask = 0;
|
||||
if (p_blend_state.attachments[i].write_r) {
|
||||
state.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
|
||||
}
|
||||
if (p_blend_state.attachments[idx].write_g) {
|
||||
if (p_blend_state.attachments[i].write_g) {
|
||||
state.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
|
||||
}
|
||||
if (p_blend_state.attachments[idx].write_b) {
|
||||
if (p_blend_state.attachments[i].write_b) {
|
||||
state.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
|
||||
}
|
||||
if (p_blend_state.attachments[idx].write_a) {
|
||||
if (p_blend_state.attachments[i].write_a) {
|
||||
state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
|
||||
}
|
||||
|
||||
attachment_states.push_back(state);
|
||||
idx++;
|
||||
}
|
||||
attachment_states.write[i] = state;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(attachment_states.size() != p_blend_state.attachments.size(), RID());
|
||||
}
|
||||
|
||||
color_blend_state_create_info.attachmentCount = attachment_states.size();
|
||||
|
@ -6863,10 +6882,11 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu
|
|||
Vector<VkImageView> attachments;
|
||||
for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
|
||||
ERR_FAIL_COND_V(!texture, ERR_BUG);
|
||||
attachments.push_back(texture->view);
|
||||
ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
|
||||
ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
|
||||
if (texture) {
|
||||
attachments.push_back(texture->view);
|
||||
ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
|
||||
ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
|
||||
}
|
||||
}
|
||||
framebuffer_create_info.attachmentCount = attachments.size();
|
||||
framebuffer_create_info.pAttachments = attachments.ptr();
|
||||
|
@ -6910,13 +6930,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
|
|||
|
||||
Vector<VkClearValue> clear_values;
|
||||
clear_values.resize(framebuffer->texture_ids.size());
|
||||
|
||||
int clear_values_count = 0;
|
||||
{
|
||||
int color_index = 0;
|
||||
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
|
||||
VkClearValue clear_value;
|
||||
|
||||
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
|
||||
if (!texture) {
|
||||
color_index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (color_index < p_clear_colors.size() && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
ERR_FAIL_INDEX_V(color_index, p_clear_colors.size(), ERR_BUG); //a bug
|
||||
Color clear_color = p_clear_colors[color_index];
|
||||
|
@ -6934,15 +6959,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
|
|||
clear_value.color.float32[2] = 0;
|
||||
clear_value.color.float32[3] = 0;
|
||||
}
|
||||
clear_values.write[i] = clear_value;
|
||||
clear_values.write[clear_values_count++] = clear_value;
|
||||
}
|
||||
}
|
||||
|
||||
render_pass_begin.clearValueCount = clear_values.size();
|
||||
render_pass_begin.clearValueCount = clear_values_count;
|
||||
render_pass_begin.pClearValues = clear_values.ptr();
|
||||
|
||||
for (int i = 0; i < p_storage_textures.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(p_storage_textures[i]);
|
||||
if (!texture) {
|
||||
continue;
|
||||
}
|
||||
ERR_CONTINUE_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), "Supplied storage texture " + itos(i) + " for draw list is not set to be used for storage.");
|
||||
|
||||
if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
|
||||
|
@ -6981,6 +7009,9 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
|
|||
|
||||
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
|
||||
if (!texture) {
|
||||
continue;
|
||||
}
|
||||
texture->bound = true;
|
||||
draw_list_bound_textures.push_back(framebuffer->texture_ids[i]);
|
||||
}
|
||||
|
@ -6989,15 +7020,21 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
|
|||
}
|
||||
|
||||
void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) {
|
||||
ERR_FAIL_COND_MSG(p_clear_color && p_clear_colors.size() != framebuffer->texture_ids.size(), "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(framebuffer->texture_ids.size()) + ").");
|
||||
Vector<VkClearAttachment> clear_attachments;
|
||||
int color_index = 0;
|
||||
int texture_index = 0;
|
||||
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
|
||||
VkClearAttachment clear_at = {};
|
||||
|
||||
if (!texture) {
|
||||
texture_index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
VkClearAttachment clear_at = {};
|
||||
if (p_clear_color && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
ERR_FAIL_INDEX(color_index, p_clear_colors.size()); //a bug
|
||||
Color clear_color = p_clear_colors[color_index];
|
||||
Color clear_color = p_clear_colors[texture_index++];
|
||||
clear_at.clearValue.color.float32[0] = clear_color.r;
|
||||
clear_at.clearValue.color.float32[1] = clear_color.g;
|
||||
clear_at.clearValue.color.float32[2] = clear_color.b;
|
||||
|
@ -7073,18 +7110,14 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
|
|||
}
|
||||
|
||||
if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values
|
||||
|
||||
int color_count = 0;
|
||||
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
|
||||
|
||||
if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
||||
color_count++;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID,
|
||||
"Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ").");
|
||||
ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ").");
|
||||
}
|
||||
|
||||
VkFramebuffer vkframebuffer;
|
||||
|
@ -7176,7 +7209,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
|
|||
for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
|
||||
Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
|
||||
|
||||
if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
if (!texture || !(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
||||
color_count++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,14 +57,6 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
|
|||
specular = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
|
||||
if (msaa == RS::VIEWPORT_MSAA_DISABLED) {
|
||||
{
|
||||
Vector<RID> fb;
|
||||
fb.push_back(color);
|
||||
fb.push_back(specular);
|
||||
fb.push_back(depth);
|
||||
|
||||
color_specular_fb = RD::get_singleton()->framebuffer_create(fb);
|
||||
}
|
||||
{
|
||||
Vector<RID> fb;
|
||||
fb.push_back(specular);
|
||||
|
@ -77,14 +69,6 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
|
|||
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
|
||||
specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
|
||||
{
|
||||
Vector<RID> fb;
|
||||
fb.push_back(color_msaa);
|
||||
fb.push_back(specular_msaa);
|
||||
fb.push_back(depth_msaa);
|
||||
|
||||
color_specular_fb = RD::get_singleton()->framebuffer_create(fb);
|
||||
}
|
||||
{
|
||||
Vector<RID> fb;
|
||||
fb.push_back(specular_msaa);
|
||||
|
@ -165,11 +149,10 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
|
|||
|
||||
color = RID();
|
||||
depth = RID();
|
||||
color_specular_fb = RID();
|
||||
specular_only_fb = RID();
|
||||
color_fb = RID();
|
||||
depth_fb = RID();
|
||||
|
||||
color_framebuffers.clear(); // Color pass framebuffers are freed automatically by their dependency relations
|
||||
|
||||
if (normal_roughness_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(normal_roughness_buffer);
|
||||
if (normal_roughness_buffer_msaa.is_valid()) {
|
||||
|
@ -203,7 +186,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
|
|||
fb.push_back(p_color_buffer);
|
||||
fb.push_back(depth);
|
||||
|
||||
color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
|
||||
color_only_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
|
||||
}
|
||||
{
|
||||
Vector<RID> fb;
|
||||
|
@ -246,7 +229,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
|
|||
fb.push_back(color_msaa);
|
||||
fb.push_back(depth_msaa);
|
||||
|
||||
color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
|
||||
color_only_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
|
||||
}
|
||||
{
|
||||
Vector<RID> fb;
|
||||
|
@ -257,6 +240,31 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
|
|||
}
|
||||
}
|
||||
|
||||
RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_pass_fb(uint32_t p_color_pass_flags) {
|
||||
if (color_framebuffers.has(p_color_pass_flags)) {
|
||||
return color_framebuffers[p_color_pass_flags];
|
||||
}
|
||||
|
||||
bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
|
||||
|
||||
Vector<RID> fb;
|
||||
fb.push_back(use_msaa ? color_msaa : color);
|
||||
|
||||
if (p_color_pass_flags & COLOR_PASS_FLAG_SEPARATE_SPECULAR) {
|
||||
ensure_specular();
|
||||
fb.push_back(use_msaa ? specular_msaa : specular);
|
||||
} else {
|
||||
fb.push_back(RID());
|
||||
}
|
||||
|
||||
fb.push_back(use_msaa ? depth_msaa : depth);
|
||||
|
||||
int v_count = (p_color_pass_flags & COLOR_PASS_FLAG_MULTIVIEW) ? view_count : 1;
|
||||
RID framebuffer = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, v_count);
|
||||
color_framebuffers[p_color_pass_flags] = framebuffer;
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb) {
|
||||
if (rb->normal_roughness_buffer.is_valid()) {
|
||||
return;
|
||||
|
@ -306,7 +314,7 @@ bool RenderForwardClustered::free(RID p_rid) {
|
|||
|
||||
/// RENDERING ///
|
||||
|
||||
template <RenderForwardClustered::PassMode p_pass_mode>
|
||||
template <RenderForwardClustered::PassMode p_pass_mode, uint32_t p_color_pass_flags>
|
||||
void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
|
||||
RD::DrawListID draw_list = p_draw_list;
|
||||
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
|
||||
|
@ -340,7 +348,7 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
|
|||
const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i];
|
||||
const RenderElementInfo &element_info = p_params->element_info[i];
|
||||
|
||||
if ((p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_SPECULAR) && !(surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
|
||||
if ((p_pass_mode == PASS_MODE_COLOR && !(p_color_pass_flags & COLOR_PASS_FLAG_TRANSPARENT)) && !(surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
|
||||
continue; // Objects with "Depth-prepass" transparency are included in both render lists, but should only be rendered in the transparent pass
|
||||
}
|
||||
|
||||
|
@ -403,10 +411,10 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
|
|||
RID xforms_uniform_set = surf->owner->transforms_uniform_set;
|
||||
|
||||
SceneShaderForwardClustered::PipelineVersion pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized.
|
||||
|
||||
uint32_t pipeline_color_pass_flags = 0;
|
||||
uint32_t pipeline_specialization = 0;
|
||||
|
||||
if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT || p_pass_mode == PASS_MODE_COLOR_SPECULAR) {
|
||||
if (p_pass_mode == PASS_MODE_COLOR) {
|
||||
if (element_info.uses_softshadow) {
|
||||
pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_SOFT_SHADOWS;
|
||||
}
|
||||
|
@ -422,28 +430,26 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
|
|||
switch (p_pass_mode) {
|
||||
case PASS_MODE_COLOR: {
|
||||
if (element_info.uses_lightmap) {
|
||||
pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS;
|
||||
} else {
|
||||
pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS;
|
||||
}
|
||||
} break;
|
||||
case PASS_MODE_COLOR_TRANSPARENT: {
|
||||
if (element_info.uses_lightmap) {
|
||||
pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS;
|
||||
pipeline_color_pass_flags |= SceneShaderForwardClustered::PIPELINE_COLOR_PASS_FLAG_LIGHTMAP;
|
||||
} else {
|
||||
if (element_info.uses_forward_gi) {
|
||||
pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_FORWARD_GI;
|
||||
}
|
||||
pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS;
|
||||
}
|
||||
} break;
|
||||
case PASS_MODE_COLOR_SPECULAR: {
|
||||
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for specular pass");
|
||||
if (element_info.uses_lightmap) {
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR;
|
||||
} else {
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS_WITH_SEPARATE_SPECULAR;
|
||||
|
||||
if constexpr ((p_color_pass_flags & COLOR_PASS_FLAG_SEPARATE_SPECULAR) != 0) {
|
||||
pipeline_color_pass_flags |= SceneShaderForwardClustered::PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
||||
}
|
||||
|
||||
if constexpr ((p_color_pass_flags & COLOR_PASS_FLAG_TRANSPARENT) != 0) {
|
||||
pipeline_color_pass_flags |= SceneShaderForwardClustered::PIPELINE_COLOR_PASS_FLAG_TRANSPARENT;
|
||||
}
|
||||
|
||||
if constexpr ((p_color_pass_flags & COLOR_PASS_FLAG_MULTIVIEW) != 0) {
|
||||
pipeline_color_pass_flags |= SceneShaderForwardClustered::PIPELINE_COLOR_PASS_FLAG_MULTIVIEW;
|
||||
}
|
||||
|
||||
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_COLOR_PASS;
|
||||
} break;
|
||||
case PASS_MODE_SHADOW:
|
||||
case PASS_MODE_DEPTH: {
|
||||
|
@ -473,7 +479,11 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
|
|||
|
||||
PipelineCacheRD *pipeline = nullptr;
|
||||
|
||||
pipeline = &shader->pipelines[cull_variant][primitive][pipeline_version];
|
||||
if constexpr (p_pass_mode == PASS_MODE_COLOR) {
|
||||
pipeline = &shader->color_pipelines[cull_variant][primitive][pipeline_color_pass_flags];
|
||||
} else {
|
||||
pipeline = &shader->pipelines[cull_variant][primitive][pipeline_version];
|
||||
}
|
||||
|
||||
RD::VertexFormatID vertex_format = -1;
|
||||
RID vertex_array_rd;
|
||||
|
@ -544,14 +554,23 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis
|
|||
//use template for faster performance (pass mode comparisons are inlined)
|
||||
|
||||
switch (p_params->pass_mode) {
|
||||
#define VALID_FLAG_COMBINATION(f) \
|
||||
case f: { \
|
||||
_render_list_template<PASS_MODE_COLOR, f>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element); \
|
||||
} break;
|
||||
|
||||
case PASS_MODE_COLOR: {
|
||||
_render_list_template<PASS_MODE_COLOR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
|
||||
} break;
|
||||
case PASS_MODE_COLOR_SPECULAR: {
|
||||
_render_list_template<PASS_MODE_COLOR_SPECULAR>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
|
||||
} break;
|
||||
case PASS_MODE_COLOR_TRANSPARENT: {
|
||||
_render_list_template<PASS_MODE_COLOR_TRANSPARENT>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
|
||||
switch (p_params->color_pass_flags) {
|
||||
VALID_FLAG_COMBINATION(0);
|
||||
VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT);
|
||||
VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_SEPARATE_SPECULAR);
|
||||
VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MULTIVIEW);
|
||||
VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT | COLOR_PASS_FLAG_MULTIVIEW);
|
||||
default: {
|
||||
ERR_FAIL_MSG("Invalid color pass flag combination " + itos(p_params->color_pass_flags));
|
||||
}
|
||||
}
|
||||
|
||||
} break;
|
||||
case PASS_MODE_SHADOW: {
|
||||
_render_list_template<PASS_MODE_SHADOW>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
|
||||
|
@ -1238,12 +1257,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
scene_state.ubo.opaque_prepass_threshold = 0.99f;
|
||||
|
||||
Size2i screen_size;
|
||||
RID opaque_framebuffer;
|
||||
RID opaque_specular_framebuffer;
|
||||
RID color_framebuffer;
|
||||
RID color_only_framebuffer;
|
||||
RID depth_framebuffer;
|
||||
RID alpha_framebuffer;
|
||||
|
||||
PassMode depth_pass_mode = PASS_MODE_DEPTH;
|
||||
uint32_t color_pass_flags = 0;
|
||||
Vector<Color> depth_pass_clear;
|
||||
bool using_separate_specular = false;
|
||||
bool using_ssr = false;
|
||||
|
@ -1256,15 +1275,14 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
screen_size.x = render_buffer->width;
|
||||
screen_size.y = render_buffer->height;
|
||||
|
||||
opaque_framebuffer = render_buffer->color_fb;
|
||||
|
||||
if (p_render_data->voxel_gi_instances->size() > 0) {
|
||||
using_voxelgi = true;
|
||||
}
|
||||
|
||||
if (!p_render_data->environment.is_valid() && using_voxelgi) {
|
||||
if (p_render_data->view_count > 1) {
|
||||
depth_pass_mode = PASS_MODE_DEPTH;
|
||||
} else if (!p_render_data->environment.is_valid() && using_voxelgi) {
|
||||
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
|
||||
|
||||
} else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) {
|
||||
if (environment_is_sdfgi_enabled(p_render_data->environment)) {
|
||||
depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also voxelgi
|
||||
|
@ -1272,14 +1290,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
} else {
|
||||
depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
|
||||
}
|
||||
|
||||
if (environment_is_ssr_enabled(p_render_data->environment)) {
|
||||
render_buffer->ensure_specular();
|
||||
using_separate_specular = true;
|
||||
using_ssr = true;
|
||||
opaque_specular_framebuffer = render_buffer->color_specular_fb;
|
||||
color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
||||
}
|
||||
|
||||
} else if (p_render_data->environment.is_valid() && (environment_is_ssao_enabled(p_render_data->environment) || using_ssil || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) {
|
||||
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
|
||||
}
|
||||
|
@ -1304,15 +1319,20 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
};
|
||||
}
|
||||
|
||||
alpha_framebuffer = opaque_framebuffer;
|
||||
if (p_render_data->view_count > 1) {
|
||||
color_pass_flags |= COLOR_PASS_FLAG_MULTIVIEW;
|
||||
}
|
||||
|
||||
color_framebuffer = render_buffer->get_color_pass_fb(color_pass_flags);
|
||||
color_only_framebuffer = render_buffer->color_only_fb;
|
||||
} else if (p_render_data->reflection_probe.is_valid()) {
|
||||
uint32_t resolution = reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
|
||||
screen_size.x = resolution;
|
||||
screen_size.y = resolution;
|
||||
|
||||
opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
|
||||
color_framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
|
||||
color_only_framebuffer = color_framebuffer;
|
||||
depth_framebuffer = reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
|
||||
alpha_framebuffer = opaque_framebuffer;
|
||||
|
||||
if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
||||
p_render_data->environment = RID(); //no environment on interiors
|
||||
|
@ -1342,11 +1362,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
|
||||
bool using_sss = render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
|
||||
|
||||
if (using_sss) {
|
||||
if (using_sss && !using_separate_specular) {
|
||||
using_separate_specular = true;
|
||||
render_buffer->ensure_specular();
|
||||
using_separate_specular = true;
|
||||
opaque_specular_framebuffer = render_buffer->color_specular_fb;
|
||||
color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
||||
color_framebuffer = render_buffer->get_color_pass_fb(color_pass_flags);
|
||||
}
|
||||
RID radiance_texture;
|
||||
bool draw_sky = false;
|
||||
|
@ -1449,7 +1468,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID());
|
||||
|
||||
bool finish_depth = using_ssao || using_sdfgi || using_voxelgi;
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
|
||||
_render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
|
||||
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
|
@ -1495,20 +1514,21 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes);
|
||||
bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes);
|
||||
|
||||
//regular forward for now
|
||||
Vector<Color> c;
|
||||
if (using_separate_specular) {
|
||||
{
|
||||
Color cc = clear_color.to_linear();
|
||||
cc.a = 0; //subsurf scatter must be 0
|
||||
if (using_separate_specular) {
|
||||
cc.a = 0; //subsurf scatter must be 0
|
||||
}
|
||||
c.push_back(cc);
|
||||
c.push_back(Color(0, 0, 0, 0));
|
||||
} else {
|
||||
c.push_back(clear_color.to_linear());
|
||||
|
||||
if (render_buffer) {
|
||||
c.push_back(Color(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
|
||||
_render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, color_pass_flags, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
|
||||
_render_list_with_threads(&render_list_params, color_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
|
||||
if (will_continue_color && using_separate_specular) {
|
||||
// close the specular framebuffer, as it's no longer used
|
||||
RD::get_singleton()->draw_list_begin(render_buffer->specular_only_fb, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
|
||||
|
@ -1526,10 +1546,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
CameraMatrix dc;
|
||||
dc.set_depth_correction(true);
|
||||
CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse());
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
RD::get_singleton()->draw_command_begin_label("Debug VoxelGIs");
|
||||
for (int i = 0; i < (int)p_render_data->voxel_gi_instances->size(); i++) {
|
||||
gi.debug_voxel_gi((*p_render_data->voxel_gi_instances)[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION, 1.0);
|
||||
gi.debug_voxel_gi((*p_render_data->voxel_gi_instances)[i], draw_list, color_only_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION, 1.0);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
RD::get_singleton()->draw_list_end();
|
||||
|
@ -1543,9 +1563,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
CameraMatrix dc;
|
||||
dc.set_depth_correction(true);
|
||||
CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse());
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
|
||||
RD::get_singleton()->draw_command_begin_label("Debug SDFGI");
|
||||
_debug_sdfgi_probes(p_render_data->render_buffers, draw_list, opaque_framebuffer, cm);
|
||||
_debug_sdfgi_probes(p_render_data->render_buffers, draw_list, color_only_framebuffer, cm);
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
@ -1559,9 +1579,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
CameraMatrix correction;
|
||||
correction.set_depth_correction(true);
|
||||
CameraMatrix projection = correction * p_render_data->cam_projection;
|
||||
sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time);
|
||||
sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time);
|
||||
} else {
|
||||
sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time);
|
||||
sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
}
|
||||
|
@ -1588,12 +1608,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
if (using_ssr) {
|
||||
RENDER_TIMESTAMP("Screen-Space Reflections");
|
||||
RD::get_singleton()->draw_command_begin_label("Process Screen-Space Reflections");
|
||||
_process_ssr(p_render_data->render_buffers, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
|
||||
_process_ssr(p_render_data->render_buffers, color_only_framebuffer, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
} else {
|
||||
//just mix specular back
|
||||
RENDER_TIMESTAMP("Merge Specular");
|
||||
storage->get_effects()->merge_specular(render_buffer->color_fb, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID());
|
||||
storage->get_effects()->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1616,7 +1636,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
|
|||
_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
|
||||
|
||||
{
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
|
||||
uint32_t transparent_color_pass_flags = (color_pass_flags | COLOR_PASS_FLAG_TRANSPARENT) & ~COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
||||
RID alpha_framebuffer = render_buffer ? render_buffer->get_color_pass_fb(transparent_color_pass_flags) : color_only_framebuffer;
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, transparent_color_pass_flags, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
|
||||
_render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
|
||||
}
|
||||
|
||||
|
@ -1738,7 +1760,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
|
|||
|
||||
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
|
||||
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
|
||||
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
|
||||
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, 0, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
|
||||
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
|
||||
}
|
||||
|
||||
|
@ -1781,7 +1803,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
|
|||
|
||||
{
|
||||
//regular forward for now
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, true, false, rp_uniform_set);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, 0, true, false, rp_uniform_set);
|
||||
_render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
|
@ -1818,7 +1840,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
|
|||
RENDER_TIMESTAMP("Render 3D Material");
|
||||
|
||||
{
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, 0, true, false, rp_uniform_set);
|
||||
//regular forward for now
|
||||
Vector<Color> clear = {
|
||||
Color(0, 0, 0, 0),
|
||||
|
@ -1864,7 +1886,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p
|
|||
RENDER_TIMESTAMP("Render 3D Material");
|
||||
|
||||
{
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, true);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, 0, true, false, rp_uniform_set, true);
|
||||
//regular forward for now
|
||||
Vector<Color> clear = {
|
||||
Color(0, 0, 0, 0),
|
||||
|
@ -1984,7 +2006,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i
|
|||
E = sdfgi_framebuffer_size_cache.insert(fb_size, fb);
|
||||
}
|
||||
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, false);
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, 0, true, false, rp_uniform_set, false);
|
||||
_render_list_with_threads(&render_list_params, E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,10 +103,10 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
RID depth_fb;
|
||||
RID depth_normal_roughness_fb;
|
||||
RID depth_normal_roughness_voxelgi_fb;
|
||||
RID color_fb;
|
||||
RID color_specular_fb;
|
||||
RID color_only_fb;
|
||||
RID specular_only_fb;
|
||||
int width, height;
|
||||
Map<uint32_t, RID> color_framebuffers;
|
||||
uint32_t view_count;
|
||||
|
||||
RID render_sdfgi_uniform_set;
|
||||
|
@ -114,6 +114,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
void ensure_voxelgi();
|
||||
void clear();
|
||||
virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count);
|
||||
RID get_color_pass_fb(uint32_t p_color_pass_flags);
|
||||
|
||||
~RenderBufferDataForwardClustered();
|
||||
};
|
||||
|
@ -135,8 +136,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
|
||||
enum PassMode {
|
||||
PASS_MODE_COLOR,
|
||||
PASS_MODE_COLOR_SPECULAR,
|
||||
PASS_MODE_COLOR_TRANSPARENT,
|
||||
PASS_MODE_SHADOW,
|
||||
PASS_MODE_SHADOW_DP,
|
||||
PASS_MODE_DEPTH,
|
||||
|
@ -146,6 +145,12 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
PASS_MODE_SDF,
|
||||
};
|
||||
|
||||
enum ColorPassFlags {
|
||||
COLOR_PASS_FLAG_TRANSPARENT = 1 << 0,
|
||||
COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 1,
|
||||
COLOR_PASS_FLAG_MULTIVIEW = 1 << 2
|
||||
};
|
||||
|
||||
struct GeometryInstanceSurfaceDataCache;
|
||||
struct RenderElementInfo;
|
||||
|
||||
|
@ -155,6 +160,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
int element_count = 0;
|
||||
bool reverse_cull = false;
|
||||
PassMode pass_mode = PASS_MODE_COLOR;
|
||||
uint32_t color_pass_flags = 0;
|
||||
bool no_gi = false;
|
||||
uint32_t view_count = 1;
|
||||
RID render_pass_uniform_set;
|
||||
|
@ -168,12 +174,13 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
uint32_t barrier = RD::BARRIER_MASK_ALL;
|
||||
bool use_directional_soft_shadow = false;
|
||||
|
||||
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
|
||||
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
|
||||
elements = p_elements;
|
||||
element_info = p_element_info;
|
||||
element_count = p_element_count;
|
||||
reverse_cull = p_reverse_cull;
|
||||
pass_mode = p_pass_mode;
|
||||
color_pass_flags = p_color_pass_flags;
|
||||
no_gi = p_no_gi;
|
||||
view_count = p_view_count;
|
||||
render_pass_uniform_set = p_render_pass_uniform_set;
|
||||
|
@ -374,7 +381,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
|||
uint32_t lod_index : 8;
|
||||
};
|
||||
|
||||
template <PassMode p_pass_mode>
|
||||
template <PassMode p_pass_mode, uint32_t p_color_pass_flags = 0>
|
||||
_FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
|
||||
|
||||
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
|
||||
|
|
|
@ -234,10 +234,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
}
|
||||
}
|
||||
|
||||
RD::PipelineColorBlendState blend_state_blend;
|
||||
blend_state_blend.attachments.push_back(blend_attachment);
|
||||
RD::PipelineColorBlendState blend_state_opaque = RD::PipelineColorBlendState::create_disabled(1);
|
||||
RD::PipelineColorBlendState blend_state_opaque_specular = RD::PipelineColorBlendState::create_disabled(2);
|
||||
// Color pass -> attachment 0: Color/Diffuse, attachment 1: Separate Specular
|
||||
RD::PipelineColorBlendState blend_state_color_blend;
|
||||
blend_state_color_blend.attachments = { blend_attachment, RD::PipelineColorBlendState::Attachment() };
|
||||
RD::PipelineColorBlendState blend_state_color_opaque = RD::PipelineColorBlendState::create_disabled(2);
|
||||
RD::PipelineColorBlendState blend_state_depth_normal_roughness = RD::PipelineColorBlendState::create_disabled(1);
|
||||
RD::PipelineColorBlendState blend_state_depth_normal_roughness_giprobe = RD::PipelineColorBlendState::create_disabled(2);
|
||||
|
||||
|
@ -280,18 +280,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
|
||||
|
||||
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_COLOR_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_COLOR_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
};
|
||||
|
||||
shader_version = shader_version_table[k];
|
||||
|
@ -307,38 +297,62 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
|
|||
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
|
||||
RD::PipelineMultisampleState multisample_state;
|
||||
|
||||
if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS || k == PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW) {
|
||||
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
} else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
multisample_state.enable_alpha_to_one = true;
|
||||
}
|
||||
if (k == PIPELINE_VERSION_COLOR_PASS) {
|
||||
for (int l = 0; l < PIPELINE_COLOR_PASS_FLAG_COUNT; l++) {
|
||||
if (!shader_singleton->valid_color_pass_pipelines.has(l)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
blend_state = blend_state_blend;
|
||||
int shader_flags = 0;
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_TRANSPARENT) {
|
||||
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
} else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
|
||||
multisample_state.enable_alpha_to_coverage = true;
|
||||
multisample_state.enable_alpha_to_one = true;
|
||||
}
|
||||
|
||||
if (depth_draw == DEPTH_DRAW_OPAQUE) {
|
||||
depth_stencil.enable_depth_write = false; //alpha does not draw depth
|
||||
blend_state = blend_state_color_blend;
|
||||
|
||||
if (depth_draw == DEPTH_DRAW_OPAQUE) {
|
||||
depth_stencil.enable_depth_write = false; //alpha does not draw depth
|
||||
}
|
||||
} else {
|
||||
blend_state = blend_state_color_opaque;
|
||||
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR;
|
||||
}
|
||||
}
|
||||
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_LIGHTMAP) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_LIGHTMAP;
|
||||
}
|
||||
|
||||
if (l & PIPELINE_COLOR_PASS_FLAG_MULTIVIEW) {
|
||||
shader_flags |= SHADER_COLOR_PASS_FLAG_MULTIVIEW;
|
||||
}
|
||||
|
||||
int variant = shader_version + shader_flags;
|
||||
RID shader_variant = shader_singleton->shader.version_get_shader(version, variant);
|
||||
color_pipelines[i][j][l].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
|
||||
}
|
||||
} else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS || k == PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW) {
|
||||
blend_state = blend_state_opaque;
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW || k == PIPELINE_VERSION_DEPTH_PASS_DP) {
|
||||
//none, leave empty
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
|
||||
blend_state = blend_state_depth_normal_roughness;
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) {
|
||||
blend_state = blend_state_depth_normal_roughness_giprobe;
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL) {
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_SDF) {
|
||||
blend_state = RD::PipelineColorBlendState(); //no color targets for SDF
|
||||
} else {
|
||||
//specular write
|
||||
blend_state = blend_state_opaque_specular;
|
||||
}
|
||||
if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW) {
|
||||
//none, leave empty
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
|
||||
blend_state = blend_state_depth_normal_roughness;
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) {
|
||||
blend_state = blend_state_depth_normal_roughness_giprobe;
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL) {
|
||||
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
|
||||
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_SDF) {
|
||||
blend_state = RD::PipelineColorBlendState(); //no color targets for SDF
|
||||
}
|
||||
|
||||
RID shader_variant = shader_singleton->shader.version_get_shader(version, shader_version);
|
||||
pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
|
||||
RID shader_variant = shader_singleton->shader.version_get_shader(version, shader_version);
|
||||
pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0, singleton->default_specialization_constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -509,25 +523,38 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
|
|||
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE
|
||||
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
|
||||
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n"); // SHADER_VERSION_DEPTH_PASS_WITH_SDF
|
||||
shader_versions.push_back(""); // SHADER_VERSION_COLOR_PASS
|
||||
shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n"); // SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR
|
||||
shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
|
||||
shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR
|
||||
|
||||
// multiview versions of our shaders
|
||||
shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS_MULTIVIEW
|
||||
shader_versions.push_back("\n#define USE_MULTIVIEW\n"); // SHADER_VERSION_COLOR_PASS_MULTIVIEW
|
||||
shader_versions.push_back("\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
|
||||
|
||||
Vector<String> color_pass_flags = {
|
||||
"\n#define MODE_SEPARATE_SPECULAR\n", // SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR
|
||||
"\n#define USE_LIGHTMAP\n", // SHADER_COLOR_PASS_FLAG_LIGHTMAP
|
||||
"\n#define USE_MULTIVIEW\n", // SHADER_COLOR_PASS_FLAG_MULTIVIEW
|
||||
};
|
||||
|
||||
for (int i = 0; i < SHADER_COLOR_PASS_FLAG_COUNT; i++) {
|
||||
String version = "";
|
||||
for (int j = 0; (1 << j) < SHADER_COLOR_PASS_FLAG_COUNT; j += 1) {
|
||||
if ((1 << j) & i) {
|
||||
version += color_pass_flags[j];
|
||||
}
|
||||
}
|
||||
shader_versions.push_back(version);
|
||||
}
|
||||
|
||||
shader.initialize(shader_versions, p_defines);
|
||||
|
||||
if (!RendererCompositorRD::singleton->is_xr_enabled()) {
|
||||
shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_MULTIVIEW, false);
|
||||
shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_MULTIVIEW, false);
|
||||
shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, false);
|
||||
// TODO Add a way to enable/disable color pass flags
|
||||
}
|
||||
}
|
||||
|
||||
valid_color_pass_pipelines.insert(0);
|
||||
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT);
|
||||
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR);
|
||||
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
|
||||
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
|
||||
|
||||
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_shader_funcs);
|
||||
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_material_funcs);
|
||||
|
||||
|
|
|
@ -51,18 +51,18 @@ public:
|
|||
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
|
||||
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
|
||||
|
||||
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_COLOR_PASS_MULTIVIEW,
|
||||
SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
|
||||
|
||||
SHADER_VERSION_COLOR_PASS,
|
||||
SHADER_VERSION_MAX
|
||||
};
|
||||
|
||||
enum ShaderColorPassFlags {
|
||||
SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 0,
|
||||
SHADER_COLOR_PASS_FLAG_LIGHTMAP = 1 << 1,
|
||||
SHADER_COLOR_PASS_FLAG_MULTIVIEW = 1 << 2,
|
||||
SHADER_COLOR_PASS_FLAG_COUNT = 1 << 3
|
||||
};
|
||||
|
||||
enum PipelineVersion {
|
||||
PIPELINE_VERSION_DEPTH_PASS,
|
||||
PIPELINE_VERSION_DEPTH_PASS_DP,
|
||||
|
@ -70,22 +70,19 @@ public:
|
|||
PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
|
||||
PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL,
|
||||
PIPELINE_VERSION_DEPTH_PASS_WITH_SDF,
|
||||
PIPELINE_VERSION_OPAQUE_PASS,
|
||||
PIPELINE_VERSION_OPAQUE_PASS_WITH_SEPARATE_SPECULAR,
|
||||
PIPELINE_VERSION_TRANSPARENT_PASS,
|
||||
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS,
|
||||
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR,
|
||||
PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS,
|
||||
|
||||
PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW,
|
||||
PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW,
|
||||
PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW,
|
||||
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW,
|
||||
PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW,
|
||||
|
||||
PIPELINE_VERSION_COLOR_PASS,
|
||||
PIPELINE_VERSION_MAX
|
||||
};
|
||||
|
||||
enum PipelineColorPassFlags {
|
||||
PIPELINE_COLOR_PASS_FLAG_TRANSPARENT = 1 << 0,
|
||||
PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 1,
|
||||
PIPELINE_COLOR_PASS_FLAG_LIGHTMAP = 1 << 2,
|
||||
PIPELINE_COLOR_PASS_FLAG_MULTIVIEW = 1 << 3,
|
||||
PIPELINE_COLOR_PASS_FLAG_COUNT = 1 << 4,
|
||||
};
|
||||
|
||||
enum ShaderSpecializations {
|
||||
SHADER_SPECIALIZATION_FORWARD_GI = 1 << 0,
|
||||
SHADER_SPECIALIZATION_PROJECTOR = 1 << 1,
|
||||
|
@ -137,6 +134,7 @@ public:
|
|||
RID version;
|
||||
uint32_t vertex_input_mask;
|
||||
PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_VERSION_MAX];
|
||||
PipelineCacheRD color_pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][PIPELINE_COLOR_PASS_FLAG_COUNT];
|
||||
|
||||
String path;
|
||||
|
||||
|
@ -240,6 +238,7 @@ public:
|
|||
ShaderData *overdraw_material_shader_ptr = nullptr;
|
||||
|
||||
Vector<RD::PipelineSpecializationConstant> default_specialization_constants;
|
||||
Set<uint32_t> valid_color_pass_pipelines;
|
||||
SceneShaderForwardClustered();
|
||||
~SceneShaderForwardClustered();
|
||||
|
||||
|
|
|
@ -499,14 +499,14 @@ layout(location = 1) out uvec2 voxel_gi_buffer;
|
|||
#endif //MODE_RENDER_NORMAL
|
||||
#else // RENDER DEPTH
|
||||
|
||||
#ifdef MODE_MULTIPLE_RENDER_TARGETS
|
||||
#ifdef MODE_SEPARATE_SPECULAR
|
||||
|
||||
layout(location = 0) out vec4 diffuse_buffer; //diffuse (rgb) and roughness
|
||||
layout(location = 1) out vec4 specular_buffer; //specular and SSS (subsurface scatter)
|
||||
#else
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
#endif // MODE_MULTIPLE_RENDER_TARGETS
|
||||
#endif // MODE_SEPARATE_SPECULAR
|
||||
|
||||
#endif // RENDER DEPTH
|
||||
|
||||
|
@ -1966,7 +1966,7 @@ void main() {
|
|||
//restore fog
|
||||
fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
|
||||
|
||||
#ifdef MODE_MULTIPLE_RENDER_TARGETS
|
||||
#ifdef MODE_SEPARATE_SPECULAR
|
||||
|
||||
#ifdef MODE_UNSHADED
|
||||
diffuse_buffer = vec4(albedo.rgb, 0.0);
|
||||
|
@ -1984,7 +1984,7 @@ void main() {
|
|||
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
|
||||
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
|
||||
|
||||
#else //MODE_MULTIPLE_RENDER_TARGETS
|
||||
#else //MODE_SEPARATE_SPECULAR
|
||||
|
||||
#ifdef MODE_UNSHADED
|
||||
frag_color = vec4(albedo, alpha);
|
||||
|
@ -1996,7 +1996,7 @@ void main() {
|
|||
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
|
||||
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
|
||||
|
||||
#endif //MODE_MULTIPLE_RENDER_TARGETS
|
||||
#endif //MODE_SEPARATE_SPECULAR
|
||||
|
||||
#endif //MODE_RENDER_DEPTH
|
||||
}
|
||||
|
|
|
@ -528,6 +528,7 @@ public:
|
|||
/*********************/
|
||||
|
||||
struct AttachmentFormat {
|
||||
enum { UNUSED_ATTACHMENT = 0xFFFFFFFF };
|
||||
DataFormat format;
|
||||
TextureSamples samples;
|
||||
uint32_t usage_flags;
|
||||
|
|
Loading…
Reference in a new issue