mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-14 01:27:00 +00:00
rsx: Vertex array attributes don't need to be stored outside of regs.
This commit is contained in:
parent
a64053fd68
commit
11858dce1a
@ -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)
|
||||
{
|
||||
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 = {
|
||||
get_vertex_attribute_format(info.type, info.size),
|
||||
D3D12_SRV_DIMENSION_BUFFER,
|
||||
get_component_mapping_from_vector_size(info.size)
|
||||
};
|
||||
get_vertex_attribute_format(info.type(), info.size()),
|
||||
D3D12_SRV_DIMENSION_BUFFER,
|
||||
get_component_mapping_from_vector_size(info.size())};
|
||||
vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size;
|
||||
vertex_buffer_view.Buffer.NumElements = buffer_size / element_size;
|
||||
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;
|
||||
|
||||
if (!info.size) // disabled
|
||||
if (!info.size()) // disabled
|
||||
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;
|
||||
@ -199,13 +198,13 @@ std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_
|
||||
index = 0;
|
||||
for (const auto &info : vertex_attribute_infos)
|
||||
{
|
||||
if (!info.size)
|
||||
if (!info.size())
|
||||
{
|
||||
index++;
|
||||
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;
|
||||
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 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[1] = subsrc[2];
|
||||
|
@ -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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
const auto &info = rsx::method_registers.vertex_arrays_info[i];
|
||||
if (!info.size) continue;
|
||||
if (!info.size()) continue;
|
||||
|
||||
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;
|
||||
@ -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))
|
||||
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);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
@ -437,9 +437,9 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32
|
||||
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 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];
|
||||
|
||||
@ -448,12 +448,12 @@ u32 GLGSRender::upload_inline_array(const u32 &max_vertex_attrib_size, const u32
|
||||
u8 *dst = static_cast<u8*>(mapping.first);
|
||||
|
||||
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
|
||||
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[1] = src[2];
|
||||
|
@ -531,12 +531,12 @@ namespace rsx
|
||||
{
|
||||
const auto &info = rsx::method_registers.vertex_arrays_info[index];
|
||||
|
||||
if (!info.size) // disabled
|
||||
if (!info.size()) // disabled
|
||||
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[1] = src[2];
|
||||
@ -587,7 +587,7 @@ namespace rsx
|
||||
u32 offset = vertex_array_info.offset();
|
||||
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
|
||||
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;
|
||||
|
||||
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
|
||||
@ -613,10 +613,10 @@ namespace rsx
|
||||
if (!enabled)
|
||||
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];
|
||||
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});
|
||||
continue;
|
||||
}
|
||||
@ -760,31 +760,25 @@ namespace rsx
|
||||
if (!enabled)
|
||||
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(
|
||||
{
|
||||
index,
|
||||
rsx::method_registers.vertex_arrays_info[index].size,
|
||||
rsx::method_registers.vertex_arrays_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
true,
|
||||
is_int_type(rsx::method_registers.vertex_arrays_info[index].type)
|
||||
}
|
||||
);
|
||||
{index,
|
||||
rsx::method_registers.vertex_arrays_info[index].size(),
|
||||
rsx::method_registers.vertex_arrays_info[index].frequency(),
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
true,
|
||||
is_int_type(rsx::method_registers.vertex_arrays_info[index].type())});
|
||||
}
|
||||
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
||||
{
|
||||
result.rsx_vertex_inputs.push_back(
|
||||
{
|
||||
index,
|
||||
rsx::method_registers.register_vertex_info[index].size,
|
||||
rsx::method_registers.register_vertex_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
false,
|
||||
is_int_type(rsx::method_registers.vertex_arrays_info[index].type)
|
||||
}
|
||||
);
|
||||
{index,
|
||||
rsx::method_registers.register_vertex_info[index].size,
|
||||
rsx::method_registers.register_vertex_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
false,
|
||||
is_int_type(rsx::method_registers.vertex_arrays_info[index].type())});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -843,10 +837,10 @@ namespace rsx
|
||||
{
|
||||
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);
|
||||
result.state.frequency[index] = rsx::method_registers.vertex_arrays_info[index].frequency;
|
||||
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();
|
||||
}
|
||||
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
||||
{
|
||||
|
@ -388,10 +388,10 @@ u32 VKGSRender::upload_inlined_array()
|
||||
for (u32 i = 0; i < rsx::limits::vertex_count; ++i)
|
||||
{
|
||||
const auto &info = rsx::method_registers.vertex_arrays_info[i];
|
||||
if (!info.size) continue;
|
||||
if (!info.size()) continue;
|
||||
|
||||
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;
|
||||
@ -403,48 +403,48 @@ u32 VKGSRender::upload_inlined_array()
|
||||
if (!m_program->has_uniform(s_reg_table[index]))
|
||||
continue;
|
||||
|
||||
if (!vertex_info.size) // disabled
|
||||
if (!vertex_info.size()) // disabled
|
||||
{
|
||||
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 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);
|
||||
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));
|
||||
|
||||
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;
|
||||
|
||||
//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");
|
||||
|
||||
switch (vertex_info.type)
|
||||
switch (vertex_info.type())
|
||||
{
|
||||
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;
|
||||
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;
|
||||
case rsx::vertex_base_type::s1:
|
||||
case rsx::vertex_base_type::ub:
|
||||
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;
|
||||
case rsx::vertex_base_type::s32k:
|
||||
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;
|
||||
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();
|
||||
|
@ -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)
|
||||
{
|
||||
rsx::method_registers.current_draw_clause.command = rsx::draw_command::array;
|
||||
@ -877,7 +864,6 @@ namespace rsx
|
||||
|
||||
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 : vertex_textures) tex.init();
|
||||
}
|
||||
@ -1275,7 +1261,6 @@ namespace rsx
|
||||
bind<NV4097_DRAW_ARRAYS, nv4097::draw_arrays>();
|
||||
bind<NV4097_DRAW_INDEX_ARRAY, nv4097::draw_index_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_DATA1F_M, 1, 16, nv4097::set_vertex_data1f_m>();
|
||||
bind_range<NV4097_SET_VERTEX_DATA2F_M, 1, 32, nv4097::set_vertex_data2f_m>();
|
||||
|
@ -137,13 +137,6 @@ namespace rsx
|
||||
transform_program = in.transform_program;
|
||||
transform_constants = in.transform_constants;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -9,19 +9,46 @@ namespace rsx
|
||||
struct data_array_format_info
|
||||
{
|
||||
private:
|
||||
u32& m_offset_register;
|
||||
public:
|
||||
u16 frequency = 0;
|
||||
u8 stride = 0;
|
||||
u8 size = 0;
|
||||
vertex_base_type type = vertex_base_type::f;
|
||||
u8 index;
|
||||
std::array<u32, 0x10000 / 4>& registers;
|
||||
|
||||
data_array_format_info(int id, std::array<u32, 0x10000 / 4> ®isters)
|
||||
: m_offset_register(registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + id]) {}
|
||||
auto decode_reg() const
|
||||
{
|
||||
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
|
||||
{
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user