2024-05-21 22:35:12 +00:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
#include <algorithm>
|
2024-05-25 12:33:15 +00:00
|
|
|
#include <boost/container/static_vector.hpp>
|
2024-09-03 11:04:30 +00:00
|
|
|
|
2024-05-25 12:33:15 +00:00
|
|
|
#include "common/assert.h"
|
|
|
|
#include "common/types.h"
|
2024-10-05 22:26:50 +00:00
|
|
|
#include "frontend/copy_shader.h"
|
|
|
|
#include "video_core/amdgpu/types.h"
|
2024-05-21 22:35:12 +00:00
|
|
|
|
|
|
|
namespace Shader {
|
|
|
|
|
|
|
|
enum class Stage : u32 {
|
2024-07-14 21:25:41 +00:00
|
|
|
Fragment,
|
2024-05-21 22:35:12 +00:00
|
|
|
Vertex,
|
|
|
|
Geometry,
|
2024-07-14 21:25:41 +00:00
|
|
|
Export,
|
|
|
|
Hull,
|
|
|
|
Local,
|
2024-05-21 22:35:12 +00:00
|
|
|
Compute,
|
|
|
|
};
|
|
|
|
constexpr u32 MaxStageTypes = 6;
|
|
|
|
|
|
|
|
[[nodiscard]] constexpr Stage StageFromIndex(size_t index) noexcept {
|
2024-09-03 11:04:30 +00:00
|
|
|
return static_cast<Stage>(index);
|
2024-05-21 22:35:12 +00:00
|
|
|
}
|
|
|
|
|
2024-10-05 22:26:50 +00:00
|
|
|
struct ExportRuntimeInfo {
|
|
|
|
u32 vertex_data_size;
|
|
|
|
|
|
|
|
auto operator<=>(const ExportRuntimeInfo&) const noexcept = default;
|
2024-05-21 22:35:12 +00:00
|
|
|
};
|
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
enum class VsOutput : u8 {
|
2024-07-04 21:15:44 +00:00
|
|
|
None,
|
|
|
|
PointSprite,
|
|
|
|
EdgeFlag,
|
|
|
|
KillFlag,
|
|
|
|
GsCutFlag,
|
|
|
|
GsMrtIndex,
|
|
|
|
GsVpIndex,
|
|
|
|
CullDist0,
|
|
|
|
CullDist1,
|
|
|
|
CullDist2,
|
|
|
|
CullDist3,
|
|
|
|
CullDist4,
|
|
|
|
CullDist5,
|
|
|
|
CullDist6,
|
|
|
|
CullDist7,
|
|
|
|
ClipDist0,
|
|
|
|
ClipDist1,
|
|
|
|
ClipDist2,
|
|
|
|
ClipDist3,
|
|
|
|
ClipDist4,
|
|
|
|
ClipDist5,
|
|
|
|
ClipDist6,
|
|
|
|
ClipDist7,
|
|
|
|
};
|
|
|
|
using VsOutputMap = std::array<VsOutput, 4>;
|
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
struct VertexRuntimeInfo {
|
|
|
|
boost::container::static_vector<VsOutputMap, 3> outputs;
|
2024-09-03 22:07:05 +00:00
|
|
|
bool emulate_depth_negative_one_to_one{};
|
2024-08-08 12:02:10 +00:00
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
bool operator==(const VertexRuntimeInfo& other) const noexcept {
|
2024-09-03 22:07:05 +00:00
|
|
|
return emulate_depth_negative_one_to_one == other.emulate_depth_negative_one_to_one;
|
2024-08-08 12:02:10 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-10-05 22:26:50 +00:00
|
|
|
static constexpr auto GsMaxOutputStreams = 4u;
|
|
|
|
using GsOutputPrimTypes = std::array<AmdGpu::GsOutputPrimitiveType, GsMaxOutputStreams>;
|
|
|
|
struct GeometryRuntimeInfo {
|
|
|
|
u32 num_invocations{};
|
|
|
|
u32 output_vertices{};
|
|
|
|
u32 in_vertex_data_size{};
|
|
|
|
u32 out_vertex_data_size{};
|
|
|
|
AmdGpu::PrimitiveType in_primitive;
|
|
|
|
GsOutputPrimTypes out_primitive;
|
|
|
|
CopyShaderData copy_data;
|
|
|
|
|
|
|
|
bool operator==(const GeometryRuntimeInfo& other) const noexcept {
|
|
|
|
return num_invocations && other.num_invocations &&
|
|
|
|
output_vertices == other.output_vertices && in_primitive == other.in_primitive &&
|
|
|
|
std::ranges::equal(out_primitive, other.out_primitive) &&
|
|
|
|
std::ranges::equal(copy_data.attr_map, other.copy_data.attr_map);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class MrtSwizzle : u8 {
|
|
|
|
Identity = 0,
|
|
|
|
Alt = 1,
|
|
|
|
Reverse = 2,
|
|
|
|
ReverseAlt = 3,
|
|
|
|
};
|
|
|
|
static constexpr u32 MaxColorBuffers = 8;
|
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
struct FragmentRuntimeInfo {
|
2024-05-25 12:33:15 +00:00
|
|
|
struct PsInput {
|
2024-09-03 11:04:30 +00:00
|
|
|
u8 param_index;
|
2024-05-25 12:33:15 +00:00
|
|
|
bool is_default;
|
|
|
|
bool is_flat;
|
2024-09-03 11:04:30 +00:00
|
|
|
u8 default_value;
|
2024-05-25 12:33:15 +00:00
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
auto operator<=>(const PsInput&) const noexcept = default;
|
2024-05-25 12:33:15 +00:00
|
|
|
};
|
2024-09-03 11:04:30 +00:00
|
|
|
boost::container::static_vector<PsInput, 32> inputs;
|
2024-10-01 20:42:37 +00:00
|
|
|
struct PsColorBuffer {
|
|
|
|
AmdGpu::NumberFormat num_format;
|
|
|
|
MrtSwizzle mrt_swizzle;
|
|
|
|
|
|
|
|
auto operator<=>(const PsColorBuffer&) const noexcept = default;
|
|
|
|
};
|
|
|
|
std::array<PsColorBuffer, MaxColorBuffers> color_buffers;
|
2024-05-25 12:33:15 +00:00
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
bool operator==(const FragmentRuntimeInfo& other) const noexcept {
|
2024-10-01 20:42:37 +00:00
|
|
|
return std::ranges::equal(color_buffers, other.color_buffers) &&
|
2024-09-03 11:04:30 +00:00
|
|
|
std::ranges::equal(inputs, other.inputs);
|
|
|
|
}
|
|
|
|
};
|
2024-05-26 22:07:46 +00:00
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
struct ComputeRuntimeInfo {
|
|
|
|
u32 shared_memory_size;
|
|
|
|
std::array<u32, 3> workgroup_size;
|
2024-08-16 17:05:37 +00:00
|
|
|
std::array<bool, 3> tgid_enable;
|
2024-05-28 22:28:34 +00:00
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
bool operator==(const ComputeRuntimeInfo& other) const noexcept {
|
|
|
|
return workgroup_size == other.workgroup_size && tgid_enable == other.tgid_enable;
|
2024-08-29 16:29:54 +00:00
|
|
|
}
|
2024-09-03 11:04:30 +00:00
|
|
|
};
|
2024-08-29 16:29:54 +00:00
|
|
|
|
2024-09-03 11:04:30 +00:00
|
|
|
/**
|
|
|
|
* Stores information relevant to shader compilation sourced from liverpool registers.
|
|
|
|
* It may potentially differ with the same shader module so must be checked.
|
|
|
|
* It's also possible to store any other custom information that needs to be part of shader key.
|
|
|
|
*/
|
|
|
|
struct RuntimeInfo {
|
|
|
|
Stage stage;
|
|
|
|
u32 num_user_data;
|
|
|
|
u32 num_input_vgprs;
|
2024-09-06 20:47:47 +00:00
|
|
|
u32 num_allocated_vgprs;
|
2024-10-05 22:26:50 +00:00
|
|
|
ExportRuntimeInfo es_info;
|
2024-09-03 11:04:30 +00:00
|
|
|
VertexRuntimeInfo vs_info;
|
2024-10-05 22:26:50 +00:00
|
|
|
GeometryRuntimeInfo gs_info;
|
2024-09-03 11:04:30 +00:00
|
|
|
FragmentRuntimeInfo fs_info;
|
|
|
|
ComputeRuntimeInfo cs_info;
|
|
|
|
|
|
|
|
RuntimeInfo(Stage stage_) : stage{stage_} {}
|
|
|
|
|
|
|
|
bool operator==(const RuntimeInfo& other) const noexcept {
|
|
|
|
switch (stage) {
|
|
|
|
case Stage::Fragment:
|
|
|
|
return fs_info == other.fs_info;
|
|
|
|
case Stage::Vertex:
|
|
|
|
return vs_info == other.vs_info;
|
|
|
|
case Stage::Compute:
|
|
|
|
return cs_info == other.cs_info;
|
2024-10-05 22:26:50 +00:00
|
|
|
case Stage::Export:
|
|
|
|
return es_info == other.es_info;
|
|
|
|
case Stage::Geometry:
|
|
|
|
return gs_info == other.gs_info;
|
2024-09-03 11:04:30 +00:00
|
|
|
default:
|
|
|
|
return true;
|
2024-08-24 15:36:40 +00:00
|
|
|
}
|
|
|
|
}
|
2024-05-21 22:35:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Shader
|