| | |
| | |
| |
|
| | #pragma once |
| |
|
| | #include <array> |
| | #include <optional> |
| |
|
| | #include "common/bit_field.h" |
| | #include "common/common_funcs.h" |
| | #include "common/common_types.h" |
| |
|
| | namespace Shader { |
| |
|
| | enum class OutputTopology : u32 { |
| | PointList = 1, |
| | LineStrip = 6, |
| | TriangleStrip = 7, |
| | }; |
| |
|
| | enum class PixelImap : u8 { |
| | Unused = 0, |
| | Constant = 1, |
| | Perspective = 2, |
| | ScreenLinear = 3, |
| | }; |
| |
|
| | |
| | |
| | struct ProgramHeader { |
| | union { |
| | BitField<0, 5, u32> sph_type; |
| | BitField<5, 5, u32> version; |
| | BitField<10, 4, u32> shader_type; |
| | BitField<14, 1, u32> mrt_enable; |
| | BitField<15, 1, u32> kills_pixels; |
| | BitField<16, 1, u32> does_global_store; |
| | BitField<17, 4, u32> sass_version; |
| | BitField<21, 2, u32> reserved1; |
| | BitField<24, 1, u32> geometry_passthrough; |
| | BitField<25, 1, u32> reserved2; |
| | BitField<26, 1, u32> does_load_or_store; |
| | BitField<27, 1, u32> does_fp64; |
| | BitField<28, 4, u32> stream_out_mask; |
| | } common0; |
| |
|
| | union { |
| | BitField<0, 24, u32> shader_local_memory_low_size; |
| | BitField<24, 8, u32> per_patch_attribute_count; |
| | } common1; |
| |
|
| | union { |
| | BitField<0, 24, u32> shader_local_memory_high_size; |
| | BitField<24, 8, u32> threads_per_input_primitive; |
| | } common2; |
| |
|
| | union { |
| | BitField<0, 24, u32> shader_local_memory_crs_size; |
| | BitField<24, 4, OutputTopology> output_topology; |
| | BitField<28, 4, u32> reserved; |
| | } common3; |
| |
|
| | union { |
| | BitField<0, 12, u32> max_output_vertices; |
| | BitField<12, 8, u32> store_req_start; |
| | BitField<20, 4, u32> reserved; |
| | BitField<24, 8, u32> store_req_end; |
| | } common4; |
| |
|
| | union { |
| | struct { |
| | INSERT_PADDING_BYTES_NOINIT(3); |
| |
|
| | union { |
| | BitField<0, 1, u8> primitive_array_id; |
| | BitField<1, 1, u8> rt_array_index; |
| | BitField<2, 1, u8> viewport_index; |
| | BitField<3, 1, u8> point_size; |
| | BitField<4, 1, u8> position_x; |
| | BitField<5, 1, u8> position_y; |
| | BitField<6, 1, u8> position_z; |
| | BitField<7, 1, u8> position_w; |
| | u8 raw; |
| | } imap_systemb; |
| |
|
| | std::array<u8, 16> imap_generic_vector; |
| |
|
| | INSERT_PADDING_BYTES_NOINIT(2); |
| | union { |
| | BitField<0, 8, u16> clip_distances; |
| | BitField<8, 1, u16> point_sprite_s; |
| | BitField<9, 1, u16> point_sprite_t; |
| | BitField<10, 1, u16> fog_coordinate; |
| | BitField<12, 1, u16> tessellation_eval_point_u; |
| | BitField<13, 1, u16> tessellation_eval_point_v; |
| | BitField<14, 1, u16> instance_id; |
| | BitField<15, 1, u16> vertex_id; |
| | }; |
| | INSERT_PADDING_BYTES_NOINIT(5); |
| | INSERT_PADDING_BYTES_NOINIT(1); |
| | INSERT_PADDING_BYTES_NOINIT(3); |
| |
|
| | union { |
| | BitField<0, 1, u8> primitive_array_id; |
| | BitField<1, 1, u8> rt_array_index; |
| | BitField<2, 1, u8> viewport_index; |
| | BitField<3, 1, u8> point_size; |
| | BitField<4, 1, u8> position_x; |
| | BitField<5, 1, u8> position_y; |
| | BitField<6, 1, u8> position_z; |
| | BitField<7, 1, u8> position_w; |
| | u8 raw; |
| | } omap_systemb; |
| |
|
| | std::array<u8, 16> omap_generic_vector; |
| |
|
| | INSERT_PADDING_BYTES_NOINIT(2); |
| |
|
| | union { |
| | BitField<0, 8, u16> clip_distances; |
| | BitField<8, 1, u16> point_sprite_s; |
| | BitField<9, 1, u16> point_sprite_t; |
| | BitField<10, 1, u16> fog_coordinate; |
| | BitField<12, 1, u16> tessellation_eval_point_u; |
| | BitField<13, 1, u16> tessellation_eval_point_v; |
| | BitField<14, 1, u16> instance_id; |
| | BitField<15, 1, u16> vertex_id; |
| | } omap_systemc; |
| |
|
| | INSERT_PADDING_BYTES_NOINIT(5); |
| | INSERT_PADDING_BYTES_NOINIT(1); |
| |
|
| | [[nodiscard]] std::array<bool, 4> InputGeneric(size_t index) const noexcept { |
| | const int data{imap_generic_vector[index >> 1] >> ((index % 2) * 4)}; |
| | return { |
| | (data & 1) != 0, |
| | (data & 2) != 0, |
| | (data & 4) != 0, |
| | (data & 8) != 0, |
| | }; |
| | } |
| |
|
| | [[nodiscard]] std::array<bool, 4> OutputGeneric(size_t index) const noexcept { |
| | const int data{omap_generic_vector[index >> 1] >> ((index % 2) * 4)}; |
| | return { |
| | (data & 1) != 0, |
| | (data & 2) != 0, |
| | (data & 4) != 0, |
| | (data & 8) != 0, |
| | }; |
| | } |
| | } vtg; |
| |
|
| | struct { |
| | INSERT_PADDING_BYTES_NOINIT(3); |
| |
|
| | union { |
| | BitField<0, 1, u8> primitive_array_id; |
| | BitField<1, 1, u8> rt_array_index; |
| | BitField<2, 1, u8> viewport_index; |
| | BitField<3, 1, u8> point_size; |
| | BitField<4, 1, u8> position_x; |
| | BitField<5, 1, u8> position_y; |
| | BitField<6, 1, u8> position_z; |
| | BitField<7, 1, u8> position_w; |
| | BitField<0, 4, u8> first; |
| | BitField<4, 4, u8> position; |
| | u8 raw; |
| | } imap_systemb; |
| |
|
| | union { |
| | BitField<0, 2, PixelImap> x; |
| | BitField<2, 2, PixelImap> y; |
| | BitField<4, 2, PixelImap> z; |
| | BitField<6, 2, PixelImap> w; |
| | u8 raw; |
| | } imap_generic_vector[32]; |
| |
|
| | INSERT_PADDING_BYTES_NOINIT(2); |
| | INSERT_PADDING_BYTES_NOINIT(2); |
| | INSERT_PADDING_BYTES_NOINIT(10); |
| | INSERT_PADDING_BYTES_NOINIT(2); |
| |
|
| | struct { |
| | u32 target; |
| | union { |
| | BitField<0, 1, u32> sample_mask; |
| | BitField<1, 1, u32> depth; |
| | BitField<2, 30, u32> reserved; |
| | }; |
| | } omap; |
| |
|
| | [[nodiscard]] std::array<bool, 4> EnabledOutputComponents(u32 rt) const noexcept { |
| | const u32 bits{omap.target >> (rt * 4)}; |
| | return {(bits & 1) != 0, (bits & 2) != 0, (bits & 4) != 0, (bits & 8) != 0}; |
| | } |
| |
|
| | [[nodiscard]] bool HasOutputComponents(u32 rt) const noexcept { |
| | const u32 bits{omap.target >> (rt * 4)}; |
| | return (bits & 0xf) != 0; |
| | } |
| |
|
| | [[nodiscard]] std::array<PixelImap, 4> GenericInputMap(u32 attribute) const { |
| | const auto& vector{imap_generic_vector[attribute]}; |
| | return {vector.x, vector.y, vector.z, vector.w}; |
| | } |
| |
|
| | [[nodiscard]] bool IsGenericVectorActive(size_t index) const { |
| | return imap_generic_vector[index].raw != 0; |
| | } |
| | } ps; |
| |
|
| | std::array<u32, 0xf> raw; |
| | }; |
| |
|
| | [[nodiscard]] u64 LocalMemorySize() const noexcept { |
| | return static_cast<u64>(common1.shader_local_memory_low_size) | |
| | (static_cast<u64>(common2.shader_local_memory_high_size) << 24); |
| | } |
| | }; |
| | static_assert(sizeof(ProgramHeader) == 0x50, "Incorrect structure size"); |
| |
|
| | } |
| |
|