mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-14 01:27:00 +00:00
rsx: Use a "draw clause" object in rsx_state.
This commit is contained in:
parent
d646fbb94f
commit
eb1d4811de
@ -303,7 +303,7 @@ std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer
|
||||
{
|
||||
size_t index_count = 0;
|
||||
for (const auto &pair : vertex_ranges)
|
||||
index_count += get_index_count(draw_mode, pair.second);
|
||||
index_count += get_index_count(rsx::method_registers.current_draw_clause.primitive, pair.second);
|
||||
|
||||
// Alloc
|
||||
size_t buffer_size = align(index_count * sizeof(u16), 64);
|
||||
@ -313,8 +313,8 @@ std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer
|
||||
size_t first = 0;
|
||||
for (const auto &pair : vertex_ranges)
|
||||
{
|
||||
size_t element_count = get_index_count(draw_mode, pair.second);
|
||||
write_index_array_for_non_indexed_non_native_primitive_to_buffer((char*)mapped_buffer, draw_mode, (u32)first, (u32)pair.second);
|
||||
size_t element_count = get_index_count(rsx::method_registers.current_draw_clause.primitive, pair.second);
|
||||
write_index_array_for_non_indexed_non_native_primitive_to_buffer((char*)mapped_buffer, rsx::method_registers.current_draw_clause.primitive, (u32)first, (u32)pair.second);
|
||||
mapped_buffer = (char*)mapped_buffer + element_count * sizeof(u16);
|
||||
first += pair.second;
|
||||
}
|
||||
@ -330,7 +330,7 @@ std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer
|
||||
|
||||
std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRender::upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *command_list)
|
||||
{
|
||||
if (draw_command == rsx::draw_command::inlined_array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array)
|
||||
{
|
||||
size_t vertex_count;
|
||||
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> vertex_buffer_view;
|
||||
@ -339,7 +339,7 @@ std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRe
|
||||
{ (const gsl::byte*) inline_vertex_array.data(), gsl::narrow<int>(inline_vertex_array.size() * sizeof(uint)) },
|
||||
m_buffer_data, m_vertex_buffer_data.Get(), command_list);
|
||||
|
||||
if (is_primitive_native(draw_mode))
|
||||
if (is_primitive_native(rsx::method_registers.current_draw_clause.primitive))
|
||||
return std::make_tuple(false, vertex_count, vertex_buffer_view);
|
||||
|
||||
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
|
||||
@ -349,25 +349,25 @@ std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRe
|
||||
return std::make_tuple(true, index_count, vertex_buffer_view);
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array)
|
||||
{
|
||||
if (is_primitive_native(draw_mode))
|
||||
if (is_primitive_native(rsx::method_registers.current_draw_clause.primitive))
|
||||
{
|
||||
size_t vertex_count = get_vertex_count(first_count_commands);
|
||||
return std::make_tuple(false, vertex_count, upload_vertex_attributes(first_count_commands, command_list));
|
||||
size_t vertex_count = get_vertex_count(rsx::method_registers.current_draw_clause.first_count_commands);
|
||||
return std::make_tuple(false, vertex_count, upload_vertex_attributes(rsx::method_registers.current_draw_clause.first_count_commands, command_list));
|
||||
}
|
||||
|
||||
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
|
||||
size_t index_count;
|
||||
std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array(first_count_commands);
|
||||
std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array(rsx::method_registers.current_draw_clause.first_count_commands);
|
||||
command_list->IASetIndexBuffer(&index_buffer_view);
|
||||
return std::make_tuple(true, index_count, upload_vertex_attributes(first_count_commands, command_list));
|
||||
return std::make_tuple(true, index_count, upload_vertex_attributes(rsx::method_registers.current_draw_clause.first_count_commands, command_list));
|
||||
}
|
||||
|
||||
EXPECTS(draw_command == rsx::draw_command::indexed);
|
||||
EXPECTS(rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed);
|
||||
|
||||
// Index count
|
||||
size_t index_count = get_index_count(draw_mode, gsl::narrow<int>(get_vertex_count(first_count_commands)));
|
||||
size_t index_count = get_index_count(rsx::method_registers.current_draw_clause.primitive, gsl::narrow<int>(get_vertex_count(rsx::method_registers.current_draw_clause.first_count_commands)));
|
||||
|
||||
rsx::index_array_type indexed_type = rsx::method_registers.index_type();
|
||||
size_t index_size = get_index_type_size(indexed_type);
|
||||
@ -380,8 +380,8 @@ std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRe
|
||||
u32 min_index, max_index;
|
||||
gsl::span<gsl::byte> dst{ reinterpret_cast<gsl::byte*>(mapped_buffer), gsl::narrow<u32>(buffer_size) };
|
||||
|
||||
std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, get_raw_index_array(first_count_commands),
|
||||
indexed_type, draw_mode, rsx::method_registers.restart_index_enabled(), rsx::method_registers.restart_index(), first_count_commands,
|
||||
std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, get_raw_index_array(rsx::method_registers.current_draw_clause.first_count_commands),
|
||||
indexed_type, rsx::method_registers.current_draw_clause.primitive, rsx::method_registers.restart_index_enabled(), rsx::method_registers.restart_index(), rsx::method_registers.current_draw_clause.first_count_commands,
|
||||
[](auto prim) { return !is_primitive_native(prim); });
|
||||
|
||||
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
|
@ -442,7 +442,7 @@ void D3D12GSRender::end()
|
||||
get_current_resource_storage().command_list->RSSetScissorRects(1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(),
|
||||
rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height()));
|
||||
|
||||
get_current_resource_storage().command_list->IASetPrimitiveTopology(get_primitive_topology(draw_mode));
|
||||
get_current_resource_storage().command_list->IASetPrimitiveTopology(get_primitive_topology(rsx::method_registers.current_draw_clause.primitive));
|
||||
|
||||
if (indexed_draw)
|
||||
get_current_resource_storage().command_list->DrawIndexedInstanced((UINT)vertex_count, 1, 0, 0, 0);
|
||||
|
@ -44,7 +44,7 @@ void D3D12GSRender::load_program()
|
||||
m_fragment_program = get_current_fragment_program();
|
||||
|
||||
D3D12PipelineProperties prop = {};
|
||||
prop.Topology = get_primitive_topology_type(draw_mode);
|
||||
prop.Topology = get_primitive_topology_type(rsx::method_registers.current_draw_clause.primitive);
|
||||
|
||||
static D3D12_BLEND_DESC CD3D12_BLEND_DESC =
|
||||
{
|
||||
|
@ -497,30 +497,30 @@ void GLGSRender::end()
|
||||
m_program->validate();
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed)
|
||||
{
|
||||
rsx::index_array_type indexed_type = rsx::method_registers.index_type();
|
||||
|
||||
if (indexed_type == rsx::index_array_type::u32)
|
||||
{
|
||||
__glcheck glDrawElements(gl::draw_mode(draw_mode), vertex_draw_count, GL_UNSIGNED_INT, (GLvoid *)(std::ptrdiff_t)offset_in_index_buffer);
|
||||
__glcheck glDrawElements(gl::draw_mode(rsx::method_registers.current_draw_clause.primitive), vertex_draw_count, GL_UNSIGNED_INT, (GLvoid *)(std::ptrdiff_t)offset_in_index_buffer);
|
||||
}
|
||||
else if (indexed_type == rsx::index_array_type::u16)
|
||||
{
|
||||
__glcheck glDrawElements(gl::draw_mode(draw_mode), vertex_draw_count, GL_UNSIGNED_SHORT, (GLvoid *)(std::ptrdiff_t)offset_in_index_buffer);
|
||||
__glcheck glDrawElements(gl::draw_mode(rsx::method_registers.current_draw_clause.primitive), vertex_draw_count, GL_UNSIGNED_SHORT, (GLvoid *)(std::ptrdiff_t)offset_in_index_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::logic_error("bad index array type");
|
||||
}
|
||||
}
|
||||
else if (!gl::is_primitive_native(draw_mode))
|
||||
else if (!gl::is_primitive_native(rsx::method_registers.current_draw_clause.primitive))
|
||||
{
|
||||
__glcheck glDrawElements(gl::draw_mode(draw_mode), vertex_draw_count, GL_UNSIGNED_SHORT, (GLvoid *)(std::ptrdiff_t)offset_in_index_buffer);
|
||||
__glcheck glDrawElements(gl::draw_mode(rsx::method_registers.current_draw_clause.primitive), vertex_draw_count, GL_UNSIGNED_SHORT, (GLvoid *)(std::ptrdiff_t)offset_in_index_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_fbo.draw_arrays(draw_mode, vertex_draw_count);
|
||||
draw_fbo.draw_arrays(rsx::method_registers.current_draw_clause.primitive, vertex_draw_count);
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
|
||||
|
@ -199,27 +199,24 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed)
|
||||
{
|
||||
rsx::index_array_type type = rsx::method_registers.index_type();
|
||||
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
|
||||
|
||||
for (const auto& first_count : first_count_commands)
|
||||
{
|
||||
vertex_draw_count += first_count.second;
|
||||
}
|
||||
vertex_draw_count += rsx::method_registers.current_draw_clause.get_elements_count();
|
||||
|
||||
u32 max_size = get_index_count(draw_mode, vertex_draw_count) * type_size;
|
||||
u32 max_size = get_index_count(rsx::method_registers.current_draw_clause.primitive, vertex_draw_count) * type_size;
|
||||
auto mapping = m_index_ring_buffer.alloc_and_map(max_size);
|
||||
void *ptr = mapping.first;
|
||||
offset_in_index_buffer = mapping.second;
|
||||
|
||||
std::tie(min_index, max_index, vertex_draw_count) = upload_index_buffer(get_raw_index_array(first_count_commands), ptr, type, draw_mode, first_count_commands, vertex_draw_count);
|
||||
std::tie(min_index, max_index, vertex_draw_count) = upload_index_buffer(get_raw_index_array(rsx::method_registers.current_draw_clause.first_count_commands), ptr, type, rsx::method_registers.current_draw_clause.primitive, rsx::method_registers.current_draw_clause.first_count_commands, vertex_draw_count);
|
||||
|
||||
m_index_ring_buffer.unmap();
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::inlined_array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array)
|
||||
{
|
||||
u32 stride = 0;
|
||||
u32 offsets[rsx::limits::vertex_count] = { 0 };
|
||||
@ -287,22 +284,19 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
//Link texture to uniform
|
||||
m_program->uniforms.texture(location, index + texture_index_offset, texture);
|
||||
|
||||
if (!gl::is_primitive_native(draw_mode))
|
||||
if (!gl::is_primitive_native(rsx::method_registers.current_draw_clause.primitive))
|
||||
{
|
||||
std::tie(vertex_draw_count, offset_in_index_buffer) = get_index_array_for_emulated_non_indexed_draw({ { 0, vertex_draw_count } }, draw_mode, m_index_ring_buffer);
|
||||
std::tie(vertex_draw_count, offset_in_index_buffer) = get_index_array_for_emulated_non_indexed_draw({ { 0, vertex_draw_count } }, rsx::method_registers.current_draw_clause.primitive, m_index_ring_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array)
|
||||
{
|
||||
for (const auto &first_count : first_count_commands)
|
||||
{
|
||||
vertex_draw_count += first_count.second;
|
||||
}
|
||||
vertex_draw_count += rsx::method_registers.current_draw_clause.get_elements_count();
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::array || draw_command == rsx::draw_command::indexed)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array || rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed)
|
||||
{
|
||||
u32 verts_allocated = std::max(vertex_draw_count, max_index + 1);
|
||||
__glcheck m_attrib_ring_buffer.reserve_and_map(verts_allocated * max_vertex_attrib_size);
|
||||
@ -342,7 +336,7 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31);
|
||||
const gsl::byte *src_ptr = gsl::narrow_cast<const gsl::byte*>(vm::base(address));
|
||||
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array)
|
||||
{
|
||||
auto mapping = m_attrib_ring_buffer.alloc_from_reserve(data_size, m_min_texbuffer_alignment);
|
||||
gsl::byte *dst = static_cast<gsl::byte*>(mapping.first);
|
||||
@ -352,14 +346,14 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
gsl::span<gsl::byte> dest_span(dst, data_size);
|
||||
prepare_buffer_for_writing(dst, vertex_info.type, vertex_info.size, vertex_draw_count);
|
||||
|
||||
for (const auto &first_count : first_count_commands)
|
||||
for (const auto &first_count : rsx::method_registers.current_draw_clause.first_count_commands)
|
||||
{
|
||||
write_vertex_array_data_to_buffer(dest_span.subspan(offset), src_ptr, first_count.first, first_count.second, vertex_info.type, vertex_info.size, vertex_info.stride, rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size));
|
||||
offset += first_count.second * element_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed)
|
||||
{
|
||||
data_size = (max_index + 1) * element_size;
|
||||
auto mapping = m_attrib_ring_buffer.alloc_from_reserve(data_size, m_min_texbuffer_alignment);
|
||||
@ -415,9 +409,9 @@ u32 GLGSRender::set_vertex_buffer()
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::array && !gl::is_primitive_native(draw_mode))
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array && !gl::is_primitive_native(rsx::method_registers.current_draw_clause.primitive))
|
||||
{
|
||||
std::tie(vertex_draw_count, offset_in_index_buffer) = get_index_array_for_emulated_non_indexed_draw(first_count_commands, draw_mode, m_index_ring_buffer);
|
||||
std::tie(vertex_draw_count, offset_in_index_buffer) = get_index_array_for_emulated_non_indexed_draw(rsx::method_registers.current_draw_clause.first_count_commands, rsx::method_registers.current_draw_clause.primitive, m_index_ring_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,14 +311,11 @@ namespace rsx
|
||||
draw_state.color_buffer = std::move(copy_render_targets_to_memory());
|
||||
draw_state.depth_stencil = std::move(copy_depth_stencil_buffer_to_memory());
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
if (draw_state.state.current_draw_clause.command == rsx::draw_command::indexed)
|
||||
{
|
||||
draw_state.vertex_count = 0;
|
||||
for (const auto &range : first_count_commands)
|
||||
{
|
||||
draw_state.vertex_count += range.second;
|
||||
}
|
||||
auto index_raw_data_ptr = get_raw_index_array(first_count_commands);
|
||||
draw_state.vertex_count = draw_state.state.current_draw_clause.get_elements_count();
|
||||
auto index_raw_data_ptr = get_raw_index_array(draw_state.state.current_draw_clause.first_count_commands);
|
||||
draw_state.index.resize(index_raw_data_ptr.size_bytes());
|
||||
std::copy(index_raw_data_ptr.begin(), index_raw_data_ptr.end(), draw_state.index.begin());
|
||||
}
|
||||
@ -332,9 +329,6 @@ namespace rsx
|
||||
{
|
||||
draw_inline_vertex_array = false;
|
||||
inline_vertex_array.clear();
|
||||
first_count_commands.clear();
|
||||
draw_command = rsx::draw_command::none;
|
||||
draw_mode = method_registers.primitive_mode();
|
||||
}
|
||||
|
||||
void thread::end()
|
||||
@ -349,13 +343,8 @@ namespace rsx
|
||||
|
||||
if (capture_current_frame)
|
||||
{
|
||||
for (const auto &first_count : first_count_commands)
|
||||
{
|
||||
vertex_draw_count += first_count.second;
|
||||
}
|
||||
|
||||
capture_frame("Draw " + std::to_string(vertex_draw_count));
|
||||
vertex_draw_count = 0;
|
||||
u32 element_count = rsx::method_registers.current_draw_clause.get_elements_count();
|
||||
capture_frame("Draw " + rsx::to_string(rsx::method_registers.current_draw_clause.primitive) + std::to_string(element_count));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,14 +143,6 @@ namespace rsx
|
||||
}
|
||||
};
|
||||
|
||||
enum class draw_command
|
||||
{
|
||||
none,
|
||||
array,
|
||||
inlined_array,
|
||||
indexed,
|
||||
};
|
||||
|
||||
class thread : public named_thread
|
||||
{
|
||||
std::shared_ptr<thread_ctrl> m_vblank_thread;
|
||||
@ -171,11 +163,6 @@ namespace rsx
|
||||
|
||||
u32 vertex_draw_count = 0;
|
||||
|
||||
/**
|
||||
* Stores the first and count argument from draw/draw indexed parameters between begin/end clauses.
|
||||
*/
|
||||
std::vector<std::pair<u32, u32> > first_count_commands;
|
||||
|
||||
// Constant stored for whole frame
|
||||
std::unordered_map<u32, color4f> local_transform_constants;
|
||||
|
||||
@ -198,8 +185,6 @@ namespace rsx
|
||||
u32 gcm_current_buffer;
|
||||
u32 ctxt_addr;
|
||||
u32 label_addr;
|
||||
rsx::draw_command draw_command;
|
||||
primitive_type draw_mode;
|
||||
|
||||
u32 local_mem_addr, main_mem_addr;
|
||||
bool strict_ordering[0x1000];
|
||||
|
@ -854,7 +854,7 @@ bool VKGSRender::load_program()
|
||||
|
||||
properties.ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
bool unused;
|
||||
properties.ia.topology = vk::get_appropriate_topology(draw_mode, unused);
|
||||
properties.ia.topology = vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, unused);
|
||||
|
||||
if (rsx::method_registers.restart_index_enabled())
|
||||
{
|
||||
|
@ -246,42 +246,36 @@ VKGSRender::upload_vertex_data()
|
||||
vertex_draw_count = 0;
|
||||
u32 min_index, max_index;
|
||||
|
||||
bool is_indexed_draw = (draw_command == rsx::draw_command::indexed);
|
||||
bool is_indexed_draw = (rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed);
|
||||
bool primitives_emulated = false;
|
||||
u32 index_count = 0;
|
||||
|
||||
VkIndexType index_format = VK_INDEX_TYPE_UINT16;
|
||||
VkPrimitiveTopology prims = vk::get_appropriate_topology(draw_mode, primitives_emulated);
|
||||
VkPrimitiveTopology prims = vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, primitives_emulated);
|
||||
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array)
|
||||
{
|
||||
for (const auto &first_count : first_count_commands)
|
||||
{
|
||||
vertex_draw_count += first_count.second;
|
||||
}
|
||||
vertex_draw_count += rsx::method_registers.current_draw_clause.get_elements_count();
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed || primitives_emulated)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed || primitives_emulated)
|
||||
{
|
||||
rsx::index_array_type type = rsx::method_registers.index_type();
|
||||
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
|
||||
|
||||
if (is_indexed_draw) //Could be emulated or not, emulated array vertex count already computed above
|
||||
{
|
||||
for (const auto& first_count : first_count_commands)
|
||||
{
|
||||
vertex_draw_count += first_count.second;
|
||||
}
|
||||
vertex_draw_count += rsx::method_registers.current_draw_clause.get_elements_count();
|
||||
}
|
||||
|
||||
index_count = vertex_draw_count;
|
||||
u32 upload_size = vertex_draw_count * type_size;
|
||||
|
||||
std::vector<std::pair<u32, u32>> ranges = first_count_commands;
|
||||
std::vector<std::pair<u32, u32>> ranges = rsx::method_registers.current_draw_clause.first_count_commands;
|
||||
|
||||
if (primitives_emulated)
|
||||
{
|
||||
index_count = get_index_count(draw_mode, vertex_draw_count);
|
||||
index_count = get_index_count(rsx::method_registers.current_draw_clause.primitive, vertex_draw_count);
|
||||
upload_size = index_count * sizeof(u16);
|
||||
|
||||
if (is_indexed_draw)
|
||||
@ -294,13 +288,13 @@ VKGSRender::upload_vertex_data()
|
||||
offset_in_index_buffer = m_index_buffer_ring_info.alloc<256>(upload_size);
|
||||
void* buf = m_index_buffer_ring_info.map(offset_in_index_buffer, upload_size);
|
||||
|
||||
std::tie(min_index, max_index, index_format) = vk::upload_index_buffer(get_raw_index_array(ranges), draw_mode, type, buf, is_indexed_draw, vertex_draw_count, index_count, ranges);
|
||||
std::tie(min_index, max_index, index_format) = vk::upload_index_buffer(get_raw_index_array(ranges), rsx::method_registers.current_draw_clause.primitive, type, buf, is_indexed_draw, vertex_draw_count, index_count, ranges);
|
||||
|
||||
m_index_buffer_ring_info.unmap();
|
||||
is_indexed_draw = true;
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::inlined_array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array)
|
||||
{
|
||||
u32 stride = 0;
|
||||
u32 offsets[rsx::limits::vertex_count] = { 0 };
|
||||
@ -373,7 +367,7 @@ VKGSRender::upload_vertex_data()
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::array || draw_command == rsx::draw_command::indexed)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array || rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed)
|
||||
{
|
||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
@ -407,7 +401,7 @@ VKGSRender::upload_vertex_data()
|
||||
|
||||
u32 num_stored_verts = vertex_draw_count;
|
||||
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::array)
|
||||
{
|
||||
size_t offset = 0;
|
||||
offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(upload_size);
|
||||
@ -416,7 +410,7 @@ VKGSRender::upload_vertex_data()
|
||||
|
||||
gsl::span<gsl::byte> dest_span(static_cast<gsl::byte*>(dst), upload_size);
|
||||
|
||||
for (const auto &first_count : first_count_commands)
|
||||
for (const auto &first_count : rsx::method_registers.current_draw_clause.first_count_commands)
|
||||
{
|
||||
write_vertex_array_data_to_buffer(dest_span.subspan(offset), src_ptr, first_count.first, first_count.second, vertex_info.type, vertex_info.size, vertex_info.stride, real_element_size);
|
||||
offset += first_count.second * real_element_size;
|
||||
@ -425,7 +419,7 @@ VKGSRender::upload_vertex_data()
|
||||
m_attrib_ring_info.unmap();
|
||||
}
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::indexed)
|
||||
{
|
||||
num_stored_verts = (max_index + 1);
|
||||
upload_size = real_element_size * num_stored_verts;
|
||||
|
@ -200,25 +200,25 @@ namespace rsx
|
||||
|
||||
void draw_arrays(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
rsx->draw_command = rsx::draw_command::array;
|
||||
rsx::method_registers.current_draw_clause.command = rsx::draw_command::array;
|
||||
u32 first = arg & 0xffffff;
|
||||
u32 count = (arg >> 24) + 1;
|
||||
|
||||
rsx->first_count_commands.emplace_back(std::make_pair(first, count));
|
||||
rsx::method_registers.current_draw_clause.first_count_commands.emplace_back(std::make_pair(first, count));
|
||||
}
|
||||
|
||||
void draw_index_array(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
rsx->draw_command = rsx::draw_command::indexed;
|
||||
rsx::method_registers.current_draw_clause.command = rsx::draw_command::indexed;
|
||||
u32 first = arg & 0xffffff;
|
||||
u32 count = (arg >> 24) + 1;
|
||||
|
||||
rsx->first_count_commands.emplace_back(std::make_pair(first, count));
|
||||
rsx::method_registers.current_draw_clause.first_count_commands.emplace_back(std::make_pair(first, count));
|
||||
}
|
||||
|
||||
void draw_inline_array(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
rsx->draw_command = rsx::draw_command::inlined_array;
|
||||
rsx::method_registers.current_draw_clause.command = rsx::draw_command::inlined_array;
|
||||
rsx->draw_inline_vertex_array = true;
|
||||
rsx->inline_vertex_array.push_back(arg);
|
||||
}
|
||||
@ -250,6 +250,9 @@ namespace rsx
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
rsx::method_registers.current_draw_clause.first_count_commands.clear();
|
||||
rsx::method_registers.current_draw_clause.command = draw_command::none;
|
||||
rsx::method_registers.current_draw_clause.primitive = rsx::method_registers.primitive_mode();
|
||||
rsxthr->begin();
|
||||
return;
|
||||
}
|
||||
@ -267,20 +270,20 @@ namespace rsx
|
||||
|
||||
vertex_info.frequency = element_count;
|
||||
|
||||
if (rsxthr->draw_command == rsx::draw_command::none)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::none)
|
||||
{
|
||||
max_vertex_count = std::max<u32>(max_vertex_count, element_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rsxthr->draw_command == rsx::draw_command::none && max_vertex_count)
|
||||
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::none && max_vertex_count)
|
||||
{
|
||||
rsxthr->draw_command = rsx::draw_command::array;
|
||||
rsxthr->first_count_commands.push_back(std::make_pair(0, max_vertex_count));
|
||||
rsx::method_registers.current_draw_clause.command = rsx::draw_command::array;
|
||||
rsx::method_registers.current_draw_clause.first_count_commands.push_back(std::make_pair(0, max_vertex_count));
|
||||
}
|
||||
|
||||
if (!(rsxthr->first_count_commands.empty() && rsxthr->inline_vertex_array.empty()))
|
||||
if (!(rsx::method_registers.current_draw_clause.first_count_commands.empty() && rsxthr->inline_vertex_array.empty()))
|
||||
{
|
||||
rsxthr->end();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <numeric>
|
||||
|
||||
#include "GCM.h"
|
||||
#include "rsx_decode.h"
|
||||
@ -14,6 +15,34 @@
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
enum class draw_command
|
||||
{
|
||||
none,
|
||||
array,
|
||||
inlined_array,
|
||||
indexed,
|
||||
};
|
||||
|
||||
struct draw_clause
|
||||
{
|
||||
primitive_type primitive;
|
||||
draw_command command;
|
||||
|
||||
/**
|
||||
* Stores the first and count argument from draw/draw indexed parameters between begin/end clauses.
|
||||
*/
|
||||
std::vector<std::pair<u32, u32> > first_count_commands;
|
||||
|
||||
/**
|
||||
* Returns how many vertex or index will be consumed by the draw clause.
|
||||
*/
|
||||
u32 get_elements_count() const
|
||||
{
|
||||
return std::accumulate(first_count_commands.begin(), first_count_commands.end(), 0,
|
||||
[](u32 acc, auto b) { return acc + b.second; });
|
||||
}
|
||||
};
|
||||
|
||||
using rsx_method_t = void(*)(class thread*, u32 reg, u32 arg);
|
||||
|
||||
//TODO
|
||||
@ -125,6 +154,8 @@ namespace rsx
|
||||
std::array<u32, 512 * 4> transform_program;
|
||||
std::unordered_map<u32, color4_base<f32>> transform_constants;
|
||||
|
||||
draw_clause current_draw_clause;
|
||||
|
||||
/**
|
||||
* RSX can sources vertex attributes from 2 places:
|
||||
* - Immediate values passed by NV4097_SET_VERTEX_DATA*_M + ARRAY_ID write.
|
||||
|
Loading…
x
Reference in New Issue
Block a user