mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 20:41:45 +01:00
rsx: Framebuffer fixes
Primary: - Fix SET_SURFACE_CLEAR channel mask - it has been wrong for all these years! Layout is RGBA not ARGB/BGRA like other registers Other Fixes: - vk: Implement subchannel clears using overla pass - vk: Simplify and clean up state management - gl: Fix nullptr deref in case of failed subresource copy - vk/gl: Ignore float buffer clears as hardware seems to do
This commit is contained in:
parent
9abbbb79ae
commit
63d9cb37ec
@ -401,6 +401,8 @@ void GLGSRender::end()
|
||||
//Bind textures and resolve external copy operations
|
||||
std::chrono::time_point<steady_clock> textures_start = steady_clock::now();
|
||||
int unused_location;
|
||||
void *unused = nullptr;
|
||||
gl::texture_view* tmp_view;
|
||||
|
||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
{
|
||||
@ -417,10 +419,10 @@ void GLGSRender::end()
|
||||
{
|
||||
sampler_state->image_handle->bind();
|
||||
}
|
||||
else if (sampler_state->external_subresource_desc.external_handle)
|
||||
else if (sampler_state->external_subresource_desc.external_handle &&
|
||||
(tmp_view = m_gl_texture_cache.create_temporary_subresource(unused, sampler_state->external_subresource_desc)))
|
||||
{
|
||||
void *unused = nullptr;
|
||||
m_gl_texture_cache.create_temporary_subresource(unused, sampler_state->external_subresource_desc)->bind();
|
||||
tmp_view->bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -967,10 +969,14 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
case rsx::surface_color_format::x32:
|
||||
case rsx::surface_color_format::w16z16y16x16:
|
||||
case rsx::surface_color_format::w32z32y32x32:
|
||||
{
|
||||
//Nop
|
||||
break;
|
||||
}
|
||||
case rsx::surface_color_format::g8b8:
|
||||
{
|
||||
//NOP
|
||||
break;
|
||||
colormask = rsx::get_g8b8_r8g8_colormask(colormask);
|
||||
// Fall through
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
@ -158,7 +158,7 @@ struct driver_state
|
||||
{
|
||||
if (!test_property(GL_COLOR_WRITEMASK, mask))
|
||||
{
|
||||
glColorMask(((mask & 0x20) ? 1 : 0), ((mask & 0x40) ? 1 : 0), ((mask & 0x80) ? 1 : 0), ((mask & 0x10) ? 1 : 0));
|
||||
glColorMask(((mask & 0x10) ? 1 : 0), ((mask & 0x20) ? 1 : 0), ((mask & 0x40) ? 1 : 0), ((mask & 0x80) ? 1 : 0));
|
||||
properties[GL_COLOR_WRITEMASK] = mask;
|
||||
}
|
||||
}
|
||||
@ -166,10 +166,10 @@ struct driver_state
|
||||
void color_mask(bool r, bool g, bool b, bool a)
|
||||
{
|
||||
u32 mask = 0;
|
||||
if (r) mask |= 0x20;
|
||||
if (g) mask |= 0x40;
|
||||
if (b) mask |= 0x80;
|
||||
if (a) mask |= 0x10;
|
||||
if (r) mask |= 0x10;
|
||||
if (g) mask |= 0x20;
|
||||
if (b) mask |= 0x40;
|
||||
if (a) mask |= 0x80;
|
||||
|
||||
color_mask(mask);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ namespace vk
|
||||
|
||||
case rsx::surface_color_format::g8b8:
|
||||
{
|
||||
VkComponentMapping gb_rg = { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R };
|
||||
VkComponentMapping gb_rg = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G };
|
||||
return std::make_pair(VK_FORMAT_R8G8_UNORM, gb_rg);
|
||||
}
|
||||
|
||||
@ -625,6 +625,9 @@ VKGSRender::VKGSRender() : GSRender()
|
||||
m_depth_scaler.reset(new vk::depth_scaling_pass());
|
||||
m_depth_scaler->create(*m_device);
|
||||
|
||||
m_attachment_clear_pass.reset(new vk::attachment_clear_pass());
|
||||
m_attachment_clear_pass->create(*m_device);
|
||||
|
||||
m_prog_buffer.reset(new VKProgramBuffer(m_render_passes.data()));
|
||||
|
||||
if (g_cfg.video.disable_vertex_cache)
|
||||
@ -632,7 +635,7 @@ VKGSRender::VKGSRender() : GSRender()
|
||||
else
|
||||
m_vertex_cache.reset(new vk::weak_vertex_cache());
|
||||
|
||||
m_shaders_cache.reset(new vk::shader_cache(*m_prog_buffer.get(), "vulkan", "v1.2"));
|
||||
m_shaders_cache.reset(new vk::shader_cache(*m_prog_buffer.get(), "vulkan", "v1.25"));
|
||||
|
||||
open_command_buffer();
|
||||
|
||||
@ -752,6 +755,10 @@ VKGSRender::~VKGSRender()
|
||||
m_depth_scaler->destroy();
|
||||
m_depth_scaler.reset();
|
||||
|
||||
//Attachment clear helper
|
||||
m_attachment_clear_pass->destroy();
|
||||
m_attachment_clear_pass.reset();
|
||||
|
||||
//Pipeline descriptors
|
||||
vkDestroyPipelineLayout(*m_device, pipeline_layout, nullptr);
|
||||
vkDestroyDescriptorSetLayout(*m_device, descriptor_layouts, nullptr);
|
||||
@ -1076,7 +1083,6 @@ void VKGSRender::end()
|
||||
|
||||
std::chrono::time_point<steady_clock> textures_start = vertex_end;
|
||||
|
||||
|
||||
auto ds = std::get<1>(m_rtts.m_bound_depth_stencil);
|
||||
|
||||
//Check for data casts
|
||||
@ -1084,6 +1090,13 @@ void VKGSRender::end()
|
||||
{
|
||||
if (ds->old_contents->info.format == VK_FORMAT_B8G8R8A8_UNORM)
|
||||
{
|
||||
//This routine does not recover stencil data, initialize to 255
|
||||
VkClearDepthStencilValue clear_depth = { 1.f, 255 };
|
||||
VkImageSubresourceRange range = { VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1 };
|
||||
change_image_layout(*m_current_command_buffer, ds, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
vkCmdClearDepthStencilImage(*m_current_command_buffer, ds->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_depth, 1, &range);
|
||||
change_image_layout(*m_current_command_buffer, ds, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
auto rp = vk::get_render_pass_location(VK_FORMAT_UNDEFINED, ds->info.format, 0);
|
||||
auto render_pass = m_render_passes[rp];
|
||||
m_depth_converter->run(*m_current_command_buffer, ds->width(), ds->height(), ds, ds->old_contents->get_view(0xAAE4, rsx::default_remap_vector), render_pass, m_framebuffers_to_clean);
|
||||
@ -1678,41 +1691,96 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
|
||||
if (mask & 0x2)
|
||||
{
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8)
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8 &&
|
||||
rsx::method_registers.stencil_mask() != 0)
|
||||
{
|
||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||
|
||||
depth_stencil_clear_values.depthStencil.stencil = clear_stencil;
|
||||
|
||||
depth_stencil_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & 0xF0)
|
||||
if (auto colormask = (mask & 0xF0))
|
||||
{
|
||||
if (m_draw_buffers_count > 0)
|
||||
{
|
||||
u8 clear_a = rsx::method_registers.clear_color_a();
|
||||
u8 clear_r = rsx::method_registers.clear_color_r();
|
||||
u8 clear_g = rsx::method_registers.clear_color_g();
|
||||
u8 clear_b = rsx::method_registers.clear_color_b();
|
||||
|
||||
color_clear_values.color.float32[0] = (float)clear_r / 255;
|
||||
color_clear_values.color.float32[1] = (float)clear_g / 255;
|
||||
color_clear_values.color.float32[2] = (float)clear_b / 255;
|
||||
color_clear_values.color.float32[3] = (float)clear_a / 255;
|
||||
|
||||
for (u32 index = 0; index < m_draw_buffers_count; ++index)
|
||||
bool use_fast_clear = false;
|
||||
bool ignore_clear = false;
|
||||
switch (rsx::method_registers.surface_color())
|
||||
{
|
||||
clear_descriptors.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, index, color_clear_values });
|
||||
}
|
||||
case rsx::surface_color_format::x32:
|
||||
case rsx::surface_color_format::w16z16y16x16:
|
||||
case rsx::surface_color_format::w32z32y32x32:
|
||||
//NOP
|
||||
ignore_clear = true;
|
||||
break;
|
||||
case rsx::surface_color_format::g8b8:
|
||||
colormask = rsx::get_g8b8_r8g8_colormask(colormask);
|
||||
use_fast_clear = (colormask == (0x10 | 0x20));
|
||||
ignore_clear = (colormask == 0);
|
||||
colormask |= (0x40 | 0x80);
|
||||
break;
|
||||
default:
|
||||
use_fast_clear = (colormask == (0x10 | 0x20 | 0x40 | 0x80));
|
||||
break;
|
||||
};
|
||||
|
||||
for (auto &rtt : m_rtts.m_bound_render_targets)
|
||||
if (!ignore_clear)
|
||||
{
|
||||
if (std::get<0>(rtt) != 0)
|
||||
u8 clear_a = rsx::method_registers.clear_color_a();
|
||||
u8 clear_r = rsx::method_registers.clear_color_r();
|
||||
u8 clear_g = rsx::method_registers.clear_color_g();
|
||||
u8 clear_b = rsx::method_registers.clear_color_b();
|
||||
|
||||
color_clear_values.color.float32[0] = (float)clear_r / 255;
|
||||
color_clear_values.color.float32[1] = (float)clear_g / 255;
|
||||
color_clear_values.color.float32[2] = (float)clear_b / 255;
|
||||
color_clear_values.color.float32[3] = (float)clear_a / 255;
|
||||
|
||||
if (use_fast_clear)
|
||||
{
|
||||
std::get<1>(rtt)->dirty = false;
|
||||
std::get<1>(rtt)->old_contents = nullptr;
|
||||
for (u32 index = 0; index < m_draw_buffers_count; ++index)
|
||||
{
|
||||
clear_descriptors.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, index, color_clear_values });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
color4f clear_color =
|
||||
{
|
||||
color_clear_values.color.float32[0],
|
||||
color_clear_values.color.float32[1],
|
||||
color_clear_values.color.float32[2],
|
||||
color_clear_values.color.float32[3]
|
||||
};
|
||||
|
||||
m_attachment_clear_pass->update_config(colormask, clear_color);
|
||||
for (u32 index = 0; index < m_draw_buffers_count; ++index)
|
||||
{
|
||||
if (auto rtt = std::get<1>(m_rtts.m_bound_render_targets[index]))
|
||||
{
|
||||
vk::insert_texture_barrier(*m_current_command_buffer, rtt);
|
||||
m_attachment_clear_pass->run(*m_current_command_buffer, rtt->width(), rtt->height(),
|
||||
rtt, rtt->get_view(0xAAE4, rsx::default_remap_vector),
|
||||
m_draw_fbo->info.renderPass, m_framebuffers_to_clean);
|
||||
}
|
||||
else
|
||||
fmt::throw_exception("Unreachable" HERE);
|
||||
}
|
||||
|
||||
//Fush unconditinally - parameters might not persist
|
||||
//TODO: Better parameter management for overlay passes
|
||||
flush_command_queue();
|
||||
}
|
||||
|
||||
for (auto &rtt : m_rtts.m_bound_render_targets)
|
||||
{
|
||||
if (std::get<0>(rtt) != 0)
|
||||
{
|
||||
std::get<1>(rtt)->dirty = false;
|
||||
std::get<1>(rtt)->old_contents = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1966,6 +2034,7 @@ void VKGSRender::process_swap_request(frame_context_t *ctx, bool free_resources)
|
||||
m_text_writer->reset_descriptors();
|
||||
}
|
||||
|
||||
m_attachment_clear_pass->free_resources();
|
||||
m_depth_converter->free_resources();
|
||||
m_depth_scaler->free_resources();
|
||||
m_ui_renderer->free_resources();
|
||||
@ -2154,22 +2223,32 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
|
||||
|
||||
vk::pipeline_props properties = {};
|
||||
|
||||
// Input assembly
|
||||
bool emulated_primitive_type;
|
||||
|
||||
properties.ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
properties.ia.topology = vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, emulated_primitive_type);
|
||||
properties.state.set_primitive_type(vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, emulated_primitive_type));
|
||||
|
||||
const bool restarts_valid = rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed && !emulated_primitive_type && !rsx::method_registers.current_draw_clause.is_disjoint_primitive;
|
||||
if (rsx::method_registers.restart_index_enabled() && !vk::emulate_primitive_restart() && restarts_valid)
|
||||
properties.ia.primitiveRestartEnable = VK_TRUE;
|
||||
else
|
||||
properties.ia.primitiveRestartEnable = VK_FALSE;
|
||||
properties.state.enable_primitive_restart();
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
properties.att_state[i].colorWriteMask = 0xf;
|
||||
properties.att_state[i].blendEnable = VK_FALSE;
|
||||
}
|
||||
// Rasterizer state
|
||||
properties.state.set_attachment_count(m_draw_buffers_count);
|
||||
properties.state.set_depth_mask(rsx::method_registers.depth_write_enabled());
|
||||
properties.state.set_front_face(vk::get_front_face(rsx::method_registers.front_face_mode()));
|
||||
properties.state.enable_depth_clamp(rsx::method_registers.depth_clamp_enabled() || !rsx::method_registers.depth_clip_enabled());
|
||||
properties.state.enable_depth_bias(true);
|
||||
|
||||
if (rsx::method_registers.depth_test_enabled())
|
||||
properties.state.enable_depth_test(vk::get_compare_func(rsx::method_registers.depth_func()));
|
||||
|
||||
if (rsx::method_registers.logic_op_enabled())
|
||||
properties.state.enable_logic_op(vk::get_logic_op(rsx::method_registers.logic_operation()));
|
||||
|
||||
if (rsx::method_registers.depth_bounds_test_enabled())
|
||||
properties.state.enable_depth_bounds_test();
|
||||
|
||||
if (rsx::method_registers.cull_face_enabled())
|
||||
properties.state.enable_cull_face(vk::get_cull_face(rsx::method_registers.cull_face_mode()));
|
||||
|
||||
bool color_mask_b = rsx::method_registers.color_mask_b();
|
||||
bool color_mask_g = rsx::method_registers.color_mask_g();
|
||||
@ -2177,21 +2256,9 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
|
||||
bool color_mask_a = rsx::method_registers.color_mask_a();
|
||||
|
||||
if (rsx::method_registers.surface_color() == rsx::surface_color_format::g8b8)
|
||||
{
|
||||
//Map GB components onto RG
|
||||
rsx::get_g8b8_r8g8_colormask(color_mask_r, color_mask_g, color_mask_b, color_mask_a);
|
||||
}
|
||||
|
||||
VkColorComponentFlags mask = 0;
|
||||
if (color_mask_a) mask |= VK_COLOR_COMPONENT_A_BIT;
|
||||
if (color_mask_b) mask |= VK_COLOR_COMPONENT_B_BIT;
|
||||
if (color_mask_g) mask |= VK_COLOR_COMPONENT_G_BIT;
|
||||
if (color_mask_r) mask |= VK_COLOR_COMPONENT_R_BIT;
|
||||
|
||||
for (u8 idx = 0; idx < m_draw_buffers_count; ++idx)
|
||||
{
|
||||
properties.att_state[idx].colorWriteMask = mask;
|
||||
}
|
||||
properties.state.set_color_mask(color_mask_r, color_mask_g, color_mask_b, color_mask_a);
|
||||
|
||||
bool mrt_blend_enabled[] =
|
||||
{
|
||||
@ -2238,84 +2305,50 @@ void VKGSRender::load_program(const vk::vertex_upload_info& vertex_info)
|
||||
{
|
||||
if (mrt_blend_enabled[idx])
|
||||
{
|
||||
properties.att_state[idx].blendEnable = VK_TRUE;
|
||||
properties.att_state[idx].srcColorBlendFactor = sfactor_rgb;
|
||||
properties.att_state[idx].dstColorBlendFactor = dfactor_rgb;
|
||||
properties.att_state[idx].srcAlphaBlendFactor = sfactor_a;
|
||||
properties.att_state[idx].dstAlphaBlendFactor = dfactor_a;
|
||||
properties.att_state[idx].colorBlendOp = equation_rgb;
|
||||
properties.att_state[idx].alphaBlendOp = equation_a;
|
||||
properties.state.enable_blend(idx, sfactor_rgb, sfactor_a, dfactor_rgb, dfactor_a, equation_rgb, equation_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
properties.cs.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
properties.cs.attachmentCount = m_draw_buffers_count;
|
||||
properties.cs.pAttachments = properties.att_state;
|
||||
|
||||
if (rsx::method_registers.logic_op_enabled())
|
||||
{
|
||||
properties.cs.logicOpEnable = true;
|
||||
properties.cs.logicOp = vk::get_logic_op(rsx::method_registers.logic_operation());
|
||||
}
|
||||
|
||||
properties.ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
properties.ds.depthWriteEnable = rsx::method_registers.depth_write_enabled() ? VK_TRUE : VK_FALSE;
|
||||
|
||||
if (rsx::method_registers.depth_bounds_test_enabled())
|
||||
{
|
||||
properties.ds.depthBoundsTestEnable = VK_TRUE;
|
||||
}
|
||||
else
|
||||
properties.ds.depthBoundsTestEnable = VK_FALSE;
|
||||
|
||||
if (rsx::method_registers.stencil_test_enabled())
|
||||
{
|
||||
properties.ds.stencilTestEnable = VK_TRUE;
|
||||
properties.ds.front.failOp = vk::get_stencil_op(rsx::method_registers.stencil_op_fail());
|
||||
properties.ds.front.passOp = vk::get_stencil_op(rsx::method_registers.stencil_op_zpass());
|
||||
properties.ds.front.depthFailOp = vk::get_stencil_op(rsx::method_registers.stencil_op_zfail());
|
||||
properties.ds.front.compareOp = vk::get_compare_func(rsx::method_registers.stencil_func());
|
||||
|
||||
if (rsx::method_registers.two_sided_stencil_test_enabled())
|
||||
if (!rsx::method_registers.two_sided_stencil_test_enabled())
|
||||
{
|
||||
properties.ds.back.failOp = vk::get_stencil_op(rsx::method_registers.back_stencil_op_fail());
|
||||
properties.ds.back.passOp = vk::get_stencil_op(rsx::method_registers.back_stencil_op_zpass());
|
||||
properties.ds.back.depthFailOp = vk::get_stencil_op(rsx::method_registers.back_stencil_op_zfail());
|
||||
properties.ds.back.compareOp = vk::get_compare_func(rsx::method_registers.back_stencil_func());
|
||||
properties.state.set_stencil_mask(rsx::method_registers.stencil_mask());
|
||||
|
||||
properties.state.enable_stencil_test(
|
||||
vk::get_stencil_op(rsx::method_registers.stencil_op_fail()),
|
||||
vk::get_stencil_op(rsx::method_registers.stencil_op_zfail()),
|
||||
vk::get_stencil_op(rsx::method_registers.stencil_op_zpass()),
|
||||
vk::get_compare_func(rsx::method_registers.stencil_func()),
|
||||
rsx::method_registers.stencil_func_mask(),
|
||||
rsx::method_registers.stencil_func_ref());
|
||||
}
|
||||
else
|
||||
properties.ds.back = properties.ds.front;
|
||||
{
|
||||
properties.state.set_stencil_mask_separate(0, rsx::method_registers.stencil_mask());
|
||||
properties.state.set_stencil_mask_separate(1, rsx::method_registers.back_stencil_mask());
|
||||
|
||||
properties.state.enable_stencil_test_separate(0,
|
||||
vk::get_stencil_op(rsx::method_registers.stencil_op_fail()),
|
||||
vk::get_stencil_op(rsx::method_registers.stencil_op_zfail()),
|
||||
vk::get_stencil_op(rsx::method_registers.stencil_op_zpass()),
|
||||
vk::get_compare_func(rsx::method_registers.stencil_func()),
|
||||
rsx::method_registers.stencil_func_mask(),
|
||||
rsx::method_registers.stencil_func_ref());
|
||||
|
||||
properties.state.enable_stencil_test_separate(1,
|
||||
vk::get_stencil_op(rsx::method_registers.back_stencil_op_fail()),
|
||||
vk::get_stencil_op(rsx::method_registers.back_stencil_op_zfail()),
|
||||
vk::get_stencil_op(rsx::method_registers.back_stencil_op_zpass()),
|
||||
vk::get_compare_func(rsx::method_registers.back_stencil_func()),
|
||||
rsx::method_registers.back_stencil_func_mask(),
|
||||
rsx::method_registers.back_stencil_func_ref());
|
||||
}
|
||||
}
|
||||
else
|
||||
properties.ds.stencilTestEnable = VK_FALSE;
|
||||
|
||||
if (rsx::method_registers.depth_test_enabled())
|
||||
{
|
||||
properties.ds.depthTestEnable = VK_TRUE;
|
||||
properties.ds.depthCompareOp = vk::get_compare_func(rsx::method_registers.depth_func());
|
||||
}
|
||||
else
|
||||
properties.ds.depthTestEnable = VK_FALSE;
|
||||
|
||||
properties.rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
properties.rs.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
properties.rs.depthClampEnable = rsx::method_registers.depth_clamp_enabled() || !rsx::method_registers.depth_clip_enabled();
|
||||
properties.rs.rasterizerDiscardEnable = VK_FALSE;
|
||||
|
||||
//Disabled by setting factors to 0 as needed
|
||||
properties.rs.depthBiasEnable = VK_TRUE;
|
||||
|
||||
if (rsx::method_registers.cull_face_enabled())
|
||||
properties.rs.cullMode = vk::get_cull_face(rsx::method_registers.cull_face_mode());
|
||||
else
|
||||
properties.rs.cullMode = VK_CULL_MODE_NONE;
|
||||
|
||||
properties.rs.frontFace = vk::get_front_face(rsx::method_registers.front_face_mode());
|
||||
|
||||
properties.render_pass = m_render_passes[m_current_renderpass_id];
|
||||
properties.render_pass_location = (int)m_current_renderpass_id;
|
||||
|
||||
properties.num_targets = m_draw_buffers_count;
|
||||
|
||||
vk::enter_uninterruptible();
|
||||
|
@ -264,6 +264,7 @@ private:
|
||||
std::unique_ptr<vk::depth_convert_pass> m_depth_converter;
|
||||
std::unique_ptr<vk::depth_scaling_pass> m_depth_scaler;
|
||||
std::unique_ptr<vk::ui_overlay_renderer> m_ui_renderer;
|
||||
std::unique_ptr<vk::attachment_clear_pass> m_attachment_clear_pass;
|
||||
|
||||
shared_mutex m_sampler_mutex;
|
||||
u64 surface_store_tag = 0;
|
||||
|
@ -2098,6 +2098,164 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class graphics_pipeline_state
|
||||
{
|
||||
public:
|
||||
VkPipelineInputAssemblyStateCreateInfo ia;
|
||||
VkPipelineDepthStencilStateCreateInfo ds;
|
||||
VkPipelineColorBlendAttachmentState att_state[4];
|
||||
VkPipelineColorBlendStateCreateInfo cs;
|
||||
VkPipelineRasterizationStateCreateInfo rs;
|
||||
|
||||
graphics_pipeline_state()
|
||||
{
|
||||
ia = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
cs = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
|
||||
ds = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
|
||||
rs = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
att_state[i] = {};
|
||||
}
|
||||
|
||||
rs.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rs.cullMode = VK_CULL_MODE_NONE;
|
||||
rs.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
rs.lineWidth = 1.f;
|
||||
}
|
||||
|
||||
~graphics_pipeline_state()
|
||||
{}
|
||||
|
||||
void set_primitive_type(VkPrimitiveTopology type)
|
||||
{
|
||||
ia.topology = type;
|
||||
}
|
||||
|
||||
void enable_primitive_restart(bool enable = true)
|
||||
{
|
||||
ia.primitiveRestartEnable = enable? VK_TRUE : VK_FALSE;
|
||||
}
|
||||
|
||||
void set_color_mask(bool r, bool g, bool b, bool a)
|
||||
{
|
||||
VkColorComponentFlags mask = 0;
|
||||
if (a) mask |= VK_COLOR_COMPONENT_A_BIT;
|
||||
if (b) mask |= VK_COLOR_COMPONENT_B_BIT;
|
||||
if (g) mask |= VK_COLOR_COMPONENT_G_BIT;
|
||||
if (r) mask |= VK_COLOR_COMPONENT_R_BIT;
|
||||
|
||||
att_state[0].colorWriteMask = mask;
|
||||
att_state[1].colorWriteMask = mask;
|
||||
att_state[2].colorWriteMask = mask;
|
||||
att_state[3].colorWriteMask = mask;
|
||||
}
|
||||
|
||||
void set_depth_mask(bool enable)
|
||||
{
|
||||
ds.depthWriteEnable = enable ? VK_TRUE : VK_FALSE;
|
||||
}
|
||||
|
||||
void set_stencil_mask(u32 mask)
|
||||
{
|
||||
ds.front.writeMask = mask;
|
||||
ds.back.writeMask = mask;
|
||||
}
|
||||
|
||||
void set_stencil_mask_separate(int face, u32 mask)
|
||||
{
|
||||
if (!face)
|
||||
ds.front.writeMask = mask;
|
||||
else
|
||||
ds.back.writeMask = mask;
|
||||
}
|
||||
|
||||
void enable_depth_test(VkCompareOp op)
|
||||
{
|
||||
ds.depthTestEnable = VK_TRUE;
|
||||
ds.depthCompareOp = op;
|
||||
}
|
||||
|
||||
void enable_depth_clamp(bool enable = true)
|
||||
{
|
||||
rs.depthClampEnable = enable ? VK_TRUE : VK_FALSE;
|
||||
}
|
||||
|
||||
void enable_depth_bias(bool enable = true)
|
||||
{
|
||||
rs.depthBiasEnable = VK_TRUE;
|
||||
}
|
||||
|
||||
void enable_depth_bounds_test(bool enable = true)
|
||||
{
|
||||
ds.depthBoundsTestEnable = enable? VK_TRUE : VK_FALSE;
|
||||
}
|
||||
|
||||
void enable_blend(int mrt_index, VkBlendFactor src_factor_rgb, VkBlendFactor src_factor_a,
|
||||
VkBlendFactor dst_factor_rgb, VkBlendFactor dst_factor_a,
|
||||
VkBlendOp equation_rgb, VkBlendOp equation_a)
|
||||
{
|
||||
att_state[mrt_index].srcColorBlendFactor = src_factor_rgb;
|
||||
att_state[mrt_index].srcAlphaBlendFactor = src_factor_a;
|
||||
att_state[mrt_index].dstColorBlendFactor = dst_factor_rgb;
|
||||
att_state[mrt_index].dstAlphaBlendFactor = dst_factor_a;
|
||||
att_state[mrt_index].colorBlendOp = equation_rgb;
|
||||
att_state[mrt_index].alphaBlendOp = equation_a;
|
||||
att_state[mrt_index].blendEnable = VK_TRUE;
|
||||
}
|
||||
|
||||
void enable_stencil_test(VkStencilOp fail, VkStencilOp zfail, VkStencilOp pass,
|
||||
VkCompareOp func, u32 func_mask, u32 ref)
|
||||
{
|
||||
ds.front.failOp = fail;
|
||||
ds.front.passOp = pass;
|
||||
ds.front.depthFailOp = zfail;
|
||||
ds.front.compareOp = func;
|
||||
ds.front.compareMask = func_mask;
|
||||
ds.front.reference = ref;
|
||||
ds.back = ds.front;
|
||||
|
||||
ds.stencilTestEnable = VK_TRUE;
|
||||
}
|
||||
|
||||
void enable_stencil_test_separate(int face, VkStencilOp fail, VkStencilOp zfail, VkStencilOp pass,
|
||||
VkCompareOp func, u32 func_mask, u32 ref)
|
||||
{
|
||||
auto& face_props = (face ? ds.back : ds.front);
|
||||
face_props.failOp = fail;
|
||||
face_props.passOp = pass;
|
||||
face_props.depthFailOp = zfail;
|
||||
face_props.compareOp = func;
|
||||
face_props.compareMask = func_mask;
|
||||
face_props.reference = ref;
|
||||
|
||||
ds.stencilTestEnable = VK_TRUE;
|
||||
}
|
||||
|
||||
void enable_logic_op(VkLogicOp op)
|
||||
{
|
||||
cs.logicOpEnable = VK_TRUE;
|
||||
cs.logicOp = op;
|
||||
}
|
||||
|
||||
void enable_cull_face(VkCullModeFlags cull_mode)
|
||||
{
|
||||
rs.cullMode = cull_mode;
|
||||
}
|
||||
|
||||
void set_front_face(VkFrontFace face)
|
||||
{
|
||||
rs.frontFace = face;
|
||||
}
|
||||
|
||||
void set_attachment_count(u32 count)
|
||||
{
|
||||
cs.attachmentCount = count;
|
||||
cs.pAttachments = att_state;
|
||||
}
|
||||
};
|
||||
|
||||
namespace glsl
|
||||
{
|
||||
enum program_input_type
|
||||
|
@ -30,15 +30,7 @@ namespace vk
|
||||
std::string vs_src;
|
||||
std::string fs_src;
|
||||
|
||||
struct
|
||||
{
|
||||
int color_attachments = 0;
|
||||
bool write_color = true;
|
||||
bool write_depth = true;
|
||||
bool no_depth_test = true;
|
||||
bool enable_blend = false;
|
||||
}
|
||||
renderpass_config;
|
||||
graphics_pipeline_state renderpass_config;
|
||||
|
||||
bool initialized = false;
|
||||
bool compiled = false;
|
||||
@ -46,6 +38,15 @@ namespace vk
|
||||
u32 num_drawable_elements = 4;
|
||||
u32 first_vertex = 0;
|
||||
|
||||
overlay_pass()
|
||||
{
|
||||
//Override-able defaults
|
||||
renderpass_config.set_primitive_type(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
~overlay_pass()
|
||||
{}
|
||||
|
||||
void init_descriptors()
|
||||
{
|
||||
VkDescriptorPoolSize descriptor_pool_sizes[2] =
|
||||
@ -173,51 +174,16 @@ namespace vk
|
||||
ms.pSampleMask = NULL;
|
||||
ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo ia = {};
|
||||
ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rs = {};
|
||||
rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rs.lineWidth = 1.f;
|
||||
rs.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
|
||||
VkPipelineColorBlendAttachmentState att = {};
|
||||
if (renderpass_config.write_color)
|
||||
{
|
||||
att.colorWriteMask = 0xf;
|
||||
|
||||
if (renderpass_config.enable_blend)
|
||||
{
|
||||
att.blendEnable = VK_TRUE;
|
||||
att.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
att.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
att.dstAlphaBlendFactor = att.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
att.srcAlphaBlendFactor = att.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo cs = {};
|
||||
cs.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
cs.attachmentCount = renderpass_config.color_attachments;
|
||||
cs.pAttachments = &att;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo ds = {};
|
||||
ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
ds.depthWriteEnable = renderpass_config.write_depth? VK_TRUE: VK_FALSE;
|
||||
ds.depthTestEnable = VK_TRUE;
|
||||
ds.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkGraphicsPipelineCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.pVertexInputState = &vi;
|
||||
info.pInputAssemblyState = &ia;
|
||||
info.pRasterizationState = &rs;
|
||||
info.pColorBlendState = &cs;
|
||||
info.pInputAssemblyState = &renderpass_config.ia;
|
||||
info.pRasterizationState = &renderpass_config.rs;
|
||||
info.pColorBlendState = &renderpass_config.cs;
|
||||
info.pMultisampleState = &ms;
|
||||
info.pViewportState = &vp;
|
||||
info.pDepthStencilState = &ds;
|
||||
info.pDepthStencilState = &renderpass_config.ds;
|
||||
info.stageCount = 2;
|
||||
info.pStages = shader_stages;
|
||||
info.pDynamicState = &dynamic_state_info;
|
||||
@ -426,7 +392,8 @@ namespace vk
|
||||
"}\n"
|
||||
};
|
||||
|
||||
renderpass_config.write_color = false;
|
||||
renderpass_config.set_depth_mask(true);
|
||||
renderpass_config.enable_depth_test(VK_COMPARE_OP_ALWAYS);
|
||||
|
||||
m_vertex_shader.id = 100002;
|
||||
m_fragment_shader.id = 100003;
|
||||
@ -507,10 +474,13 @@ namespace vk
|
||||
"}\n"
|
||||
};
|
||||
|
||||
renderpass_config.color_attachments = 1;
|
||||
renderpass_config.write_color = true;
|
||||
renderpass_config.write_depth = false;
|
||||
renderpass_config.enable_blend = true;
|
||||
renderpass_config.set_attachment_count(1);
|
||||
renderpass_config.set_color_mask(true, true, true, true);
|
||||
renderpass_config.set_depth_mask(false);
|
||||
renderpass_config.enable_blend(0,
|
||||
VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
VK_BLEND_OP_ADD, VK_BLEND_OP_ADD);
|
||||
|
||||
m_vertex_shader.id = 100004;
|
||||
m_fragment_shader.id = 100005;
|
||||
@ -749,9 +719,96 @@ namespace vk
|
||||
"}\n"
|
||||
};
|
||||
|
||||
renderpass_config.write_color = false;
|
||||
renderpass_config.set_depth_mask(true);
|
||||
renderpass_config.enable_depth_test(VK_COMPARE_OP_ALWAYS);
|
||||
|
||||
m_vertex_shader.id = 100006;
|
||||
m_fragment_shader.id = 100007;
|
||||
}
|
||||
};
|
||||
|
||||
struct attachment_clear_pass : public overlay_pass
|
||||
{
|
||||
color4f clear_color = { 0.f, 0.f, 0.f, 0.f };
|
||||
color4f colormask = { 1.f, 1.f, 1.f, 1.f };
|
||||
|
||||
attachment_clear_pass()
|
||||
{
|
||||
vs_src =
|
||||
{
|
||||
"#version 450\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
"layout(std140, set=0, binding=1) uniform static_data{ vec4 regs[8]; };\n"
|
||||
"layout(location=0) out vec2 tc0;\n"
|
||||
"layout(location=1) out vec4 color;\n"
|
||||
"layout(location=2) out vec4 mask;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n"
|
||||
" vec2 coords[] = {vec2(0., 0.), vec2(1., 0.), vec2(0., 1.), vec2(1., 1.)};\n"
|
||||
" tc0 = coords[gl_VertexIndex % 4];\n"
|
||||
" color = regs[0];\n"
|
||||
" mask = regs[1];\n"
|
||||
" gl_Position = vec4(positions[gl_VertexIndex % 4], 0., 1.);\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
fs_src =
|
||||
{
|
||||
"#version 420\n"
|
||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||
"layout(set=0, binding=0) uniform sampler2D fs0;\n"
|
||||
"layout(location=0) in vec2 tc0;\n"
|
||||
"layout(location=1) in vec4 color;\n"
|
||||
"layout(location=2) in vec4 mask;\n"
|
||||
"layout(location=0) out vec4 out_color;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec4 original_color = texture(fs0, tc0);\n"
|
||||
" out_color = mix(original_color, color, bvec4(mask));\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
renderpass_config.set_depth_mask(false);
|
||||
renderpass_config.set_color_mask(true, true, true, true);
|
||||
renderpass_config.set_attachment_count(1);
|
||||
|
||||
m_vertex_shader.id = 100006;
|
||||
m_fragment_shader.id = 100007;
|
||||
}
|
||||
|
||||
void update_uniforms(vk::glsl::program* /*program*/) override
|
||||
{
|
||||
auto dst = (f32*)m_ubo->map(0, 128);
|
||||
dst[0] = clear_color.r;
|
||||
dst[1] = clear_color.g;
|
||||
dst[2] = clear_color.b;
|
||||
dst[3] = clear_color.a;
|
||||
dst[4] = colormask.r;
|
||||
dst[5] = colormask.g;
|
||||
dst[6] = colormask.b;
|
||||
dst[7] = colormask.a;
|
||||
m_ubo->unmap();
|
||||
}
|
||||
|
||||
bool update_config(u32 clearmask, color4f color)
|
||||
{
|
||||
color4f mask = { 0.f, 0.f, 0.f, 0.f };
|
||||
if (clearmask & 0x10) mask.r = 1.f;
|
||||
if (clearmask & 0x20) mask.g = 1.f;
|
||||
if (clearmask & 0x40) mask.b = 1.f;
|
||||
if (clearmask & 0x80) mask.a = 1.f;
|
||||
|
||||
if (mask != colormask || color != clear_color)
|
||||
{
|
||||
colormask = mask;
|
||||
clear_color = color;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -3,45 +3,41 @@
|
||||
#include "VKFragmentProgram.h"
|
||||
#include "../Common/ProgramStateCache.h"
|
||||
#include "Utilities/hash.h"
|
||||
#include "VKHelpers.h"
|
||||
|
||||
namespace vk
|
||||
{
|
||||
struct pipeline_props
|
||||
{
|
||||
VkPipelineInputAssemblyStateCreateInfo ia;
|
||||
VkPipelineDepthStencilStateCreateInfo ds;
|
||||
VkPipelineColorBlendAttachmentState att_state[4];
|
||||
VkPipelineColorBlendStateCreateInfo cs;
|
||||
VkPipelineRasterizationStateCreateInfo rs;
|
||||
|
||||
graphics_pipeline_state state;
|
||||
VkRenderPass render_pass;
|
||||
int num_targets;
|
||||
int render_pass_location;
|
||||
|
||||
bool operator==(const pipeline_props& other) const
|
||||
{
|
||||
if (memcmp(&att_state[0], &other.att_state[0], sizeof(VkPipelineColorBlendAttachmentState)))
|
||||
if (memcmp(&state.att_state[0], &other.state.att_state[0], sizeof(VkPipelineColorBlendAttachmentState)))
|
||||
return false;
|
||||
|
||||
if (render_pass_location != other.render_pass_location)
|
||||
return false;
|
||||
|
||||
if (memcmp(&rs, &other.rs, sizeof(VkPipelineRasterizationStateCreateInfo)))
|
||||
if (memcmp(&state.rs, &other.state.rs, sizeof(VkPipelineRasterizationStateCreateInfo)))
|
||||
return false;
|
||||
|
||||
//Cannot memcmp cs due to pAttachments being a pointer to memory
|
||||
if (cs.attachmentCount != other.cs.attachmentCount ||
|
||||
cs.flags != other.cs.flags ||
|
||||
cs.logicOp != other.cs.logicOp ||
|
||||
cs.logicOpEnable != other.cs.logicOpEnable ||
|
||||
cs.sType != other.cs.sType ||
|
||||
memcmp(cs.blendConstants, other.cs.blendConstants, 4 * sizeof(f32)))
|
||||
if (state.cs.attachmentCount != other.state.cs.attachmentCount ||
|
||||
state.cs.flags != other.state.cs.flags ||
|
||||
state.cs.logicOp != other.state.cs.logicOp ||
|
||||
state.cs.logicOpEnable != other.state.cs.logicOpEnable ||
|
||||
state.cs.sType != other.state.cs.sType ||
|
||||
memcmp(state.cs.blendConstants, other.state.cs.blendConstants, 4 * sizeof(f32)))
|
||||
return false;
|
||||
|
||||
if (memcmp(&ia, &other.ia, sizeof(VkPipelineInputAssemblyStateCreateInfo)))
|
||||
if (memcmp(&state.ia, &other.state.ia, sizeof(VkPipelineInputAssemblyStateCreateInfo)))
|
||||
return false;
|
||||
|
||||
if (memcmp(&ds, &other.ds, sizeof(VkPipelineDepthStencilStateCreateInfo)))
|
||||
if (memcmp(&state.ds, &other.state.ds, sizeof(VkPipelineDepthStencilStateCreateInfo)))
|
||||
return false;
|
||||
|
||||
if (num_targets != other.num_targets)
|
||||
@ -58,16 +54,16 @@ namespace rpcs3
|
||||
size_t hash_struct<vk::pipeline_props>(const vk::pipeline_props &pipelineProperties)
|
||||
{
|
||||
size_t seed = hash_base<int>(pipelineProperties.num_targets);
|
||||
seed ^= hash_struct(pipelineProperties.ia);
|
||||
seed ^= hash_struct(pipelineProperties.ds);
|
||||
seed ^= hash_struct(pipelineProperties.rs);
|
||||
seed ^= hash_struct(pipelineProperties.state.ia);
|
||||
seed ^= hash_struct(pipelineProperties.state.ds);
|
||||
seed ^= hash_struct(pipelineProperties.state.rs);
|
||||
|
||||
//Do not compare pointers to memory!
|
||||
auto tmp = pipelineProperties.cs;
|
||||
auto tmp = pipelineProperties.state.cs;
|
||||
tmp.pAttachments = nullptr;
|
||||
seed ^= hash_struct(tmp);
|
||||
|
||||
seed ^= hash_struct(pipelineProperties.att_state[0]);
|
||||
seed ^= hash_struct(pipelineProperties.state.att_state[0]);
|
||||
return hash_base<size_t>(seed);
|
||||
}
|
||||
}
|
||||
@ -99,17 +95,16 @@ struct VKTraits
|
||||
void validate_pipeline_properties(const VKVertexProgram&, const VKFragmentProgram &fp, vk::pipeline_props& properties)
|
||||
{
|
||||
//Explicitly disable writing to undefined registers
|
||||
properties.att_state[0].colorWriteMask &= fp.output_color_masks[0];
|
||||
properties.att_state[1].colorWriteMask &= fp.output_color_masks[1];
|
||||
properties.att_state[2].colorWriteMask &= fp.output_color_masks[2];
|
||||
properties.att_state[3].colorWriteMask &= fp.output_color_masks[3];
|
||||
properties.state.att_state[0].colorWriteMask &= fp.output_color_masks[0];
|
||||
properties.state.att_state[1].colorWriteMask &= fp.output_color_masks[1];
|
||||
properties.state.att_state[2].colorWriteMask &= fp.output_color_masks[2];
|
||||
properties.state.att_state[3].colorWriteMask &= fp.output_color_masks[3];
|
||||
}
|
||||
|
||||
static
|
||||
pipeline_storage_type build_pipeline(const vertex_program_type &vertexProgramData, const fragment_program_type &fragmentProgramData,
|
||||
const vk::pipeline_props &pipelineProperties, VkDevice dev, VkPipelineLayout common_pipeline_layout)
|
||||
{
|
||||
|
||||
VkPipelineShaderStageCreateInfo shader_stages[2] = {};
|
||||
shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
@ -151,12 +146,12 @@ struct VKTraits
|
||||
VkGraphicsPipelineCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.pVertexInputState = &vi;
|
||||
info.pInputAssemblyState = &pipelineProperties.ia;
|
||||
info.pRasterizationState = &pipelineProperties.rs;
|
||||
info.pColorBlendState = &pipelineProperties.cs;
|
||||
info.pInputAssemblyState = &pipelineProperties.state.ia;
|
||||
info.pRasterizationState = &pipelineProperties.state.rs;
|
||||
info.pColorBlendState = &pipelineProperties.state.cs;
|
||||
info.pMultisampleState = &ms;
|
||||
info.pViewportState = &vp;
|
||||
info.pDepthStencilState = &pipelineProperties.ds;
|
||||
info.pDepthStencilState = &pipelineProperties.state.ds;
|
||||
info.stageCount = 2;
|
||||
info.pStages = shader_stages;
|
||||
info.pDynamicState = &dynamic_state_info;
|
||||
@ -208,7 +203,7 @@ public:
|
||||
{
|
||||
//Extract pointers from pipeline props
|
||||
props.render_pass = m_render_pass_data[props.render_pass_location];
|
||||
props.cs.pAttachments = props.att_state;
|
||||
props.state.cs.pAttachments = props.state.att_state;
|
||||
vp.skip_vertex_input_check = true;
|
||||
getGraphicPipelineState(vp, fp, props, std::forward<Args>(args)...);
|
||||
}
|
||||
|
@ -456,8 +456,8 @@ namespace rsx
|
||||
static inline u32 get_g8b8_r8g8_colormask(u32 mask)
|
||||
{
|
||||
u32 result = 0;
|
||||
if (mask & 0x40) result |= 0x40;
|
||||
if (mask & 0x80) result |= 0x20;
|
||||
if (mask & 0x20) result |= 0x20;
|
||||
if (mask & 0x40) result |= 0x10;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user