rsx: Implement stippled rendering

This commit is contained in:
kd-11 2020-05-29 00:51:36 +03:00 committed by kd-11
parent 3df83e03a9
commit 1677618c75
15 changed files with 153 additions and 10 deletions

View file

@ -430,6 +430,23 @@ namespace glsl
"}\n\n"; "}\n\n";
} }
static void insert_rop_init(std::ostream& OS)
{
OS <<
" if ((rop_control & (1u << 9)) != 0)\n"
" {\n"
" // Convert x,y to linear address\n"
" uvec2 stipple_coord = uvec2(gl_FragCoord.xy) % uvec2(32u, 32u);\n"
" uint address = stipple_coord.y * 32u + stipple_coord.x;\n"
" uint mask = (1u << (address & 31u));\n\n"
" if ((stipple_pattern[address >> 7u][(address >> 5u) & 3u] & mask) == 0u)\n"
" {\n"
" _kill();\n"
" }\n"
" }\n\n";
}
static void insert_rop(std::ostream& OS, const shader_properties& props) static void insert_rop(std::ostream& OS, const shader_properties& props)
{ {
const std::string reg0 = props.fp32_outputs ? "r0" : "h0"; const std::string reg0 = props.fp32_outputs ? "r0" : "h0";

View file

@ -190,6 +190,11 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
OS << "{\n"; OS << "{\n";
OS << " sampler_info texture_parameters[16];\n"; OS << " sampler_info texture_parameters[16];\n";
OS << "};\n\n"; OS << "};\n\n";
OS << "layout(std140, binding = " << GL_RASTERIZER_STATE_BIND_SLOT << ") uniform RasterizerHeap\n";
OS << "{\n";
OS << " uvec4 stipple_pattern[8];\n";
OS << "};\n\n";
} }
void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
@ -303,6 +308,8 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
OS << "void main()\n"; OS << "void main()\n";
OS << "{\n"; OS << "{\n";
::glsl::insert_rop_init(OS);
OS << "\n" << " fs_main();\n\n"; OS << "\n" << " fs_main();\n\n";
glsl::insert_rop(OS, m_shader_props); glsl::insert_rop(OS, m_shader_props);

View file

@ -200,6 +200,7 @@ void GLGSRender::on_init_thread()
m_index_ring_buffer = std::make_unique<gl::legacy_ring_buffer>(); m_index_ring_buffer = std::make_unique<gl::legacy_ring_buffer>();
m_vertex_instructions_buffer = std::make_unique<gl::legacy_ring_buffer>(); m_vertex_instructions_buffer = std::make_unique<gl::legacy_ring_buffer>();
m_fragment_instructions_buffer = std::make_unique<gl::legacy_ring_buffer>(); m_fragment_instructions_buffer = std::make_unique<gl::legacy_ring_buffer>();
m_raster_env_ring_buffer = std::make_unique<gl::legacy_ring_buffer>();
} }
else else
{ {
@ -213,6 +214,7 @@ void GLGSRender::on_init_thread()
m_index_ring_buffer = std::make_unique<gl::ring_buffer>(); m_index_ring_buffer = std::make_unique<gl::ring_buffer>();
m_vertex_instructions_buffer = std::make_unique<gl::ring_buffer>(); m_vertex_instructions_buffer = std::make_unique<gl::ring_buffer>();
m_fragment_instructions_buffer = std::make_unique<gl::ring_buffer>(); m_fragment_instructions_buffer = std::make_unique<gl::ring_buffer>();
m_raster_env_ring_buffer = std::make_unique<gl::ring_buffer>();
} }
m_attrib_ring_buffer->create(gl::buffer::target::texture, 256 * 0x100000); m_attrib_ring_buffer->create(gl::buffer::target::texture, 256 * 0x100000);
@ -223,6 +225,7 @@ void GLGSRender::on_init_thread()
m_vertex_env_buffer->create(gl::buffer::target::uniform, 16 * 0x100000); m_vertex_env_buffer->create(gl::buffer::target::uniform, 16 * 0x100000);
m_texture_parameters_buffer->create(gl::buffer::target::uniform, 16 * 0x100000); m_texture_parameters_buffer->create(gl::buffer::target::uniform, 16 * 0x100000);
m_vertex_layout_buffer->create(gl::buffer::target::uniform, 16 * 0x100000); m_vertex_layout_buffer->create(gl::buffer::target::uniform, 16 * 0x100000);
m_raster_env_ring_buffer->create(gl::buffer::target::uniform, 16 * 0x100000);
if (shadermode == shader_mode::async_with_interpreter || shadermode == shader_mode::interpreter_only) if (shadermode == shader_mode::async_with_interpreter || shadermode == shader_mode::interpreter_only)
{ {
@ -449,6 +452,11 @@ void GLGSRender::on_exit()
m_fragment_instructions_buffer->remove(); m_fragment_instructions_buffer->remove();
} }
if (m_raster_env_ring_buffer)
{
m_raster_env_ring_buffer->remove();
}
m_null_textures.clear(); m_null_textures.clear();
m_text_printer.close(); m_text_printer.close();
m_gl_texture_cache.destroy(); m_gl_texture_cache.destroy();
@ -704,6 +712,7 @@ void GLGSRender::load_program_env()
const bool update_fragment_env = !!(m_graphics_state & rsx::pipeline_state::fragment_state_dirty); const bool update_fragment_env = !!(m_graphics_state & rsx::pipeline_state::fragment_state_dirty);
const bool update_fragment_texture_env = !!(m_graphics_state & rsx::pipeline_state::fragment_texture_state_dirty); const bool update_fragment_texture_env = !!(m_graphics_state & rsx::pipeline_state::fragment_texture_state_dirty);
const bool update_instruction_buffers = (!!m_interpreter_state && m_shader_interpreter.is_interpreter(m_program)); const bool update_instruction_buffers = (!!m_interpreter_state && m_shader_interpreter.is_interpreter(m_program));
const bool update_raster_env = (rsx::method_registers.polygon_stipple_enabled() && !!(m_graphics_state & rsx::pipeline_state::polygon_stipple_pattern_dirty));
m_program->use(); m_program->use();
@ -714,6 +723,7 @@ void GLGSRender::load_program_env()
if (update_fragment_texture_env) m_texture_parameters_buffer->reserve_storage_on_heap(256); if (update_fragment_texture_env) m_texture_parameters_buffer->reserve_storage_on_heap(256);
if (update_fragment_constants) m_fragment_constants_buffer->reserve_storage_on_heap(align(fragment_constants_size, 256)); if (update_fragment_constants) m_fragment_constants_buffer->reserve_storage_on_heap(align(fragment_constants_size, 256));
if (update_transform_constants) m_transform_constants_buffer->reserve_storage_on_heap(8192); if (update_transform_constants) m_transform_constants_buffer->reserve_storage_on_heap(8192);
if (update_raster_env) m_raster_env_ring_buffer->reserve_storage_on_heap(128);
if (update_instruction_buffers) if (update_instruction_buffers)
{ {
@ -779,6 +789,16 @@ void GLGSRender::load_program_env()
m_texture_parameters_buffer->bind_range(GL_FRAGMENT_TEXTURE_PARAMS_BIND_SLOT, mapping.second, 256); m_texture_parameters_buffer->bind_range(GL_FRAGMENT_TEXTURE_PARAMS_BIND_SLOT, mapping.second, 256);
} }
if (update_raster_env)
{
auto mapping = m_raster_env_ring_buffer->alloc_from_heap(128, m_uniform_buffer_offset_align);
std::memcpy(mapping.first, rsx::method_registers.polygon_stipple_pattern(), 128);
m_raster_env_ring_buffer->bind_range(GL_RASTERIZER_STATE_BIND_SLOT, mapping.second, 128);
m_graphics_state &= ~(rsx::pipeline_state::polygon_stipple_pattern_dirty);
}
if (update_instruction_buffers) if (update_instruction_buffers)
{ {
if (m_interpreter_state & rsx::vertex_program_dirty) if (m_interpreter_state & rsx::vertex_program_dirty)
@ -830,6 +850,7 @@ void GLGSRender::load_program_env()
if (update_fragment_texture_env) m_texture_parameters_buffer->unmap(); if (update_fragment_texture_env) m_texture_parameters_buffer->unmap();
if (update_fragment_constants) m_fragment_constants_buffer->unmap(); if (update_fragment_constants) m_fragment_constants_buffer->unmap();
if (update_transform_constants) m_transform_constants_buffer->unmap(); if (update_transform_constants) m_transform_constants_buffer->unmap();
if (update_raster_env) m_raster_env_ring_buffer->unmap();
if (update_instruction_buffers) if (update_instruction_buffers)
{ {

View file

@ -99,6 +99,7 @@ private:
std::unique_ptr<gl::ring_buffer> m_index_ring_buffer; std::unique_ptr<gl::ring_buffer> m_index_ring_buffer;
std::unique_ptr<gl::ring_buffer> m_vertex_instructions_buffer; std::unique_ptr<gl::ring_buffer> m_vertex_instructions_buffer;
std::unique_ptr<gl::ring_buffer> m_fragment_instructions_buffer; std::unique_ptr<gl::ring_buffer> m_fragment_instructions_buffer;
std::unique_ptr<gl::ring_buffer> m_raster_env_ring_buffer;
// Identity buffer used to fix broken gl_VertexID on ATI stack // Identity buffer used to fix broken gl_VertexID on ATI stack
std::unique_ptr<gl::buffer> m_identity_index_buffer; std::unique_ptr<gl::buffer> m_identity_index_buffer;

View file

@ -28,9 +28,10 @@
#define GL_FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT 3 #define GL_FRAGMENT_CONSTANT_BUFFERS_BIND_SLOT 3
#define GL_FRAGMENT_STATE_BIND_SLOT 4 #define GL_FRAGMENT_STATE_BIND_SLOT 4
#define GL_FRAGMENT_TEXTURE_PARAMS_BIND_SLOT 5 #define GL_FRAGMENT_TEXTURE_PARAMS_BIND_SLOT 5
#define GL_INTERPRETER_VERTEX_BLOCK 6 #define GL_RASTERIZER_STATE_BIND_SLOT 6
#define GL_INTERPRETER_FRAGMENT_BLOCK 7 #define GL_INTERPRETER_VERTEX_BLOCK 7
#define GL_COMPUTE_BUFFER_SLOT(index) (index + 8) #define GL_INTERPRETER_FRAGMENT_BLOCK 8
#define GL_COMPUTE_BUFFER_SLOT(index) (index + 9)
// Noop keyword outside of Windows (used in log_debug) // Noop keyword outside of Windows (used in log_debug)
#if !defined(_WIN32) && !defined(APIENTRY) #if !defined(_WIN32) && !defined(APIENTRY)

View file

@ -792,6 +792,11 @@ namespace rsx
} }
} }
if (rsx::method_registers.polygon_stipple_enabled())
{
rop_control |= (1u << 9);
}
// Generate wpos coefficients // Generate wpos coefficients
// wpos equation is now as follows: // wpos equation is now as follows:
// wpos.y = (frag_coord / resolution_scale) * ((window_origin!=top)?-1.: 1.) + ((window_origin!=top)? window_height : 0) // wpos.y = (frag_coord / resolution_scale) * ((window_origin!=top)?-1.: 1.) + ((window_origin!=top)? window_height : 0)

View file

@ -82,6 +82,9 @@ namespace rsx
scissor_setup_invalid = 0x400, // Scissor configuration is broken scissor_setup_invalid = 0x400, // Scissor configuration is broken
scissor_setup_clipped = 0x800, // Scissor region is cropped by viewport constraint scissor_setup_clipped = 0x800, // Scissor region is cropped by viewport constraint
polygon_stipple_pattern_dirty = 0x1000, // Rasterizer stippling pattern changed
line_stipple_pattern_dirty = 0x2000, // Line stippling pattern changed
invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty, invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty,
memory_barrier_bits = framebuffer_reads_dirty, memory_barrier_bits = framebuffer_reads_dirty,
all_dirty = ~0u all_dirty = ~0u

View file

@ -206,6 +206,11 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
OS << " sampler_info texture_parameters[16];\n"; OS << " sampler_info texture_parameters[16];\n";
OS << "};\n\n"; OS << "};\n\n";
OS << "layout(std140, set = 0, binding = " << std::to_string(m_binding_table.rasterizer_env_bind_slot) << ") uniform RasterizerHeap\n";
OS << "{\n";
OS << " uvec4 stipple_pattern[8];\n";
OS << "};\n\n";
vk::glsl::program_input in; vk::glsl::program_input in;
in.location = m_binding_table.fragment_constant_buffers_bind_slot; in.location = m_binding_table.fragment_constant_buffers_bind_slot;
in.domain = glsl::glsl_fragment_program; in.domain = glsl::glsl_fragment_program;
@ -220,6 +225,10 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
in.location = m_binding_table.fragment_texture_params_bind_slot; in.location = m_binding_table.fragment_texture_params_bind_slot;
in.name = "TextureParametersBuffer"; in.name = "TextureParametersBuffer";
inputs.push_back(in); inputs.push_back(in);
in.location = m_binding_table.rasterizer_env_bind_slot;
in.name = "RasterizerHeap";
inputs.push_back(in);
} }
void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
@ -333,6 +342,8 @@ void VKFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
OS << "void main()\n"; OS << "void main()\n";
OS << "{\n"; OS << "{\n";
::glsl::insert_rop_init(OS);
OS << "\n" << " fs_main();\n\n"; OS << "\n" << " fs_main();\n\n";
glsl::insert_rop(OS, m_shader_props); glsl::insert_rop(OS, m_shader_props);

View file

@ -279,6 +279,13 @@ namespace
idx++; idx++;
bindings[idx].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
bindings[idx].descriptorCount = 1;
bindings[idx].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[idx].binding = binding_table.rasterizer_env_bind_slot;
idx++;
for (auto binding = binding_table.textures_first_bind_slot; for (auto binding = binding_table.textures_first_bind_slot;
binding < binding_table.vertex_textures_first_bind_slot; binding < binding_table.vertex_textures_first_bind_slot;
binding++) binding++)
@ -464,6 +471,7 @@ VKGSRender::VKGSRender() : GSRender()
m_transform_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer"); m_transform_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer");
m_index_buffer_ring_info.create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer"); m_index_buffer_ring_info.create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer");
m_texture_upload_buffer_ring_info.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, "texture upload buffer", 32 * 0x100000); m_texture_upload_buffer_ring_info.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, "texture upload buffer", 32 * 0x100000);
m_raster_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "raster env buffer");
const auto shadermode = g_cfg.video.shadermode.get(); const auto shadermode = g_cfg.video.shadermode.get();
@ -473,6 +481,9 @@ VKGSRender::VKGSRender() : GSRender()
m_fragment_instructions_buffer.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 64 * 0x100000, "fragment instructions buffer", 2048); m_fragment_instructions_buffer.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 64 * 0x100000, "fragment instructions buffer", 2048);
} }
// Initiailize optional allocation information with placeholders
m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, 0, 128 };
const auto limits = m_device->gpu().get_limits(); const auto limits = m_device->gpu().get_limits();
m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000u); m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000u);
@ -606,6 +617,7 @@ VKGSRender::~VKGSRender()
m_texture_upload_buffer_ring_info.destroy(); m_texture_upload_buffer_ring_info.destroy();
m_vertex_instructions_buffer.destroy(); m_vertex_instructions_buffer.destroy();
m_fragment_instructions_buffer.destroy(); m_fragment_instructions_buffer.destroy();
m_raster_env_ring_info.destroy();
//Fallback bindables //Fallback bindables
null_buffer.reset(); null_buffer.reset();
@ -806,7 +818,8 @@ void VKGSRender::check_heap_status(u32 flags)
m_vertex_layout_ring_info.is_critical() || m_vertex_layout_ring_info.is_critical() ||
m_fragment_constants_ring_info.is_critical() || m_fragment_constants_ring_info.is_critical() ||
m_transform_constants_ring_info.is_critical() || m_transform_constants_ring_info.is_critical() ||
m_index_buffer_ring_info.is_critical(); m_index_buffer_ring_info.is_critical() ||
m_raster_env_ring_info.is_critical();
} }
else if (flags) else if (flags)
{ {
@ -829,7 +842,7 @@ void VKGSRender::check_heap_status(u32 flags)
heap_critical = m_vertex_env_ring_info.is_critical(); heap_critical = m_vertex_env_ring_info.is_critical();
break; break;
case VK_HEAP_CHECK_FRAGMENT_ENV_STORAGE: case VK_HEAP_CHECK_FRAGMENT_ENV_STORAGE:
heap_critical = m_fragment_env_ring_info.is_critical(); heap_critical = m_fragment_env_ring_info.is_critical() || m_raster_env_ring_info.is_critical();
break; break;
case VK_HEAP_CHECK_TEXTURE_ENV_STORAGE: case VK_HEAP_CHECK_TEXTURE_ENV_STORAGE:
heap_critical = m_fragment_texture_params_ring_info.is_critical(); heap_critical = m_fragment_texture_params_ring_info.is_critical();
@ -880,6 +893,7 @@ void VKGSRender::check_heap_status(u32 flags)
m_transform_constants_ring_info.reset_allocation_stats(); m_transform_constants_ring_info.reset_allocation_stats();
m_attrib_ring_info.reset_allocation_stats(); m_attrib_ring_info.reset_allocation_stats();
m_texture_upload_buffer_ring_info.reset_allocation_stats(); m_texture_upload_buffer_ring_info.reset_allocation_stats();
m_raster_env_ring_info.reset_allocation_stats();
m_current_frame->reset_heap_ptrs(); m_current_frame->reset_heap_ptrs();
m_last_heap_sync_time = get_system_time(); m_last_heap_sync_time = get_system_time();
} }
@ -1652,6 +1666,7 @@ void VKGSRender::load_program_env()
const bool update_fragment_env = !!(m_graphics_state & rsx::pipeline_state::fragment_state_dirty); const bool update_fragment_env = !!(m_graphics_state & rsx::pipeline_state::fragment_state_dirty);
const bool update_fragment_texture_env = !!(m_graphics_state & rsx::pipeline_state::fragment_texture_state_dirty); const bool update_fragment_texture_env = !!(m_graphics_state & rsx::pipeline_state::fragment_texture_state_dirty);
const bool update_instruction_buffers = (!!m_interpreter_state && m_shader_interpreter.is_interpreter(m_program)); const bool update_instruction_buffers = (!!m_interpreter_state && m_shader_interpreter.is_interpreter(m_program));
const bool update_raster_env = (rsx::method_registers.polygon_stipple_enabled() && !!(m_graphics_state & rsx::pipeline_state::polygon_stipple_pattern_dirty));
if (update_vertex_env) if (update_vertex_env)
{ {
@ -1731,6 +1746,20 @@ void VKGSRender::load_program_env()
m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, mem, 256 }; m_fragment_texture_params_buffer_info = { m_fragment_texture_params_ring_info.heap->value, mem, 256 };
} }
if (update_raster_env)
{
check_heap_status(VK_HEAP_CHECK_FRAGMENT_ENV_STORAGE);
auto mem = m_raster_env_ring_info.alloc<256>(256);
auto buf = m_raster_env_ring_info.map(mem, 128);
std::memcpy(buf, rsx::method_registers.polygon_stipple_pattern(), 128);
m_raster_env_ring_info.unmap();
m_raster_env_buffer_info = { m_raster_env_ring_info.heap->value, mem, 128 };
m_graphics_state &= ~(rsx::pipeline_state::polygon_stipple_pattern_dirty);
}
if (update_instruction_buffers) if (update_instruction_buffers)
{ {
if (m_interpreter_state & rsx::vertex_program_dirty) if (m_interpreter_state & rsx::vertex_program_dirty)
@ -1778,6 +1807,7 @@ void VKGSRender::load_program_env()
m_program->bind_uniform(m_vertex_constants_buffer_info, binding_table.vertex_constant_buffers_bind_slot, m_current_frame->descriptor_set); m_program->bind_uniform(m_vertex_constants_buffer_info, binding_table.vertex_constant_buffers_bind_slot, m_current_frame->descriptor_set);
m_program->bind_uniform(m_fragment_env_buffer_info, binding_table.fragment_state_bind_slot, m_current_frame->descriptor_set); m_program->bind_uniform(m_fragment_env_buffer_info, binding_table.fragment_state_bind_slot, m_current_frame->descriptor_set);
m_program->bind_uniform(m_fragment_texture_params_buffer_info, binding_table.fragment_texture_params_bind_slot, m_current_frame->descriptor_set); m_program->bind_uniform(m_fragment_texture_params_buffer_info, binding_table.fragment_texture_params_bind_slot, m_current_frame->descriptor_set);
m_program->bind_uniform(m_raster_env_buffer_info, binding_table.rasterizer_env_bind_slot, m_current_frame->descriptor_set);
if (!m_shader_interpreter.is_interpreter(m_program)) if (!m_shader_interpreter.is_interpreter(m_program))
{ {
@ -1869,7 +1899,8 @@ void VKGSRender::close_and_submit_command_buffer(vk::fence* pFence, VkSemaphore
m_fragment_constants_ring_info.dirty() || m_fragment_constants_ring_info.dirty() ||
m_index_buffer_ring_info.dirty() || m_index_buffer_ring_info.dirty() ||
m_transform_constants_ring_info.dirty() || m_transform_constants_ring_info.dirty() ||
m_texture_upload_buffer_ring_info.dirty()) m_texture_upload_buffer_ring_info.dirty() ||
m_raster_env_ring_info.dirty())
{ {
std::lock_guard lock(m_secondary_cb_guard); std::lock_guard lock(m_secondary_cb_guard);
m_secondary_command_buffer.begin(); m_secondary_command_buffer.begin();
@ -1883,6 +1914,7 @@ void VKGSRender::close_and_submit_command_buffer(vk::fence* pFence, VkSemaphore
m_index_buffer_ring_info.sync(m_secondary_command_buffer); m_index_buffer_ring_info.sync(m_secondary_command_buffer);
m_transform_constants_ring_info.sync(m_secondary_command_buffer); m_transform_constants_ring_info.sync(m_secondary_command_buffer);
m_texture_upload_buffer_ring_info.sync(m_secondary_command_buffer); m_texture_upload_buffer_ring_info.sync(m_secondary_command_buffer);
m_raster_env_ring_info.sync(m_secondary_command_buffer);
m_secondary_command_buffer.end(); m_secondary_command_buffer.end();

View file

@ -208,6 +208,7 @@ namespace vk
s64 frag_texparam_heap_ptr = 0; s64 frag_texparam_heap_ptr = 0;
s64 index_heap_ptr = 0; s64 index_heap_ptr = 0;
s64 texture_upload_heap_ptr = 0; s64 texture_upload_heap_ptr = 0;
s64 rasterizer_env_heap_ptr = 0;
u64 last_frame_sync_time = 0; u64 last_frame_sync_time = 0;
@ -230,6 +231,7 @@ namespace vk
vtx_const_heap_ptr = other.vtx_const_heap_ptr; vtx_const_heap_ptr = other.vtx_const_heap_ptr;
index_heap_ptr = other.index_heap_ptr; index_heap_ptr = other.index_heap_ptr;
texture_upload_heap_ptr = other.texture_upload_heap_ptr; texture_upload_heap_ptr = other.texture_upload_heap_ptr;
rasterizer_env_heap_ptr = other.rasterizer_env_heap_ptr;
} }
//Exchange storage (non-copyable) //Exchange storage (non-copyable)
@ -238,7 +240,10 @@ namespace vk
std::swap(buffer_views_to_clean, other.buffer_views_to_clean); std::swap(buffer_views_to_clean, other.buffer_views_to_clean);
} }
void tag_frame_end(s64 attrib_loc, s64 vtxenv_loc, s64 fragenv_loc, s64 vtxlayout_loc, s64 fragtex_loc, s64 fragconst_loc,s64 vtxconst_loc, s64 index_loc, s64 texture_loc) void tag_frame_end(
s64 attrib_loc, s64 vtxenv_loc, s64 fragenv_loc, s64 vtxlayout_loc,
s64 fragtex_loc, s64 fragconst_loc,s64 vtxconst_loc, s64 index_loc,
s64 texture_loc, s64 rasterizer_loc)
{ {
attrib_heap_ptr = attrib_loc; attrib_heap_ptr = attrib_loc;
vtx_env_heap_ptr = vtxenv_loc; vtx_env_heap_ptr = vtxenv_loc;
@ -249,6 +254,7 @@ namespace vk
vtx_const_heap_ptr = vtxconst_loc; vtx_const_heap_ptr = vtxconst_loc;
index_heap_ptr = index_loc; index_heap_ptr = index_loc;
texture_upload_heap_ptr = texture_loc; texture_upload_heap_ptr = texture_loc;
rasterizer_env_heap_ptr = rasterizer_loc;
last_frame_sync_time = get_system_time(); last_frame_sync_time = get_system_time();
} }
@ -425,6 +431,7 @@ private:
vk::data_heap m_vertex_layout_ring_info; // Vertex layout structure vk::data_heap m_vertex_layout_ring_info; // Vertex layout structure
vk::data_heap m_index_buffer_ring_info; // Index data vk::data_heap m_index_buffer_ring_info; // Index data
vk::data_heap m_texture_upload_buffer_ring_info; // Texture upload heap vk::data_heap m_texture_upload_buffer_ring_info; // Texture upload heap
vk::data_heap m_raster_env_ring_info; // Raster control such as polygon and line stipple
vk::data_heap m_fragment_instructions_buffer; vk::data_heap m_fragment_instructions_buffer;
vk::data_heap m_vertex_instructions_buffer; vk::data_heap m_vertex_instructions_buffer;
@ -435,6 +442,7 @@ private:
VkDescriptorBufferInfo m_vertex_constants_buffer_info; VkDescriptorBufferInfo m_vertex_constants_buffer_info;
VkDescriptorBufferInfo m_fragment_constants_buffer_info; VkDescriptorBufferInfo m_fragment_constants_buffer_info;
VkDescriptorBufferInfo m_fragment_texture_params_buffer_info; VkDescriptorBufferInfo m_fragment_texture_params_buffer_info;
VkDescriptorBufferInfo m_raster_env_buffer_info;
VkDescriptorBufferInfo m_vertex_instructions_buffer_info; VkDescriptorBufferInfo m_vertex_instructions_buffer_info;
VkDescriptorBufferInfo m_fragment_instructions_buffer_info; VkDescriptorBufferInfo m_fragment_instructions_buffer_info;

View file

@ -245,8 +245,9 @@ namespace vk
u8 fragment_texture_params_bind_slot = 4; u8 fragment_texture_params_bind_slot = 4;
u8 vertex_buffers_first_bind_slot = 5; u8 vertex_buffers_first_bind_slot = 5;
u8 conditional_render_predicate_slot = 8; u8 conditional_render_predicate_slot = 8;
u8 textures_first_bind_slot = 9; u8 rasterizer_env_bind_slot = 9;
u8 vertex_textures_first_bind_slot = 9; // Invalid, has to be initialized properly u8 textures_first_bind_slot = 10;
u8 vertex_textures_first_bind_slot = 10; // Invalid, has to be initialized properly
u8 total_descriptor_bindings = vertex_textures_first_bind_slot; // Invalid, has to be initialized properly u8 total_descriptor_bindings = vertex_textures_first_bind_slot; // Invalid, has to be initialized properly
}; };

View file

@ -122,7 +122,8 @@ void VKGSRender::advance_queued_frames()
m_fragment_constants_ring_info.get_current_put_pos_minus_one(), m_fragment_constants_ring_info.get_current_put_pos_minus_one(),
m_transform_constants_ring_info.get_current_put_pos_minus_one(), m_transform_constants_ring_info.get_current_put_pos_minus_one(),
m_index_buffer_ring_info.get_current_put_pos_minus_one(), m_index_buffer_ring_info.get_current_put_pos_minus_one(),
m_texture_upload_buffer_ring_info.get_current_put_pos_minus_one()); m_texture_upload_buffer_ring_info.get_current_put_pos_minus_one(),
m_raster_env_ring_info.get_current_put_pos_minus_one());
m_queued_frames.push_back(m_current_frame); m_queued_frames.push_back(m_current_frame);
verify(HERE), m_queued_frames.size() <= VK_MAX_ASYNC_FRAMES; verify(HERE), m_queued_frames.size() <= VK_MAX_ASYNC_FRAMES;

View file

@ -4074,6 +4074,29 @@ struct registers_decoder<NV4097_SET_TRANSFORM_CONSTANT_LOAD>
} }
}; };
template<>
struct registers_decoder<NV4097_SET_POLYGON_STIPPLE>
{
struct decoded_type
{
private:
u32 value;
public:
decoded_type(u32 value) : value(value) {}
bool enabled() const
{
return value > 0;
}
};
static std::string dump(decoded_type&& decoded_values)
{
return std::string("polygon_stipple: ") + (decoded_values.enabled()? "true" : "false");
}
};
#define EXPAND_RANGE_1(index, MACRO) \ #define EXPAND_RANGE_1(index, MACRO) \
MACRO(index) MACRO(index)

View file

@ -3120,6 +3120,8 @@ namespace rsx
bind_range<NV4097_SET_VIEWPORT_OFFSET, 1, 3, nv4097::set_viewport_dirty_bit>(); bind_range<NV4097_SET_VIEWPORT_OFFSET, 1, 3, nv4097::set_viewport_dirty_bit>();
bind<NV4097_SET_INDEX_ARRAY_DMA, nv4097::check_index_array_dma>(); bind<NV4097_SET_INDEX_ARRAY_DMA, nv4097::check_index_array_dma>();
bind<NV4097_SET_BLEND_EQUATION, nv4097::set_blend_equation>(); bind<NV4097_SET_BLEND_EQUATION, nv4097::set_blend_equation>();
bind<NV4097_SET_POLYGON_STIPPLE, nv4097::notify_state_changed<fragment_state_dirty>>();
bind_array<NV4097_SET_POLYGON_STIPPLE, 1, 32, nv4097::notify_state_changed<polygon_stipple_pattern_dirty>>();
//NV308A (0xa400..0xbffc!) //NV308A (0xa400..0xbffc!)
bind_range<NV308A_COLOR + (256 * 0), 1, 256, nv308a::color, 256 * 0>(); bind_range<NV308A_COLOR + (256 * 0), 1, 256, nv308a::color, 256 * 0>();

View file

@ -1706,6 +1706,16 @@ namespace rsx
{ {
return decode<NV4097_SET_POINT_SPRITE_CONTROL>().texcoord_mask(); return decode<NV4097_SET_POINT_SPRITE_CONTROL>().texcoord_mask();
} }
const void* polygon_stipple_pattern() const
{
return registers.data() + NV4097_SET_POLYGON_STIPPLE_PATTERN;
}
bool polygon_stipple_enabled() const
{
return decode<NV4097_SET_POLYGON_STIPPLE>().enabled();
}
}; };
extern rsx_state method_registers; extern rsx_state method_registers;