mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-19 21:40:43 +00:00
rsx: Fix vertex attrib parsing
This commit is contained in:
parent
dab30c0051
commit
f72157bcec
@ -218,6 +218,14 @@ void GLGSRender::end()
|
|||||||
//Do vertex upload before RTT prep / texture lookups to give the driver time to push data
|
//Do vertex upload before RTT prep / texture lookups to give the driver time to push data
|
||||||
auto upload_info = set_vertex_buffer();
|
auto upload_info = set_vertex_buffer();
|
||||||
|
|
||||||
|
if (upload_info.vertex_draw_count == 0)
|
||||||
|
{
|
||||||
|
// Malformed vertex setup; abort
|
||||||
|
do_heap_cleanup();
|
||||||
|
rsx::thread::end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Check if depth buffer is bound and valid
|
//Check if depth buffer is bound and valid
|
||||||
//If ds is not initialized clear it; it seems new depth textures should have depth cleared
|
//If ds is not initialized clear it; it seems new depth textures should have depth cleared
|
||||||
auto copy_rtt_contents = [this](gl::render_target *surface, bool is_depth)
|
auto copy_rtt_contents = [this](gl::render_target *surface, bool is_depth)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "GLGSRender.h"
|
#include "GLGSRender.h"
|
||||||
#include "../rsx_methods.h"
|
#include "../rsx_methods.h"
|
||||||
#include "../Common/BufferUtils.h"
|
#include "../Common/BufferUtils.h"
|
||||||
@ -158,7 +158,7 @@ namespace
|
|||||||
|
|
||||||
vertex_input_state operator()(const rsx::draw_inlined_array& command)
|
vertex_input_state operator()(const rsx::draw_inlined_array& command)
|
||||||
{
|
{
|
||||||
const u32 vertex_count = m_vertex_layout.interleaved_blocks[0].locations.size() ? ((u32)command.inline_vertex_array.size() * sizeof(u32)) / m_vertex_layout.interleaved_blocks[0].attribute_stride : 0;
|
const u32 vertex_count = (u32)(command.inline_vertex_array.size() * sizeof(u32)) / m_vertex_layout.interleaved_blocks[0].attribute_stride;
|
||||||
|
|
||||||
if (!gl::is_primitive_native(rsx::method_registers.current_draw_clause.primitive))
|
if (!gl::is_primitive_native(rsx::method_registers.current_draw_clause.primitive))
|
||||||
{
|
{
|
||||||
@ -186,6 +186,9 @@ gl::vertex_upload_info GLGSRender::set_vertex_buffer()
|
|||||||
|
|
||||||
m_vertex_layout = analyse_inputs_interleaved();
|
m_vertex_layout = analyse_inputs_interleaved();
|
||||||
|
|
||||||
|
if (!m_vertex_layout.validate())
|
||||||
|
return {};
|
||||||
|
|
||||||
//Write index buffers and count verts
|
//Write index buffers and count verts
|
||||||
auto result = std::visit(draw_command_visitor(*m_index_ring_buffer, m_vertex_layout), get_draw_command(rsx::method_registers));
|
auto result = std::visit(draw_command_visitor(*m_index_ring_buffer, m_vertex_layout), get_draw_command(rsx::method_registers));
|
||||||
|
|
||||||
|
@ -1776,10 +1776,6 @@ namespace rsx
|
|||||||
|
|
||||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
{
|
{
|
||||||
// Check if vertex stream is enabled
|
|
||||||
if (!(input_mask & (1 << index)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto &vinfo = state.vertex_arrays_info[index];
|
auto &vinfo = state.vertex_arrays_info[index];
|
||||||
|
|
||||||
if (vinfo.size() > 0)
|
if (vinfo.size() > 0)
|
||||||
|
@ -204,6 +204,39 @@ namespace rsx
|
|||||||
std::vector<u8> referenced_registers; // Volatile register data
|
std::vector<u8> referenced_registers; // Volatile register data
|
||||||
|
|
||||||
std::array<attribute_buffer_placement, 16> attribute_placement;
|
std::array<attribute_buffer_placement, 16> attribute_placement;
|
||||||
|
|
||||||
|
vertex_input_layout()
|
||||||
|
{
|
||||||
|
attribute_placement.fill(attribute_buffer_placement::none);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validate() const
|
||||||
|
{
|
||||||
|
switch (attribute_placement[0])
|
||||||
|
{
|
||||||
|
case attribute_buffer_placement::transient:
|
||||||
|
{
|
||||||
|
if (!referenced_registers.empty() && referenced_registers.front() == 0)
|
||||||
|
{
|
||||||
|
// ATTR[0] is position which cannot be from a register
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The source is inline array or immediate draw push buffer
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case attribute_buffer_placement::persistent:
|
||||||
|
{
|
||||||
|
// Attribute stride cannot be 0, proper packing stride is computed elsewhere
|
||||||
|
verify(HERE), (!interleaved_blocks.empty() && interleaved_blocks[0].attribute_stride != 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case attribute_buffer_placement::none:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct framebuffer_layout
|
struct framebuffer_layout
|
||||||
|
@ -1364,6 +1364,13 @@ void VKGSRender::end()
|
|||||||
std::chrono::time_point<steady_clock> vertex_end = steady_clock::now();
|
std::chrono::time_point<steady_clock> vertex_end = steady_clock::now();
|
||||||
m_vertex_upload_time += std::chrono::duration_cast<std::chrono::microseconds>(vertex_end - vertex_start).count();
|
m_vertex_upload_time += std::chrono::duration_cast<std::chrono::microseconds>(vertex_end - vertex_start).count();
|
||||||
|
|
||||||
|
if (!upload_info.vertex_draw_count)
|
||||||
|
{
|
||||||
|
// Malformed vertex setup; abort
|
||||||
|
rsx::thread::end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Load program execution environment
|
// Load program execution environment
|
||||||
program_start = vertex_end;
|
program_start = vertex_end;
|
||||||
load_program_env(upload_info);
|
load_program_env(upload_info);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Memory/vm.h"
|
#include "Emu/Memory/vm.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "VKGSRender.h"
|
#include "VKGSRender.h"
|
||||||
@ -212,7 +212,7 @@ namespace
|
|||||||
auto &draw_clause = rsx::method_registers.current_draw_clause;
|
auto &draw_clause = rsx::method_registers.current_draw_clause;
|
||||||
VkPrimitiveTopology prims = vk::get_appropriate_topology(draw_clause.primitive, primitives_emulated);
|
VkPrimitiveTopology prims = vk::get_appropriate_topology(draw_clause.primitive, primitives_emulated);
|
||||||
|
|
||||||
const u32 vertex_count = m_vertex_layout.interleaved_blocks[0].locations.size() ? ((u32)command.inline_vertex_array.size() * sizeof(u32)) / m_vertex_layout.interleaved_blocks[0].attribute_stride : 0;
|
const u32 vertex_count = ((u32)command.inline_vertex_array.size() * sizeof(u32)) / m_vertex_layout.interleaved_blocks[0].attribute_stride;
|
||||||
|
|
||||||
if (!primitives_emulated)
|
if (!primitives_emulated)
|
||||||
{
|
{
|
||||||
@ -235,6 +235,9 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data()
|
|||||||
{
|
{
|
||||||
m_vertex_layout = analyse_inputs_interleaved();
|
m_vertex_layout = analyse_inputs_interleaved();
|
||||||
|
|
||||||
|
if (!m_vertex_layout.validate())
|
||||||
|
return {};
|
||||||
|
|
||||||
draw_command_visitor visitor(m_index_buffer_ring_info, m_vertex_layout);
|
draw_command_visitor visitor(m_index_buffer_ring_info, m_vertex_layout);
|
||||||
auto result = std::visit(visitor, get_draw_command(rsx::method_registers));
|
auto result = std::visit(visitor, get_draw_command(rsx::method_registers));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user