mirror of https://github.com/RPCS3/rpcs3.git
Merge pull request #1941 from vlj/rsx-refactor
rsx: Use register_decoder for vertex attributes.
This commit is contained in:
commit
2af86e363c
|
@ -59,6 +59,19 @@ namespace
|
||||||
return vertex_buffer_view;
|
return vertex_buffer_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D12_SHADER_RESOURCE_VIEW_DESC get_vertex_attribute_srv(const rsx::vertex_base_type type, u8 size, UINT64 offset_in_vertex_buffers_buffer, UINT buffer_size)
|
||||||
|
{
|
||||||
|
u32 element_size = rsx::get_vertex_type_size_on_host(type, size);
|
||||||
|
D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {
|
||||||
|
get_vertex_attribute_format(type, size),
|
||||||
|
D3D12_SRV_DIMENSION_BUFFER,
|
||||||
|
get_component_mapping_from_vector_size(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;
|
||||||
|
}
|
||||||
|
|
||||||
template<int N>
|
template<int N>
|
||||||
UINT64 get_next_multiple_of(UINT64 val)
|
UINT64 get_next_multiple_of(UINT64 val)
|
||||||
{
|
{
|
||||||
|
@ -120,20 +133,19 @@ std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> D3D12GSRender::upload_vertex_attrib
|
||||||
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
||||||
{
|
{
|
||||||
// In register vertex attribute
|
// In register vertex attribute
|
||||||
const rsx::data_array_format_info &info = rsx::method_registers.register_vertex_info[index];
|
const rsx::register_vertex_data_info &info = rsx::method_registers.register_vertex_info[index];
|
||||||
const std::vector<u8> &data = rsx::method_registers.register_vertex_data[index];
|
|
||||||
|
|
||||||
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 = gsl::narrow<UINT>(data.size());
|
UINT buffer_size = element_size;
|
||||||
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
||||||
|
|
||||||
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||||
memcpy(mapped_buffer, data.data(), data.size());
|
memcpy(mapped_buffer, info.data.data(), buffer_size);
|
||||||
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||||
|
|
||||||
command_list->CopyBufferRegion(m_vertex_buffer_data.Get(), offset_in_vertex_buffers_buffer, m_buffer_data.get_heap(), heap_offset, buffer_size);
|
command_list->CopyBufferRegion(m_vertex_buffer_data.Get(), offset_in_vertex_buffers_buffer, m_buffer_data.get_heap(), heap_offset, buffer_size);
|
||||||
|
|
||||||
vertex_buffer_views.emplace_back(get_vertex_attribute_srv(info, offset_in_vertex_buffers_buffer, buffer_size));
|
vertex_buffer_views.emplace_back(get_vertex_attribute_srv(info.type, info.size, offset_in_vertex_buffers_buffer, buffer_size));
|
||||||
offset_in_vertex_buffers_buffer = get_next_multiple_of<48>(offset_in_vertex_buffers_buffer + buffer_size); // 48 is multiple of 2, 4, 6, 8, 12, 16
|
offset_in_vertex_buffers_buffer = get_next_multiple_of<48>(offset_in_vertex_buffers_buffer + buffer_size); // 48 is multiple of 2, 4, 6, 8, 12, 16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,7 +388,6 @@ u32 GLGSRender::set_vertex_buffer()
|
||||||
}
|
}
|
||||||
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
||||||
{
|
{
|
||||||
auto &vertex_data = rsx::method_registers.register_vertex_data[index];
|
|
||||||
auto &vertex_info = rsx::method_registers.register_vertex_info[index];
|
auto &vertex_info = rsx::method_registers.register_vertex_info[index];
|
||||||
|
|
||||||
switch (vertex_info.type)
|
switch (vertex_info.type)
|
||||||
|
@ -397,14 +396,14 @@ u32 GLGSRender::set_vertex_buffer()
|
||||||
{
|
{
|
||||||
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);
|
||||||
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
|
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
|
||||||
const size_t data_size = vertex_data.size();
|
const size_t data_size = element_size;
|
||||||
|
|
||||||
auto &texture = m_gl_attrib_buffers[index];
|
auto &texture = m_gl_attrib_buffers[index];
|
||||||
|
|
||||||
auto mapping = m_attrib_ring_buffer.alloc_from_reserve(data_size, m_min_texbuffer_alignment);
|
auto mapping = m_attrib_ring_buffer.alloc_from_reserve(data_size, m_min_texbuffer_alignment);
|
||||||
u8 *dst = static_cast<u8*>(mapping.first);
|
u8 *dst = static_cast<u8*>(mapping.first);
|
||||||
|
|
||||||
memcpy(dst, vertex_data.data(), data_size);
|
memcpy(dst, vertex_info.data.data(), element_size);
|
||||||
texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size);
|
texture.copy_from(m_attrib_ring_buffer, gl_type, mapping.second, data_size);
|
||||||
|
|
||||||
//Link texture to uniform
|
//Link texture to uniform
|
||||||
|
|
|
@ -354,7 +354,6 @@ namespace rsx
|
||||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||||
{
|
{
|
||||||
rsx::method_registers.register_vertex_info[index].size = 0;
|
rsx::method_registers.register_vertex_info[index].size = 0;
|
||||||
rsx::method_registers.register_vertex_data[index].clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (capture_current_frame)
|
if (capture_current_frame)
|
||||||
|
|
|
@ -508,18 +508,17 @@ VKGSRender::upload_vertex_data()
|
||||||
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
else if (rsx::method_registers.register_vertex_info[index].size > 0)
|
||||||
{
|
{
|
||||||
//Untested!
|
//Untested!
|
||||||
auto &vertex_data = rsx::method_registers.register_vertex_data[index];
|
|
||||||
auto &vertex_info = rsx::method_registers.register_vertex_info[index];
|
auto &vertex_info = rsx::method_registers.register_vertex_info[index];
|
||||||
|
|
||||||
switch (vertex_info.type)
|
switch (vertex_info.type)
|
||||||
{
|
{
|
||||||
case rsx::vertex_base_type::f:
|
case rsx::vertex_base_type::f:
|
||||||
{
|
{
|
||||||
size_t data_size = vertex_data.size();
|
size_t data_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||||
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 = 0;
|
u32 offset_in_attrib_buffer = 0;
|
||||||
void *data_ptr = vertex_data.data();
|
void *data_ptr = vertex_info.data.data();
|
||||||
|
|
||||||
if (vk::requires_component_expansion(vertex_info.type, vertex_info.size))
|
if (vk::requires_component_expansion(vertex_info.type, vertex_info.size))
|
||||||
{
|
{
|
||||||
|
@ -530,14 +529,14 @@ VKGSRender::upload_vertex_data()
|
||||||
offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(data_size);
|
offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(data_size);
|
||||||
void *dst = m_attrib_ring_info.map(offset_in_attrib_buffer, data_size);
|
void *dst = m_attrib_ring_info.map(offset_in_attrib_buffer, data_size);
|
||||||
|
|
||||||
vk::expand_array_components<float, 3, 4, 1>(reinterpret_cast<float*>(vertex_data.data()), dst, num_stored_verts);
|
vk::expand_array_components<float, 3, 4, 1>(reinterpret_cast<float*>(vertex_info.data.data()), dst, num_stored_verts);
|
||||||
m_attrib_ring_info.unmap();
|
m_attrib_ring_info.unmap();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(data_size);
|
offset_in_attrib_buffer = m_attrib_ring_info.alloc<256>(data_size);
|
||||||
void *dst = m_attrib_ring_info.map(offset_in_attrib_buffer, data_size);
|
void *dst = m_attrib_ring_info.map(offset_in_attrib_buffer, data_size);
|
||||||
memcpy(dst, vertex_data.data(), data_size);
|
memcpy(dst, vertex_info.data.data(), data_size);
|
||||||
m_attrib_ring_info.unmap();
|
m_attrib_ring_info.unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,21 @@ namespace
|
||||||
subreg == 2 ? "z" :
|
subreg == 2 ? "z" :
|
||||||
"w";
|
"w";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string print_vertex_attribute_format(rsx::vertex_base_type type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case rsx::vertex_base_type::s1: return "Signed short normalized";
|
||||||
|
case rsx::vertex_base_type::f: return "Float";
|
||||||
|
case rsx::vertex_base_type::sf: return "Half float";
|
||||||
|
case rsx::vertex_base_type::ub: return "Unsigned byte normalized";
|
||||||
|
case rsx::vertex_base_type::s32k: return "Signed short unormalized";
|
||||||
|
case rsx::vertex_base_type::cmp: return "CMP";
|
||||||
|
case rsx::vertex_base_type::ub256: return "Unsigned byte unormalized";
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace rsx
|
namespace rsx
|
||||||
|
@ -2318,6 +2333,172 @@ struct registers_decoder<NV4097_SET_TRANSFORM_PROGRAM_LOAD>
|
||||||
#define DECLARE_TRANSFORM_PROGRAM(index) NV4097_SET_TRANSFORM_PROGRAM + index,
|
#define DECLARE_TRANSFORM_PROGRAM(index) NV4097_SET_TRANSFORM_PROGRAM + index,
|
||||||
EXPAND_RANGE_512(0, TRANSFORM_PROGRAM)
|
EXPAND_RANGE_512(0, TRANSFORM_PROGRAM)
|
||||||
|
|
||||||
|
template<u32 index>
|
||||||
|
struct vertex_array_helper
|
||||||
|
{
|
||||||
|
static auto decode(u32 value)
|
||||||
|
{
|
||||||
|
u16 frequency = value >> 16;
|
||||||
|
u8 stride = (value >> 8) & 0xff;
|
||||||
|
u8 size = (value >> 4) & 0xf;
|
||||||
|
rsx::vertex_base_type type = rsx::to_vertex_base_type(value & 0xf);
|
||||||
|
return std::make_tuple(frequency, stride, size, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void commit_rsx_state(rsx::rsx_state &state, std::tuple<u16, u8, u8, rsx::vertex_base_type> &&decoded_values)
|
||||||
|
{
|
||||||
|
state.vertex_arrays_info[index].frequency = std::get<0>(decoded_values);
|
||||||
|
state.vertex_arrays_info[index].stride = std::get<1>(decoded_values);
|
||||||
|
state.vertex_arrays_info[index].size = std::get<2>(decoded_values);
|
||||||
|
state.vertex_arrays_info[index].type = std::get<3>(decoded_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string dump(std::tuple<u16, u8, u8, rsx::vertex_base_type> &&decoded_values)
|
||||||
|
{
|
||||||
|
if (std::get<2>(decoded_values) == 0)
|
||||||
|
return "(disabled)";
|
||||||
|
|
||||||
|
return "Vertex array " + std::to_string(index) + ": Type = " + print_vertex_attribute_format(std::get<3>(decoded_values)) +
|
||||||
|
" size = " + std::to_string(std::get<2>(decoded_values)) +
|
||||||
|
" stride = " + std::to_string(std::get<1>(decoded_values)) +
|
||||||
|
" frequency = " + std::to_string(std::get<0>(decoded_values));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VERTEX_DATA_ARRAY_FORMAT(index) template<> struct registers_decoder<NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + index> : public vertex_array_helper<index> {};
|
||||||
|
#define DECLARE_VERTEX_DATA_ARRAY_FORMAT(index) NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + index,
|
||||||
|
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA_ARRAY_FORMAT)
|
||||||
|
|
||||||
|
template<u32 index>
|
||||||
|
struct vertex_array_offset_helper
|
||||||
|
{
|
||||||
|
static auto decode(u32 value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void commit_rsx_state(rsx::rsx_state &state, u32 &&decoded_values)
|
||||||
|
{
|
||||||
|
state.vertex_arrays_info[index].m_offset = decoded_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string dump(u32 &&decoded_values)
|
||||||
|
{
|
||||||
|
return "Vertex array " + std::to_string(index) + ": Offset = " + std::to_string(decoded_values);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VERTEX_DATA_ARRAY_OFFSET(index) template<> struct registers_decoder<NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index> : public vertex_array_offset_helper<index> {};
|
||||||
|
#define DECLARE_VERTEX_DATA_ARRAY_OFFSET(index) NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index,
|
||||||
|
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA_ARRAY_OFFSET)
|
||||||
|
|
||||||
|
template<typename Type> struct vertex_data_type_from_element_type;
|
||||||
|
template<> struct vertex_data_type_from_element_type<float> { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::f; };
|
||||||
|
template<> struct vertex_data_type_from_element_type<f16> { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::sf; };
|
||||||
|
template<> struct vertex_data_type_from_element_type<u8> { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::ub; };
|
||||||
|
template<> struct vertex_data_type_from_element_type<u16> { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::s1; };
|
||||||
|
|
||||||
|
template<typename type, int count>
|
||||||
|
struct vertex_type_namer;
|
||||||
|
|
||||||
|
template<int count>
|
||||||
|
struct vertex_type_namer<f32, count>
|
||||||
|
{
|
||||||
|
static std::string get()
|
||||||
|
{
|
||||||
|
return "float" + std::to_string(count);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int count>
|
||||||
|
struct vertex_type_namer<u16, count>
|
||||||
|
{
|
||||||
|
static std::string get()
|
||||||
|
{
|
||||||
|
return "short" + std::to_string(count);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct vertex_type_namer<u8, 4>
|
||||||
|
{
|
||||||
|
static std::string get()
|
||||||
|
{
|
||||||
|
return "uchar4";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<u32 index, typename type, int count>
|
||||||
|
struct register_vertex_helper
|
||||||
|
{
|
||||||
|
static auto decode(u32 value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const size_t increment_per_array_index = (count * sizeof(type)) / sizeof(u32);
|
||||||
|
|
||||||
|
static const size_t attribute_index = index / increment_per_array_index;
|
||||||
|
static const size_t vertex_subreg = index % increment_per_array_index;
|
||||||
|
|
||||||
|
static void commit_rsx_state(rsx::rsx_state &state, u32 &&decoded_values)
|
||||||
|
{
|
||||||
|
auto& info = state.register_vertex_info[attribute_index];
|
||||||
|
|
||||||
|
info.type = vertex_data_type_from_element_type<type>::type;
|
||||||
|
info.size = count;
|
||||||
|
info.frequency = 0;
|
||||||
|
info.stride = 0;
|
||||||
|
state.register_vertex_info[attribute_index].data[vertex_subreg] = decoded_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string dump(u32&& decoded_values)
|
||||||
|
{
|
||||||
|
return "register vertex " + std::to_string(attribute_index) + " as " + vertex_type_namer<type, count>::get() + ": " +
|
||||||
|
std::to_string(decoded_values);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VERTEX_DATA4UB(index) \
|
||||||
|
template<> struct registers_decoder<NV4097_SET_VERTEX_DATA4UB_M + index> : public register_vertex_helper<index, u8, 4> {};
|
||||||
|
#define VERTEX_DATA1F(index) \
|
||||||
|
template<> struct registers_decoder<NV4097_SET_VERTEX_DATA1F_M + index> : public register_vertex_helper<index, f32, 1> {};
|
||||||
|
#define VERTEX_DATA2F(index) \
|
||||||
|
template<> struct registers_decoder<NV4097_SET_VERTEX_DATA2F_M + index> : public register_vertex_helper<index, f32, 2> {};
|
||||||
|
#define VERTEX_DATA3F(index) \
|
||||||
|
template<> struct registers_decoder<NV4097_SET_VERTEX_DATA3F_M + index> : public register_vertex_helper<index, f32, 3> {};
|
||||||
|
#define VERTEX_DATA4F(index) \
|
||||||
|
template<> struct registers_decoder<NV4097_SET_VERTEX_DATA4F_M + index> : public register_vertex_helper<index, f32, 4> {};
|
||||||
|
#define VERTEX_DATA2S(index) \
|
||||||
|
template<> struct registers_decoder<NV4097_SET_VERTEX_DATA2S_M + index> : public register_vertex_helper<index, u16, 2> {};
|
||||||
|
#define VERTEX_DATA4S(index) \
|
||||||
|
template<> struct registers_decoder<NV4097_SET_VERTEX_DATA4S_M + index> : public register_vertex_helper<index, u16, 4> {};
|
||||||
|
|
||||||
|
#define DECLARE_VERTEX_DATA4UB(index) \
|
||||||
|
NV4097_SET_VERTEX_DATA4UB_M + index,
|
||||||
|
#define DECLARE_VERTEX_DATA1F(index) \
|
||||||
|
NV4097_SET_VERTEX_DATA1F_M + index,
|
||||||
|
#define DECLARE_VERTEX_DATA2F(index) \
|
||||||
|
NV4097_SET_VERTEX_DATA2F_M + index,
|
||||||
|
#define DECLARE_VERTEX_DATA3F(index) \
|
||||||
|
NV4097_SET_VERTEX_DATA3F_M + index,
|
||||||
|
#define DECLARE_VERTEX_DATA4F(index) \
|
||||||
|
NV4097_SET_VERTEX_DATA4F_M + index,
|
||||||
|
#define DECLARE_VERTEX_DATA2S(index) \
|
||||||
|
NV4097_SET_VERTEX_DATA2S_M + index,
|
||||||
|
#define DECLARE_VERTEX_DATA4S(index) \
|
||||||
|
NV4097_SET_VERTEX_DATA4S_M + index,
|
||||||
|
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA4UB)
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA1F)
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA2F)
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA3F)
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA4F)
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA2S)
|
||||||
|
EXPAND_RANGE_16(0, VERTEX_DATA4S)
|
||||||
|
|
||||||
constexpr std::integer_sequence<u32,
|
constexpr std::integer_sequence<u32,
|
||||||
NV4097_SET_VIEWPORT_HORIZONTAL,
|
NV4097_SET_VIEWPORT_HORIZONTAL,
|
||||||
NV4097_SET_VIEWPORT_VERTICAL,
|
NV4097_SET_VIEWPORT_VERTICAL,
|
||||||
|
@ -2463,10 +2644,18 @@ constexpr std::integer_sequence<u32,
|
||||||
NV4097_SET_ANTI_ALIASING_CONTROL,
|
NV4097_SET_ANTI_ALIASING_CONTROL,
|
||||||
NV4097_SET_FRONT_POLYGON_MODE,
|
NV4097_SET_FRONT_POLYGON_MODE,
|
||||||
NV4097_SET_BACK_POLYGON_MODE,
|
NV4097_SET_BACK_POLYGON_MODE,
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA_ARRAY_FORMAT)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA_ARRAY_OFFSET)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA4UB)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA1F)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA2F)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA3F)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA4F)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA2S)
|
||||||
|
EXPAND_RANGE_16(0, DECLARE_VERTEX_DATA4S)
|
||||||
EXPAND_RANGE_32(0, DECLARE_TRANSFORM_CONSTANT)
|
EXPAND_RANGE_32(0, DECLARE_TRANSFORM_CONSTANT)
|
||||||
NV4097_SET_TRANSFORM_CONSTANT_LOAD,
|
NV4097_SET_TRANSFORM_CONSTANT_LOAD,
|
||||||
EXPAND_RANGE_512(0, DECLARE_TRANSFORM_PROGRAM)
|
EXPAND_RANGE_512(0, DECLARE_TRANSFORM_PROGRAM)
|
||||||
NV4097_SET_TRANSFORM_PROGRAM_LOAD
|
NV4097_SET_TRANSFORM_PROGRAM_LOAD
|
||||||
> opcode_list{};
|
> opcode_list{};
|
||||||
|
|
||||||
} // end namespace rsx
|
} // end namespace rsx
|
||||||
|
|
|
@ -26,12 +26,6 @@ namespace rsx
|
||||||
rsx_state method_registers;
|
rsx_state method_registers;
|
||||||
rsx_method_t methods[0x10000 >> 2]{};
|
rsx_method_t methods[0x10000 >> 2]{};
|
||||||
|
|
||||||
template<typename Type> struct vertex_data_type_from_element_type;
|
|
||||||
template<> struct vertex_data_type_from_element_type<float> { static const vertex_base_type type = vertex_base_type::f; };
|
|
||||||
template<> struct vertex_data_type_from_element_type<f16> { static const vertex_base_type type = vertex_base_type::sf; };
|
|
||||||
template<> struct vertex_data_type_from_element_type<u8> { static const vertex_base_type type = vertex_base_type::ub; };
|
|
||||||
template<> struct vertex_data_type_from_element_type<u16> { static const vertex_base_type type = vertex_base_type::s1; };
|
|
||||||
|
|
||||||
namespace nv406e
|
namespace nv406e
|
||||||
{
|
{
|
||||||
force_inline void set_reference(thread* rsx, u32 arg)
|
force_inline void set_reference(thread* rsx, u32 arg)
|
||||||
|
@ -73,104 +67,6 @@ namespace rsx
|
||||||
(arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
|
(arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
//fire only when all data passed to rsx cmd buffer
|
|
||||||
template<u32 id, u32 index, int count, typename type>
|
|
||||||
force_inline void set_vertex_data_impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
static const size_t element_size = (count * sizeof(type));
|
|
||||||
static const size_t element_size_in_words = element_size / sizeof(u32);
|
|
||||||
|
|
||||||
auto& info = rsx::method_registers.register_vertex_info[index];
|
|
||||||
|
|
||||||
info.type = vertex_data_type_from_element_type<type>::type;
|
|
||||||
info.size = count;
|
|
||||||
info.frequency = 0;
|
|
||||||
info.stride = 0;
|
|
||||||
|
|
||||||
auto& entry = rsx::method_registers.register_vertex_data[index];
|
|
||||||
|
|
||||||
//find begin of data
|
|
||||||
size_t begin = id + index * element_size_in_words;
|
|
||||||
|
|
||||||
size_t position = entry.size();
|
|
||||||
entry.resize(position + element_size);
|
|
||||||
|
|
||||||
memcpy(entry.data() + position, &method_registers[begin], element_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data4ub_m
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA4UB_M, index, 4, u8>(rsx, arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data1f_m
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA1F_M, index, 1, f32>(rsx, arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data2f_m
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA2F_M, index, 2, f32>(rsx, arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data3f_m
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA3F_M, index, 3, f32>(rsx, arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data4f_m
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA4F_M, index, 4, f32>(rsx, arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data2s_m
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA2S_M, index, 2, u16>(rsx, arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data4s_m
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
set_vertex_data_impl<NV4097_SET_VERTEX_DATA4S_M, index, 4, u16>(rsx, arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<u32 index>
|
|
||||||
struct set_vertex_data_array_format
|
|
||||||
{
|
|
||||||
force_inline static void impl(thread* rsx, u32 arg)
|
|
||||||
{
|
|
||||||
auto& info = rsx::method_registers.vertex_arrays_info[index];
|
|
||||||
info.unpack_array(arg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
force_inline void draw_arrays(thread* rsx, u32 arg)
|
force_inline void draw_arrays(thread* rsx, u32 arg)
|
||||||
{
|
{
|
||||||
rsx->draw_command = rsx::draw_command::array;
|
rsx->draw_command = rsx::draw_command::array;
|
||||||
|
@ -221,10 +117,8 @@ namespace rsx
|
||||||
|
|
||||||
if (vertex_info.size > 0)
|
if (vertex_info.size > 0)
|
||||||
{
|
{
|
||||||
auto &vertex_data = rsx::method_registers.register_vertex_data[index];
|
|
||||||
|
|
||||||
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||||
u32 element_count = vertex_data.size() / element_size;
|
u32 element_count = vertex_info.size;
|
||||||
|
|
||||||
vertex_info.frequency = element_count;
|
vertex_info.frequency = element_count;
|
||||||
|
|
||||||
|
@ -763,9 +657,7 @@ namespace rsx
|
||||||
|
|
||||||
rsx_state::rsx_state() :
|
rsx_state::rsx_state() :
|
||||||
fragment_textures(fill_array<texture>(registers, std::make_index_sequence<16>())),
|
fragment_textures(fill_array<texture>(registers, std::make_index_sequence<16>())),
|
||||||
vertex_textures(fill_array<vertex_texture>(registers, std::make_index_sequence<4>())),
|
vertex_textures(fill_array<vertex_texture>(registers, std::make_index_sequence<4>()))
|
||||||
register_vertex_info(fill_array<data_array_format_info>(registers, std::make_index_sequence<16>())),
|
|
||||||
vertex_arrays_info(fill_array<data_array_format_info>(registers, std::make_index_sequence<16>()))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1033,14 +925,6 @@ namespace
|
||||||
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_DATA1F_M, 1, 16, nv4097::set_vertex_data1f_m>();
|
|
||||||
bind_range<NV4097_SET_VERTEX_DATA2F_M + 1, 2, 16, nv4097::set_vertex_data2f_m>();
|
|
||||||
bind_range<NV4097_SET_VERTEX_DATA3F_M + 2, 3, 16, nv4097::set_vertex_data3f_m>();
|
|
||||||
bind_range<NV4097_SET_VERTEX_DATA4F_M + 3, 4, 16, nv4097::set_vertex_data4f_m>();
|
|
||||||
bind_range<NV4097_SET_VERTEX_DATA2S_M, 1, 16, nv4097::set_vertex_data2s_m>();
|
|
||||||
bind_range<NV4097_SET_VERTEX_DATA4S_M + 1, 2, 16, nv4097::set_vertex_data4s_m>();
|
|
||||||
bind_range<NV4097_SET_TRANSFORM_CONSTANT, 1, 32, nv4097::set_transform_constant>();
|
bind_range<NV4097_SET_TRANSFORM_CONSTANT, 1, 32, nv4097::set_transform_constant>();
|
||||||
bind_cpu_only<NV4097_GET_REPORT, nv4097::get_report>();
|
bind_cpu_only<NV4097_GET_REPORT, nv4097::get_report>();
|
||||||
bind_cpu_only<NV4097_CLEAR_REPORT_VALUE, nv4097::clear_report_value>();
|
bind_cpu_only<NV4097_CLEAR_REPORT_VALUE, nv4097::clear_report_value>();
|
||||||
|
|
|
@ -101,23 +101,12 @@ namespace rsx
|
||||||
* Note that behavior when both vertex array and immediate value system are disabled but vertex attrib mask
|
* Note that behavior when both vertex array and immediate value system are disabled but vertex attrib mask
|
||||||
* request inputs is unknown.
|
* request inputs is unknown.
|
||||||
*/
|
*/
|
||||||
std::array<data_array_format_info, 16> register_vertex_info;
|
std::array<register_vertex_data_info, 16> register_vertex_info;
|
||||||
std::array<std::vector<u8>, 16> register_vertex_data;
|
|
||||||
std::array<data_array_format_info, 16> vertex_arrays_info;
|
std::array<data_array_format_info, 16> vertex_arrays_info;
|
||||||
|
|
||||||
rsx_state();
|
rsx_state();
|
||||||
~rsx_state();
|
~rsx_state();
|
||||||
|
|
||||||
u32& operator[](size_t idx)
|
|
||||||
{
|
|
||||||
return registers[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
const u32& operator[](size_t idx) const
|
|
||||||
{
|
|
||||||
return registers[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
void decode(u32 reg, u32 value);
|
void decode(u32 reg, u32 value);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -8,33 +8,30 @@ namespace rsx
|
||||||
|
|
||||||
struct data_array_format_info
|
struct data_array_format_info
|
||||||
{
|
{
|
||||||
private:
|
u16 frequency = 0;
|
||||||
u8 index;
|
u8 stride = 0;
|
||||||
std::array<u32, 0x10000 / 4> ®isters;
|
u8 size = 0;
|
||||||
public:
|
vertex_base_type type = vertex_base_type::f;
|
||||||
|
u32 m_offset;
|
||||||
|
|
||||||
|
data_array_format_info() {}
|
||||||
|
|
||||||
|
u32 offset() const
|
||||||
|
{
|
||||||
|
return m_offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct register_vertex_data_info
|
||||||
|
{
|
||||||
u16 frequency = 0;
|
u16 frequency = 0;
|
||||||
u8 stride = 0;
|
u8 stride = 0;
|
||||||
u8 size = 0;
|
u8 size = 0;
|
||||||
vertex_base_type type = vertex_base_type::f;
|
vertex_base_type type = vertex_base_type::f;
|
||||||
|
|
||||||
|
register_vertex_data_info() {}
|
||||||
|
std::array<u32, 4> data;
|
||||||
|
|
||||||
data_array_format_info(u8 idx, std::array<u32, 0x10000 / 4> &r) : index(idx), registers(r)
|
|
||||||
{}
|
|
||||||
|
|
||||||
data_array_format_info() = delete;
|
|
||||||
|
|
||||||
void unpack_array(u32 data_array_format)
|
|
||||||
{
|
|
||||||
frequency = data_array_format >> 16;
|
|
||||||
stride = (data_array_format >> 8) & 0xff;
|
|
||||||
size = (data_array_format >> 4) & 0xf;
|
|
||||||
type = to_vertex_base_type(data_array_format & 0xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 offset() const
|
|
||||||
{
|
|
||||||
return registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue