rsx: Vertex array attributes don't need to be stored outside of regs.

This commit is contained in:
vlj 2016-08-26 15:46:44 +02:00
parent a64053fd68
commit 11858dce1a
7 changed files with 90 additions and 92 deletions

View File

@ -49,12 +49,11 @@ namespace
D3D12_SHADER_RESOURCE_VIEW_DESC get_vertex_attribute_srv(const rsx::data_array_format_info &info, UINT64 offset_in_vertex_buffers_buffer, UINT buffer_size) D3D12_SHADER_RESOURCE_VIEW_DESC get_vertex_attribute_srv(const rsx::data_array_format_info &info, UINT64 offset_in_vertex_buffers_buffer, UINT buffer_size)
{ {
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size); u32 element_size = rsx::get_vertex_type_size_on_host(info.type(), info.size());
D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = { D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {
get_vertex_attribute_format(info.type, info.size), get_vertex_attribute_format(info.type(), info.size()),
D3D12_SRV_DIMENSION_BUFFER, D3D12_SRV_DIMENSION_BUFFER,
get_component_mapping_from_vector_size(info.size) get_component_mapping_from_vector_size(info.size())};
};
vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size; vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size;
vertex_buffer_view.Buffer.NumElements = buffer_size / element_size; vertex_buffer_view.Buffer.NumElements = buffer_size / element_size;
return vertex_buffer_view; return vertex_buffer_view;
@ -186,10 +185,10 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
{ {
initial_offsets[index++] = stride; initial_offsets[index++] = stride;
if (!info.size) // disabled if (!info.size()) // disabled
continue; continue;
stride += rsx::get_vertex_type_size_on_host(info.type, info.size); stride += rsx::get_vertex_type_size_on_host(info.type(), info.size());
} }
u32 element_count = ::narrow<u32>(inlined_array_raw_data.size_bytes()) / stride; u32 element_count = ::narrow<u32>(inlined_array_raw_data.size_bytes()) / stride;
@ -199,13 +198,13 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
index = 0; index = 0;
for (const auto &info : vertex_attribute_infos) for (const auto &info : vertex_attribute_infos)
{ {
if (!info.size) if (!info.size())
{ {
index++; index++;
continue; continue;
} }
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size); u32 element_size = rsx::get_vertex_type_size_on_host(info.type(), info.size());
UINT buffer_size = element_size * element_count; UINT buffer_size = element_size * element_count;
size_t heap_offset = ring_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size); size_t heap_offset = ring_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
@ -216,7 +215,7 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
{ {
auto subdst = dst.subspan(i * element_size, element_size); auto subdst = dst.subspan(i * element_size, element_size);
auto subsrc = inlined_array_raw_data.subspan(initial_offsets[index] + (i * stride), element_size); auto subsrc = inlined_array_raw_data.subspan(initial_offsets[index] + (i * stride), element_size);
if (info.type == rsx::vertex_base_type::ub && info.size == 4) if (info.type() == rsx::vertex_base_type::ub && info.size() == 4)
{ {
subdst[0] = subsrc[3]; subdst[0] = subsrc[3];
subdst[1] = subsrc[2]; subdst[1] = subsrc[2];

View File

@ -214,7 +214,7 @@ std::tuple<u32, std::optional<std::tuple<GLenum, u32> > > GLGSRender::set_vertex
for (u8 index = 0; index < rsx::limits::vertex_count; ++index) for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
{ {
if (rsx::method_registers.vertex_arrays_info[index].size || rsx::method_registers.register_vertex_info[index].size) if (rsx::method_registers.vertex_arrays_info[index].size() || rsx::method_registers.register_vertex_info[index].size)
{ {
max_vertex_attrib_size += 16; max_vertex_attrib_size += 16;
} }
@ -412,10 +412,10 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32
for (u32 i = 0; i < rsx::limits::vertex_count; ++i) for (u32 i = 0; i < rsx::limits::vertex_count; ++i)
{ {
const auto &info = rsx::method_registers.vertex_arrays_info[i]; const auto &info = rsx::method_registers.vertex_arrays_info[i];
if (!info.size) continue; if (!info.size()) continue;
offsets[i] = stride; offsets[i] = stride;
stride += rsx::get_vertex_type_size_on_host(info.type, info.size); stride += rsx::get_vertex_type_size_on_host(info.type(), info.size());
} }
u32 vertex_draw_count = (u32)(inline_vertex_array.size() * sizeof(u32)) / stride; u32 vertex_draw_count = (u32)(inline_vertex_array.size() * sizeof(u32)) / stride;
@ -429,7 +429,7 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32
if (!m_program->uniforms.has_location(s_reg_table[index], &location)) if (!m_program->uniforms.has_location(s_reg_table[index], &location))
continue; continue;
if (!vertex_info.size) // disabled, bind a null sampler if (!vertex_info.size()) // disabled, bind a null sampler
{ {
glActiveTexture(GL_TEXTURE0 + index + texture_index_offset); glActiveTexture(GL_TEXTURE0 + index + texture_index_offset);
glBindTexture(GL_TEXTURE_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, 0);
@ -437,9 +437,9 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32
continue; continue;
} }
const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size); const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type(), vertex_info.size());
u32 data_size = element_size * vertex_draw_count; u32 data_size = element_size * vertex_draw_count;
u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size); u32 gl_type = to_gl_internal_type(vertex_info.type(), vertex_info.size());
auto &texture = m_gl_attrib_buffers[index]; auto &texture = m_gl_attrib_buffers[index];
@ -448,12 +448,12 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32
u8 *dst = static_cast<u8*>(mapping.first); u8 *dst = static_cast<u8*>(mapping.first);
src += offsets[index]; src += offsets[index];
prepare_buffer_for_writing(dst, vertex_info.type, vertex_info.size, vertex_draw_count); prepare_buffer_for_writing(dst, vertex_info.type(), vertex_info.size(), vertex_draw_count);
//TODO: properly handle compressed data //TODO: properly handle compressed data
for (u32 i = 0; i < vertex_draw_count; ++i) for (u32 i = 0; i < vertex_draw_count; ++i)
{ {
if (vertex_info.type == rsx::vertex_base_type::ub && vertex_info.size == 4) if (vertex_info.type() == rsx::vertex_base_type::ub && vertex_info.size() == 4)
{ {
dst[0] = src[3]; dst[0] = src[3];
dst[1] = src[2]; dst[1] = src[2];

View File

@ -531,12 +531,12 @@ namespace rsx
{ {
const auto &info = rsx::method_registers.vertex_arrays_info[index]; const auto &info = rsx::method_registers.vertex_arrays_info[index];
if (!info.size) // disabled if (!info.size()) // disabled
continue; continue;
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size); u32 element_size = rsx::get_vertex_type_size_on_host(info.type(), info.size());
if (info.type == vertex_base_type::ub && info.size == 4) if (info.type() == vertex_base_type::ub && info.size() == 4)
{ {
dst[0] = src[3]; dst[0] = src[3];
dst[1] = src[2]; dst[1] = src[2];
@ -587,7 +587,7 @@ namespace rsx
u32 offset = vertex_array_info.offset(); u32 offset = vertex_array_info.offset();
u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31); u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31);
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_array_info.type, vertex_array_info.size); u32 element_size = rsx::get_vertex_type_size_on_host(vertex_array_info.type(), vertex_array_info.size());
// Disjoint first_counts ranges not supported atm // Disjoint first_counts ranges not supported atm
for (int i = 0; i < vertex_ranges.size() - 1; i++) for (int i = 0; i < vertex_ranges.size() - 1; i++)
@ -600,7 +600,7 @@ namespace rsx
u32 count = std::get<0>(vertex_ranges.back()) + std::get<1>(vertex_ranges.back()) - first; u32 count = std::get<0>(vertex_ranges.back()) + std::get<1>(vertex_ranges.back()) - first;
const gsl::byte* ptr = gsl::narrow_cast<const gsl::byte*>(vm::base(address)); const gsl::byte* ptr = gsl::narrow_cast<const gsl::byte*>(vm::base(address));
return {ptr + first * vertex_array_info.stride, count * vertex_array_info.stride + element_size}; return {ptr + first * vertex_array_info.stride(), count * vertex_array_info.stride() + element_size};
} }
std::vector<std::variant<vertex_array_buffer, vertex_array_register, empty_vertex_array>> thread::get_vertex_buffers(const rsx::rsx_state& state, const std::vector<std::pair<u32, u32>>& vertex_ranges) const std::vector<std::variant<vertex_array_buffer, vertex_array_register, empty_vertex_array>> thread::get_vertex_buffers(const rsx::rsx_state& state, const std::vector<std::pair<u32, u32>>& vertex_ranges) const
@ -613,10 +613,10 @@ namespace rsx
if (!enabled) if (!enabled)
continue; continue;
if (state.vertex_arrays_info[index].size > 0) if (state.vertex_arrays_info[index].size() > 0)
{ {
const rsx::data_array_format_info& info = state.vertex_arrays_info[index]; const rsx::data_array_format_info& info = state.vertex_arrays_info[index];
result.push_back(vertex_array_buffer{info.type, info.size, info.stride, result.push_back(vertex_array_buffer{info.type(), info.size(), info.stride(),
get_raw_vertex_buffer(info, state.vertex_data_base_offset(), vertex_ranges), index}); get_raw_vertex_buffer(info, state.vertex_data_base_offset(), vertex_ranges), index});
continue; continue;
} }
@ -760,31 +760,25 @@ namespace rsx
if (!enabled) if (!enabled)
continue; continue;
if (rsx::method_registers.vertex_arrays_info[index].size > 0) if (rsx::method_registers.vertex_arrays_info[index].size() > 0)
{ {
result.rsx_vertex_inputs.push_back( result.rsx_vertex_inputs.push_back(
{ {index,
index, rsx::method_registers.vertex_arrays_info[index].size(),
rsx::method_registers.vertex_arrays_info[index].size, rsx::method_registers.vertex_arrays_info[index].frequency(),
rsx::method_registers.vertex_arrays_info[index].frequency, !!((modulo_mask >> index) & 0x1),
!!((modulo_mask >> index) & 0x1), true,
true, is_int_type(rsx::method_registers.vertex_arrays_info[index].type())});
is_int_type(rsx::method_registers.vertex_arrays_info[index].type)
}
);
} }
else if (rsx::method_registers.register_vertex_info[index].size > 0) else if (rsx::method_registers.register_vertex_info[index].size > 0)
{ {
result.rsx_vertex_inputs.push_back( result.rsx_vertex_inputs.push_back(
{ {index,
index, rsx::method_registers.register_vertex_info[index].size,
rsx::method_registers.register_vertex_info[index].size, rsx::method_registers.register_vertex_info[index].frequency,
rsx::method_registers.register_vertex_info[index].frequency, !!((modulo_mask >> index) & 0x1),
!!((modulo_mask >> index) & 0x1), false,
false, is_int_type(rsx::method_registers.vertex_arrays_info[index].type())});
is_int_type(rsx::method_registers.vertex_arrays_info[index].type)
}
);
} }
} }
return result; return result;
@ -843,10 +837,10 @@ namespace rsx
{ {
bool is_int = false; bool is_int = false;
if (rsx::method_registers.vertex_arrays_info[index].size > 0) if (rsx::method_registers.vertex_arrays_info[index].size() > 0)
{ {
is_int = is_int_type(rsx::method_registers.vertex_arrays_info[index].type); is_int = is_int_type(rsx::method_registers.vertex_arrays_info[index].type());
result.state.frequency[index] = rsx::method_registers.vertex_arrays_info[index].frequency; result.state.frequency[index] = rsx::method_registers.vertex_arrays_info[index].frequency();
} }
else if (rsx::method_registers.register_vertex_info[index].size > 0) else if (rsx::method_registers.register_vertex_info[index].size > 0)
{ {

View File

@ -388,10 +388,10 @@ u32 VKGSRender::upload_inlined_array()
for (u32 i = 0; i < rsx::limits::vertex_count; ++i) for (u32 i = 0; i < rsx::limits::vertex_count; ++i)
{ {
const auto &info = rsx::method_registers.vertex_arrays_info[i]; const auto &info = rsx::method_registers.vertex_arrays_info[i];
if (!info.size) continue; if (!info.size()) continue;
offsets[i] = stride; offsets[i] = stride;
stride += rsx::get_vertex_type_size_on_host(info.type, info.size); stride += rsx::get_vertex_type_size_on_host(info.type(), info.size());
} }
u32 vertex_draw_count = (u32)(inline_vertex_array.size() * sizeof(u32)) / stride; u32 vertex_draw_count = (u32)(inline_vertex_array.size() * sizeof(u32)) / stride;
@ -403,48 +403,48 @@ u32 VKGSRender::upload_inlined_array()
if (!m_program->has_uniform(s_reg_table[index])) if (!m_program->has_uniform(s_reg_table[index]))
continue; continue;
if (!vertex_info.size) // disabled if (!vertex_info.size()) // disabled
{ {
continue; continue;
} }
const u32 element_size = vk::get_suitable_vk_size(vertex_info.type, vertex_info.size); const u32 element_size = vk::get_suitable_vk_size(vertex_info.type(), vertex_info.size());
const u32 data_size = element_size * vertex_draw_count; const u32 data_size = element_size * vertex_draw_count;
const VkFormat format = vk::get_suitable_vk_format(vertex_info.type, vertex_info.size); const VkFormat format = vk::get_suitable_vk_format(vertex_info.type(), vertex_info.size());
u32 offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(data_size); u32 offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(data_size);
u8 *src = reinterpret_cast<u8*>(inline_vertex_array.data()); u8 *src = reinterpret_cast<u8*>(inline_vertex_array.data());
u8 *dst = static_cast<u8*>(m_attrib_ring_info.map(offset_in_attrib_buffer, data_size)); u8 *dst = static_cast<u8*>(m_attrib_ring_info.map(offset_in_attrib_buffer, data_size));
src += offsets[index]; src += offsets[index];
u8 opt_size = vertex_info.size; u8 opt_size = vertex_info.size();
if (vertex_info.size == 3) if (vertex_info.size() == 3)
opt_size = 4; opt_size = 4;
//TODO: properly handle cmp type //TODO: properly handle cmp type
if (vertex_info.type == rsx::vertex_base_type::cmp) if (vertex_info.type() == rsx::vertex_base_type::cmp)
LOG_ERROR(RSX, "Compressed vertex attributes not supported for inlined arrays yet"); LOG_ERROR(RSX, "Compressed vertex attributes not supported for inlined arrays yet");
switch (vertex_info.type) switch (vertex_info.type())
{ {
case rsx::vertex_base_type::f: case rsx::vertex_base_type::f:
vk::copy_inlined_data_to_buffer<float, 1>(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); vk::copy_inlined_data_to_buffer<float, 1>(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride);
break; break;
case rsx::vertex_base_type::sf: case rsx::vertex_base_type::sf:
vk::copy_inlined_data_to_buffer<u16, 0x3c00>(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); vk::copy_inlined_data_to_buffer<u16, 0x3c00>(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride);
break; break;
case rsx::vertex_base_type::s1: case rsx::vertex_base_type::s1:
case rsx::vertex_base_type::ub: case rsx::vertex_base_type::ub:
case rsx::vertex_base_type::ub256: case rsx::vertex_base_type::ub256:
vk::copy_inlined_data_to_buffer<u8, 1>(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); vk::copy_inlined_data_to_buffer<u8, 1>(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride);
break; break;
case rsx::vertex_base_type::s32k: case rsx::vertex_base_type::s32k:
case rsx::vertex_base_type::cmp: case rsx::vertex_base_type::cmp:
vk::copy_inlined_data_to_buffer<u16, 1>(src, dst, vertex_draw_count, vertex_info.type, vertex_info.size, opt_size, element_size, stride); vk::copy_inlined_data_to_buffer<u16, 1>(src, dst, vertex_draw_count, vertex_info.type(), vertex_info.size(), opt_size, element_size, stride);
break; break;
default: default:
fmt::throw_exception("Unknown base type %d" HERE, (u32)vertex_info.type); fmt::throw_exception("Unknown base type %d" HERE, (u32)vertex_info.type());
} }
m_attrib_ring_info.unmap(); m_attrib_ring_info.unmap();

View File

@ -185,19 +185,6 @@ namespace rsx
} }
}; };
template<u32 index>
struct set_vertex_data_array_format
{
static void impl(thread* rsx, u32 _reg, u32 arg)
{
const typename rsx::registers_decoder<NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + index>::decoded_type decoded_value(arg);
rsx::method_registers.vertex_arrays_info[index].frequency = decoded_value.frequency();
rsx::method_registers.vertex_arrays_info[index].stride = decoded_value.stride();
rsx::method_registers.vertex_arrays_info[index].size = decoded_value.size();
rsx::method_registers.vertex_arrays_info[index].type = decoded_value.type();
}
};
void draw_arrays(thread* rsx, u32 _reg, u32 arg) void draw_arrays(thread* rsx, u32 _reg, u32 arg)
{ {
rsx::method_registers.current_draw_clause.command = rsx::draw_command::array; rsx::method_registers.current_draw_clause.command = rsx::draw_command::array;
@ -877,7 +864,6 @@ namespace rsx
registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff;
for (auto& info : vertex_arrays_info) info.size = 0;
for (auto& tex : fragment_textures) tex.init(); for (auto& tex : fragment_textures) tex.init();
for (auto& tex : vertex_textures) tex.init(); for (auto& tex : vertex_textures) tex.init();
} }
@ -1275,7 +1261,6 @@ namespace rsx
bind<NV4097_DRAW_ARRAYS, nv4097::draw_arrays>(); bind<NV4097_DRAW_ARRAYS, nv4097::draw_arrays>();
bind<NV4097_DRAW_INDEX_ARRAY, nv4097::draw_index_array>(); bind<NV4097_DRAW_INDEX_ARRAY, nv4097::draw_index_array>();
bind<NV4097_INLINE_ARRAY, nv4097::draw_inline_array>(); bind<NV4097_INLINE_ARRAY, nv4097::draw_inline_array>();
bind_range<NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, 1, 16, nv4097::set_vertex_data_array_format>();
bind_range<NV4097_SET_VERTEX_DATA4UB_M, 1, 16, nv4097::set_vertex_data4ub_m>(); bind_range<NV4097_SET_VERTEX_DATA4UB_M, 1, 16, nv4097::set_vertex_data4ub_m>();
bind_range<NV4097_SET_VERTEX_DATA1F_M, 1, 16, nv4097::set_vertex_data1f_m>(); bind_range<NV4097_SET_VERTEX_DATA1F_M, 1, 16, nv4097::set_vertex_data1f_m>();
bind_range<NV4097_SET_VERTEX_DATA2F_M, 1, 32, nv4097::set_vertex_data2f_m>(); bind_range<NV4097_SET_VERTEX_DATA2F_M, 1, 32, nv4097::set_vertex_data2f_m>();

View File

@ -137,13 +137,6 @@ namespace rsx
transform_program = in.transform_program; transform_program = in.transform_program;
transform_constants = in.transform_constants; transform_constants = in.transform_constants;
register_vertex_info = in.register_vertex_info; register_vertex_info = in.register_vertex_info;
for (int i = 0; i < 16; i++)
{
vertex_arrays_info[i].size = in.vertex_arrays_info[i].size;
vertex_arrays_info[i].stride = in.vertex_arrays_info[i].stride;
vertex_arrays_info[i].frequency = in.vertex_arrays_info[i].frequency;
vertex_arrays_info[i].type = in.vertex_arrays_info[i].type;
}
return *this; return *this;
} }

View File

@ -9,19 +9,46 @@ namespace rsx
struct data_array_format_info struct data_array_format_info
{ {
private: private:
u32& m_offset_register; u8 index;
public: std::array<u32, 0x10000 / 4>& registers;
u16 frequency = 0;
u8 stride = 0;
u8 size = 0;
vertex_base_type type = vertex_base_type::f;
data_array_format_info(int id, std::array<u32, 0x10000 / 4> &registers) auto decode_reg() const
: m_offset_register(registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + id]) {} {
const typename rsx::registers_decoder<NV4097_SET_VERTEX_DATA_ARRAY_FORMAT>::decoded_type
decoded_value(registers[NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + index]);
return decoded_value;
}
public:
data_array_format_info(int id, std::array<u32, 0x10000 / 4>& r)
: registers(r)
, index(id)
{
}
u32 offset() const u32 offset() const
{ {
return m_offset_register; return registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index];
}
u8 stride() const
{
return decode_reg().stride();
}
u8 size() const
{
return decode_reg().size();
}
u16 frequency() const
{
return decode_reg().frequency();
}
vertex_base_type type() const
{
return decode_reg().type();
} }
}; };