rsx: Use a "draw clause" object in rsx_state.

This commit is contained in:
Vincent Lejeune 2016-08-04 19:59:50 +02:00
parent d646fbb94f
commit eb1d4811de
11 changed files with 102 additions and 106 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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 =
{

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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];

View File

@ -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())
{

View File

@ -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;

View File

@ -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();
}

View File

@ -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.