Merge pull request #59205 from JFonS/color_pass_flags
This commit is contained in:
commit
0896fb5bcb
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…
Add table
Reference in a new issue