video_core: Commonise rasterizer class
* Also added some comments providing some details about attribute loaders
This commit is contained in:
@@ -72,6 +72,9 @@ public:
|
|||||||
return Vec2{f, f};
|
return Vec2{f, f};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default comparison operators
|
||||||
|
[[nodiscard]] auto operator<=>(const Vec2& other) const = default;
|
||||||
|
|
||||||
[[nodiscard]] constexpr Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const {
|
[[nodiscard]] constexpr Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const {
|
||||||
return {x + other.x, y + other.y};
|
return {x + other.x, y + other.y};
|
||||||
}
|
}
|
||||||
@@ -230,6 +233,9 @@ public:
|
|||||||
return Vec3(f, f, f);
|
return Vec3(f, f, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default comparison operators
|
||||||
|
[[nodiscard]] auto operator<=>(const Vec3& other) const = default;
|
||||||
|
|
||||||
[[nodiscard]] constexpr Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const {
|
[[nodiscard]] constexpr Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const {
|
||||||
return {x + other.x, y + other.y, z + other.z};
|
return {x + other.x, y + other.y, z + other.z};
|
||||||
}
|
}
|
||||||
@@ -452,6 +458,9 @@ public:
|
|||||||
return Vec4(f, f, f, f);
|
return Vec4(f, f, f, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default comparison operators
|
||||||
|
[[nodiscard]] auto operator<=>(const Vec4& other) const = default;
|
||||||
|
|
||||||
[[nodiscard]] constexpr Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const {
|
[[nodiscard]] constexpr Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const {
|
||||||
return {x + other.x, y + other.y, z + other.z, w + other.w};
|
return {x + other.x, y + other.y, z + other.z, w + other.w};
|
||||||
}
|
}
|
||||||
|
@@ -42,15 +42,19 @@ public:
|
|||||||
// Creates a backend specific shader object
|
// Creates a backend specific shader object
|
||||||
virtual ShaderHandle CreateShader(ShaderStage stage, std::string_view name, std::string source) = 0;
|
virtual ShaderHandle CreateShader(ShaderStage stage, std::string_view name, std::string source) = 0;
|
||||||
|
|
||||||
|
// Binds a vertex buffer at a provided offset
|
||||||
|
virtual void BindVertexBuffer(BufferHandle buffer, std::span<const u32> offsets) = 0;
|
||||||
|
|
||||||
|
// Binds an index buffer at provided offset
|
||||||
|
virtual void BindIndexBuffer(BufferHandle buffer, AttribType index_type, u32 offset) = 0;
|
||||||
|
|
||||||
// Start a draw operation
|
// Start a draw operation
|
||||||
virtual void Draw(PipelineHandle pipeline, FramebufferHandle draw_framebuffer,
|
virtual void Draw(PipelineHandle pipeline, FramebufferHandle draw_framebuffer, u32 base_vertex,
|
||||||
BufferHandle vertex_buffer,
|
u32 num_vertices) = 0;
|
||||||
u32 base_vertex, u32 num_vertices) = 0;
|
|
||||||
|
|
||||||
// Start an indexed draw operation
|
// Start an indexed draw operation
|
||||||
virtual void DrawIndexed(PipelineHandle pipeline, FramebufferHandle draw_framebuffer,
|
virtual void DrawIndexed(PipelineHandle pipeline, FramebufferHandle draw_framebuffer, u32 base_vertex,
|
||||||
BufferHandle vertex_buffer, BufferHandle index_buffer, AttribType index_type,
|
u32 base_index, u32 num_indices) = 0;
|
||||||
u32 base_index, u32 num_indices, u32 base_vertex) = 0;
|
|
||||||
|
|
||||||
// Executes a compute shader
|
// Executes a compute shader
|
||||||
virtual void DispatchCompute(PipelineHandle pipeline, Common::Vec3<u32> groupsize,
|
virtual void DispatchCompute(PipelineHandle pipeline, Common::Vec3<u32> groupsize,
|
||||||
|
@@ -46,7 +46,7 @@ static_assert(std::is_standard_layout_v<BufferInfo>, "BufferInfo is not a standa
|
|||||||
class BufferBase : public IntrusivePtrEnabled<BufferBase> {
|
class BufferBase : public IntrusivePtrEnabled<BufferBase> {
|
||||||
public:
|
public:
|
||||||
BufferBase() = default;
|
BufferBase() = default;
|
||||||
BufferBase(const BufferInfo& info) : info(info), bind_range(info.capacity) {}
|
BufferBase(const BufferInfo& info) : info(info) {}
|
||||||
virtual ~BufferBase() = default;
|
virtual ~BufferBase() = default;
|
||||||
|
|
||||||
// Disable copy constructor
|
// Disable copy constructor
|
||||||
@@ -61,23 +61,6 @@ public:
|
|||||||
// Flushes write to buffer memory
|
// Flushes write to buffer memory
|
||||||
virtual void Commit(u32 size = 0) = 0;
|
virtual void Commit(u32 size = 0) = 0;
|
||||||
|
|
||||||
// Sets the range of the buffer that will be used when bound
|
|
||||||
void SetBindRange(u32 offset, u32 range) {
|
|
||||||
ASSERT(offset < info.capacity && offset + range < info.capacity);
|
|
||||||
bind_offset = offset;
|
|
||||||
bind_range = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the bind offset
|
|
||||||
u32 GetBindOffset() const {
|
|
||||||
return bind_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the number of bytes after bind_offset that will be bound
|
|
||||||
u32 GetBindRange() const {
|
|
||||||
return bind_range;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the size of the buffer in bytes
|
// Returns the size of the buffer in bytes
|
||||||
u32 GetCapacity() const {
|
u32 GetCapacity() const {
|
||||||
return info.capacity;
|
return info.capacity;
|
||||||
@@ -89,7 +72,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the starting offset of the currently mapped buffer slice
|
// Returns the starting offset of the currently mapped buffer slice
|
||||||
u64 GetCurrentOffset() const {
|
u32 GetCurrentOffset() const {
|
||||||
return buffer_offset;
|
return buffer_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,8 +89,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
BufferInfo info{};
|
BufferInfo info{};
|
||||||
u32 bind_offset = 0;
|
|
||||||
u32 bind_range; // Initialized to capacity
|
|
||||||
u32 buffer_offset = 0;
|
u32 buffer_offset = 0;
|
||||||
bool invalid = false;
|
bool invalid = false;
|
||||||
};
|
};
|
||||||
|
@@ -57,17 +57,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sets the area of the framebuffer affected by draw operations
|
// Sets the area of the framebuffer affected by draw operations
|
||||||
void SetDrawRect(Rect2D rect) {
|
void SetDrawRect(Common::Rectangle<u32> rect) {
|
||||||
draw_rect = rect;
|
draw_rect = rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the area of the framebuffer affected by draw operations
|
||||||
|
Common::Rectangle<u32> GetDrawRect() {
|
||||||
|
return draw_rect;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns how many samples the framebuffer takes
|
// Returns how many samples the framebuffer takes
|
||||||
MSAASamples GetMSAASamples() const {
|
MSAASamples GetMSAASamples() const {
|
||||||
return info.samples;
|
return info.samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Rect2D draw_rect;
|
Common::Rectangle<u32> draw_rect;
|
||||||
FramebufferInfo info;
|
FramebufferInfo info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -93,4 +93,14 @@ static_assert(sizeof(VSUniformData) == 1856,
|
|||||||
"The size of the VSUniformData structure has changed, update the structure in the shader");
|
"The size of the VSUniformData structure has changed, update the structure in the shader");
|
||||||
|
|
||||||
|
|
||||||
|
inline Common::Vec4f ColorRGBA8(const u32 color) {
|
||||||
|
return Common::Vec4f{(color >> 0 & 0xFF), (color >> 8 & 0xFF),
|
||||||
|
(color >> 16 & 0xFF), (color >> 24 & 0xFF)} / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Common::Vec3f LightColor(const Pica::LightingRegs::LightColor& color) {
|
||||||
|
return Common::Vec3f{color.r, color.g, color.b} / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace VideoCore
|
} // namespace VideoCore
|
||||||
|
@@ -17,7 +17,8 @@
|
|||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
constexpr u32 MAX_SHADER_STAGES = 3;
|
constexpr u32 MAX_SHADER_STAGES = 3;
|
||||||
constexpr u32 MAX_VERTEX_ATTRIBUTES = 8;
|
constexpr u32 MAX_VERTEX_ATTRIBUTES = 16;
|
||||||
|
constexpr u32 MAX_VERTEX_BINDINGS = 16;
|
||||||
constexpr u32 MAX_BINDINGS_IN_GROUP = 7;
|
constexpr u32 MAX_BINDINGS_IN_GROUP = 7;
|
||||||
constexpr u32 MAX_BINDING_GROUPS = 6;
|
constexpr u32 MAX_BINDING_GROUPS = 6;
|
||||||
|
|
||||||
@@ -74,16 +75,18 @@ union DepthStencilState {
|
|||||||
|
|
||||||
union BlendState {
|
union BlendState {
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
BitField<0, 4, Pica::BlendFactor> src_color_blend_factor;
|
BitField<0, 1, u32> blend_enable;
|
||||||
BitField<4, 4, Pica::BlendFactor> dst_color_blend_factor;
|
BitField<1, 4, Pica::BlendFactor> src_color_blend_factor;
|
||||||
BitField<8, 3, Pica::BlendEquation> color_blend_eq;
|
BitField<5, 4, Pica::BlendFactor> dst_color_blend_factor;
|
||||||
BitField<11, 4, Pica::BlendFactor> src_alpha_blend_factor;
|
BitField<9, 3, Pica::BlendEquation> color_blend_eq;
|
||||||
BitField<15, 4, Pica::BlendFactor> dst_alpha_blend_factor;
|
BitField<12, 4, Pica::BlendFactor> src_alpha_blend_factor;
|
||||||
BitField<19, 3, Pica::BlendEquation> alpha_blend_eq;
|
BitField<16, 4, Pica::BlendFactor> dst_alpha_blend_factor;
|
||||||
BitField<22, 4, u32> color_write_mask;
|
BitField<20, 3, Pica::BlendEquation> alpha_blend_eq;
|
||||||
|
BitField<23, 4, u32> color_write_mask;
|
||||||
|
BitField<27, 4, Pica::LogicOp> logic_op;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class AttribType : u8 {
|
enum class AttribType : u32 {
|
||||||
Float = 0,
|
Float = 0,
|
||||||
Int = 1,
|
Int = 1,
|
||||||
Short = 2,
|
Short = 2,
|
||||||
@@ -91,14 +94,25 @@ enum class AttribType : u8 {
|
|||||||
Ubyte = 4
|
Ubyte = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union VertexBinding {
|
||||||
|
BitField<0, 4, u16> binding;
|
||||||
|
BitField<4, 1, u16> fixed;
|
||||||
|
BitField<5, 11, u16> stride;
|
||||||
|
};
|
||||||
|
|
||||||
union VertexAttribute {
|
union VertexAttribute {
|
||||||
BitField<0, 3, AttribType> type;
|
BitField<0, 4, u32> binding;
|
||||||
BitField<3, 3, u8> components;
|
BitField<4, 4, u32> location;
|
||||||
|
BitField<8, 3, AttribType> type;
|
||||||
|
BitField<11, 3, u32> size;
|
||||||
|
BitField<14, 11, u32> offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct VertexLayout {
|
struct VertexLayout {
|
||||||
u8 stride = 0;
|
u8 binding_count = 0;
|
||||||
|
u8 attribute_count = 0;
|
||||||
|
std::array<VertexBinding, MAX_VERTEX_BINDINGS> bindings{};
|
||||||
std::array<VertexAttribute, MAX_VERTEX_ATTRIBUTES> attributes{};
|
std::array<VertexAttribute, MAX_VERTEX_ATTRIBUTES> attributes{};
|
||||||
};
|
};
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
@@ -123,11 +137,12 @@ struct PipelineInfo {
|
|||||||
};
|
};
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
constexpr s32 WHOLE_SIZE = -1;
|
||||||
|
|
||||||
// An opaque handle to a backend specific program pipeline
|
// An opaque handle to a backend specific program pipeline
|
||||||
class PipelineBase : public IntrusivePtrEnabled<PipelineBase> {
|
class PipelineBase : public IntrusivePtrEnabled<PipelineBase> {
|
||||||
public:
|
public:
|
||||||
PipelineBase(PipelineType type, PipelineInfo info) :
|
PipelineBase(PipelineType type, PipelineInfo info) : info(info), type(type) {}
|
||||||
type(type), info(info) {}
|
|
||||||
virtual ~PipelineBase() = default;
|
virtual ~PipelineBase() = default;
|
||||||
|
|
||||||
// Disable copy constructor
|
// Disable copy constructor
|
||||||
@@ -138,83 +153,26 @@ public:
|
|||||||
virtual void BindTexture(u32 group, u32 slot, TextureHandle handle) = 0;
|
virtual void BindTexture(u32 group, u32 slot, TextureHandle handle) = 0;
|
||||||
|
|
||||||
// Binds the texture in the specified slot
|
// Binds the texture in the specified slot
|
||||||
virtual void BindBuffer(u32 group, u32 slot, BufferHandle handle, u32 view = 0) = 0;
|
virtual void BindBuffer(u32 group, u32 slot, BufferHandle handle,
|
||||||
|
u32 offset = 0, u32 range = WHOLE_SIZE, u32 view = 0) = 0;
|
||||||
|
|
||||||
// Binds the sampler in the specified slot
|
// Binds the sampler in the specified slot
|
||||||
virtual void BindSampler(u32 group, u32 slot, SamplerHandle handle) = 0;
|
virtual void BindSampler(u32 group, u32 slot, SamplerHandle handle) = 0;
|
||||||
|
|
||||||
|
// Sets the viewport of the pipeline
|
||||||
|
virtual void SetViewport(Rect2D viewport) = 0;
|
||||||
|
|
||||||
|
// Sets the scissor of the pipeline
|
||||||
|
virtual void SetScissor(Rect2D scissor) = 0;
|
||||||
|
|
||||||
|
// Returns the pipeline type (Graphics or Compute)
|
||||||
PipelineType GetType() const {
|
PipelineType GetType() const {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the primitive topology
|
|
||||||
void SetTopology(Pica::TriangleTopology topology) {
|
|
||||||
info.rasterization.topology.Assign(topology);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the culling mode
|
|
||||||
void SetCullMode(Pica::CullMode mode) {
|
|
||||||
info.rasterization.cull_mode.Assign(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the color blending function
|
|
||||||
void SetColorBlendFunc(Pica::BlendFactor src_color_factor,
|
|
||||||
Pica::BlendFactor dst_color_factor,
|
|
||||||
Pica::BlendEquation color_eq) {
|
|
||||||
info.blending.src_color_blend_factor.Assign(src_color_factor);
|
|
||||||
info.blending.dst_color_blend_factor.Assign(dst_color_factor);
|
|
||||||
info.blending.color_blend_eq.Assign(color_eq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the alpha blending function
|
|
||||||
void SetAlphaBlendFunc(Pica::BlendFactor src_alpha_factor,
|
|
||||||
Pica::BlendFactor dst_alpha_factor,
|
|
||||||
Pica::BlendEquation alpha_eq) {
|
|
||||||
info.blending.src_alpha_blend_factor.Assign(src_alpha_factor);
|
|
||||||
info.blending.dst_alpha_blend_factor.Assign(dst_alpha_factor);
|
|
||||||
info.blending.alpha_blend_eq.Assign(alpha_eq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the color write mask
|
|
||||||
void SetColorWriteMask(u32 mask) {
|
|
||||||
info.blending.color_write_mask.Assign(mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the depth test
|
|
||||||
void SetDepthTest(bool enable, Pica::CompareFunc compare_op) {
|
|
||||||
info.depth_stencil.depth_test_enable.Assign(enable);
|
|
||||||
info.depth_stencil.depth_compare_op.Assign(compare_op);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enables or disables depth writes
|
|
||||||
void SetDepthWrites(bool enable) {
|
|
||||||
info.depth_stencil.depth_write_enable.Assign(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the stencil test
|
|
||||||
void SetStencilTest(bool enable, Pica::StencilAction fail, Pica::StencilAction pass,
|
|
||||||
Pica::StencilAction depth_fail, Pica::CompareFunc compare, u32 ref) {
|
|
||||||
info.depth_stencil.stencil_test_enable.Assign(enable);
|
|
||||||
info.depth_stencil.stencil_fail_op.Assign(fail);
|
|
||||||
info.depth_stencil.stencil_pass_op.Assign(pass);
|
|
||||||
info.depth_stencil.stencil_depth_fail_op.Assign(depth_fail);
|
|
||||||
info.depth_stencil.stencil_compare_op.Assign(compare);
|
|
||||||
info.depth_stencil.stencil_reference.Assign(ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Selects the bits of the stencil values participating in the stencil test
|
|
||||||
void SetStencilCompareMask(u32 mask) {
|
|
||||||
info.depth_stencil.stencil_compare_mask.Assign(mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Selects the bits of the stencil values updated by the stencil test
|
|
||||||
void SetStencilWriteMask(u32 mask) {
|
|
||||||
info.depth_stencil.stencil_write_mask.Assign(mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PipelineInfo info;
|
||||||
PipelineType type = PipelineType::Graphics;
|
PipelineType type = PipelineType::Graphics;
|
||||||
PipelineInfo info{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using PipelineHandle = IntrusivePtr<PipelineBase>;
|
using PipelineHandle = IntrusivePtr<PipelineBase>;
|
||||||
|
@@ -44,6 +44,22 @@ PipelineCache::PipelineCache(Frontend::EmuWindow& emu_window, std::unique_ptr<Ba
|
|||||||
//generator = std::make_unique<ShaderGenerator
|
//generator = std::make_unique<ShaderGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PipelineHandle PipelineCache::GetPipeline(PipelineInfo& info) {
|
||||||
|
// Update shader handles
|
||||||
|
info.shaders[static_cast<u32>(ProgramType::VertexShader)] = current_vertex_shader;
|
||||||
|
info.shaders[static_cast<u32>(ProgramType::GeometryShader)] = current_geometry_shader;
|
||||||
|
info.shaders[static_cast<u32>(ProgramType::FragmentShader)] = current_fragment_shader;
|
||||||
|
|
||||||
|
// Search cache
|
||||||
|
if (auto iter = cached_pipelines.find(info); iter != cached_pipelines.end()) {
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new pipeline
|
||||||
|
auto iter = cached_pipelines.emplace(info, backend->CreatePipeline(PipelineType::Graphics, info)).first;
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
bool PipelineCache::UsePicaVertexShader(const Pica::Regs& regs, Pica::Shader::ShaderSetup& setup) {
|
bool PipelineCache::UsePicaVertexShader(const Pica::Regs& regs, Pica::Shader::ShaderSetup& setup) {
|
||||||
PicaVSConfig config{regs.vs, setup};
|
PicaVSConfig config{regs.vs, setup};
|
||||||
auto [handle, shader_str] = pica_vertex_shaders.Get(config, setup);
|
auto [handle, shader_str] = pica_vertex_shaders.Get(config, setup);
|
||||||
|
@@ -38,6 +38,9 @@ public:
|
|||||||
PipelineCache(Frontend::EmuWindow& emu_window, std::unique_ptr<BackendBase>& backend);
|
PipelineCache(Frontend::EmuWindow& emu_window, std::unique_ptr<BackendBase>& backend);
|
||||||
~PipelineCache() = default;
|
~PipelineCache() = default;
|
||||||
|
|
||||||
|
// Searches the cache for pipelines matching the information structure
|
||||||
|
PipelineHandle GetPipeline(PipelineInfo& info);
|
||||||
|
|
||||||
// Loads backend specific shader binaries from disk
|
// Loads backend specific shader binaries from disk
|
||||||
void LoadDiskCache(const std::atomic_bool& stop_loading, const DiskLoadCallback& callback);
|
void LoadDiskCache(const std::atomic_bool& stop_loading, const DiskLoadCallback& callback);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -4,29 +4,27 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
|
||||||
#include "common/vector_math.h"
|
|
||||||
#include "video_core/regs_lighting.h"
|
|
||||||
#include "video_core/regs_texturing.h"
|
|
||||||
#include "video_core/common/rasterizer_cache.h"
|
#include "video_core/common/rasterizer_cache.h"
|
||||||
|
#include "video_core/common/pica_uniforms.h"
|
||||||
#include "video_core/common/pipeline.h"
|
#include "video_core/common/pipeline.h"
|
||||||
#include "video_core/shader/shader.h"
|
|
||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
class ShaderProgramManager;
|
class PipelineCache;
|
||||||
|
|
||||||
/// Structure that the hardware rendered vertices are composed of
|
class Callback;
|
||||||
|
using DiskLoadCallback = Callback;
|
||||||
|
|
||||||
|
// Structure that the hardware rendered vertices are composed of
|
||||||
struct HardwareVertex {
|
struct HardwareVertex {
|
||||||
HardwareVertex() = default;
|
HardwareVertex() = default;
|
||||||
HardwareVertex(const Pica::Shader::OutputVertex& v, bool flip_quaternion);
|
HardwareVertex(const Pica::Shader::OutputVertex& v, bool flip_quaternion);
|
||||||
|
|
||||||
// Returns the pipeline vertex layout of the vertex
|
// Returns the pipeline vertex layout of the vertex used with software shaders
|
||||||
constexpr static VertexLayout GetVertexLayout();
|
constexpr static VertexLayout GetVertexLayout();
|
||||||
|
|
||||||
Common::Vec4f position;
|
Common::Vec4f position;
|
||||||
@@ -46,8 +44,7 @@ public:
|
|||||||
explicit Rasterizer(Frontend::EmuWindow& emu_window, std::unique_ptr<BackendBase>& backend);
|
explicit Rasterizer(Frontend::EmuWindow& emu_window, std::unique_ptr<BackendBase>& backend);
|
||||||
~Rasterizer();
|
~Rasterizer();
|
||||||
|
|
||||||
//void LoadDiskResources(const std::atomic_bool& stop_loading,
|
void LoadDiskResources(const std::atomic_bool& stop_loading, const DiskLoadCallback& callback);
|
||||||
// const VideoCore::DiskResourceLoadCallback& callback);
|
|
||||||
|
|
||||||
void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1,
|
void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1,
|
||||||
const Pica::Shader::OutputVertex& v2);
|
const Pica::Shader::OutputVertex& v2);
|
||||||
@@ -58,6 +55,7 @@ public:
|
|||||||
void InvalidateRegion(PAddr addr, u32 size);
|
void InvalidateRegion(PAddr addr, u32 size);
|
||||||
void FlushAndInvalidateRegion(PAddr addr, u32 size);
|
void FlushAndInvalidateRegion(PAddr addr, u32 size);
|
||||||
void ClearAll(bool flush);
|
void ClearAll(bool flush);
|
||||||
|
|
||||||
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config);
|
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config);
|
||||||
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config);
|
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config);
|
||||||
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config);
|
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config);
|
||||||
@@ -170,13 +168,13 @@ private:
|
|||||||
void SyncAndUploadLUTsLF();
|
void SyncAndUploadLUTsLF();
|
||||||
|
|
||||||
/// Upload the uniform blocks to the uniform buffer object
|
/// Upload the uniform blocks to the uniform buffer object
|
||||||
void UploadUniforms(bool accelerate_draw);
|
void UploadUniforms(PipelineHandle pipeline, bool accelerate_draw);
|
||||||
|
|
||||||
/// Generic draw function for DrawTriangles and AccelerateDrawBatch
|
/// Generic draw function for DrawTriangles and AccelerateDrawBatch
|
||||||
bool Draw(bool accelerate, bool is_indexed);
|
bool Draw(bool accelerate, bool is_indexed);
|
||||||
|
|
||||||
/// Internal implementation for AccelerateDrawBatch
|
/// Internal implementation for AccelerateDrawBatch
|
||||||
bool AccelerateDrawBatchInternal(bool is_indexed);
|
bool AccelerateDrawBatchInternal(PipelineHandle pipeline, FramebufferHandle framebuffer, bool is_indexed);
|
||||||
|
|
||||||
struct VertexArrayInfo {
|
struct VertexArrayInfo {
|
||||||
u32 vs_input_index_min;
|
u32 vs_input_index_min;
|
||||||
@@ -188,7 +186,7 @@ private:
|
|||||||
VertexArrayInfo AnalyzeVertexArray(bool is_indexed);
|
VertexArrayInfo AnalyzeVertexArray(bool is_indexed);
|
||||||
|
|
||||||
/// Setup vertex array for AccelerateDrawBatch
|
/// Setup vertex array for AccelerateDrawBatch
|
||||||
void SetupVertexArray(u8* array_ptr, u32 buffer_offset, u32 vs_input_index_min, u32 vs_input_index_max);
|
void SetupVertexArray(u32 vs_input_size, u32 vs_input_index_min, u32 vs_input_index_max);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<BackendBase>& backend;
|
std::unique_ptr<BackendBase>& backend;
|
||||||
@@ -209,13 +207,17 @@ private:
|
|||||||
bool dirty = true;
|
bool dirty = true;
|
||||||
} uniform_block_data{};
|
} uniform_block_data{};
|
||||||
|
|
||||||
std::unique_ptr<ShaderProgramManager> shader_program_manager;
|
// Pipeline information structure used to identify a rasterizer pipeline
|
||||||
|
// The shader handles are automatically filled by the pipeline cache
|
||||||
|
PipelineInfo raster_info{};
|
||||||
|
std::unique_ptr<PipelineCache> pipeline_cache;
|
||||||
|
|
||||||
// Clear texture for placeholder purposes
|
// Clear texture for placeholder purposes
|
||||||
TextureHandle clear_texture;
|
TextureHandle clear_texture;
|
||||||
|
|
||||||
// Uniform alignment
|
// Uniform alignment
|
||||||
std::array<bool, 16> hw_vao_enabled_attributes{};
|
std::array<bool, 16> hw_vao_enabled_attributes{};
|
||||||
|
std::size_t uniform_buffer_alignment;
|
||||||
std::size_t uniform_size_aligned_vs = 0;
|
std::size_t uniform_size_aligned_vs = 0;
|
||||||
std::size_t uniform_size_aligned_fs = 0;
|
std::size_t uniform_size_aligned_fs = 0;
|
||||||
|
|
||||||
@@ -229,8 +231,8 @@ private:
|
|||||||
std::array<Common::Vec2f, 128> proctex_noise_lut_data{};
|
std::array<Common::Vec2f, 128> proctex_noise_lut_data{};
|
||||||
std::array<Common::Vec2f, 128> proctex_color_map_data{};
|
std::array<Common::Vec2f, 128> proctex_color_map_data{};
|
||||||
std::array<Common::Vec2f, 128> proctex_alpha_map_data{};
|
std::array<Common::Vec2f, 128> proctex_alpha_map_data{};
|
||||||
std::array<Common::Vec2f, 256> proctex_lut_data{};
|
std::array<Common::Vec4f, 256> proctex_lut_data{};
|
||||||
std::array<Common::Vec2f, 256> proctex_diff_lut_data{};
|
std::array<Common::Vec4f, 256> proctex_diff_lut_data{};
|
||||||
|
|
||||||
// Texture unit sampler cache
|
// Texture unit sampler cache
|
||||||
SamplerInfo texture_cube_sampler;
|
SamplerInfo texture_cube_sampler;
|
||||||
|
@@ -1166,7 +1166,7 @@ const CachedTextureCube& RasterizerCache::GetTextureCube(const TextureCubeConfig
|
|||||||
return cube;
|
return cube;
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferHandle RasterizerCache::GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
|
SurfaceSurfaceRect_Tuple RasterizerCache::GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
|
||||||
Common::Rectangle<s32> viewport_rect) {
|
Common::Rectangle<s32> viewport_rect) {
|
||||||
const auto& config = Pica::g_state.regs.framebuffer.framebuffer;
|
const auto& config = Pica::g_state.regs.framebuffer.framebuffer;
|
||||||
|
|
||||||
@@ -1256,9 +1256,13 @@ FramebufferHandle RasterizerCache::GetFramebufferSurfaces(bool using_color_fb, b
|
|||||||
depth_surface->InvalidateAllWatcher();
|
depth_surface->InvalidateAllWatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::make_tuple(color_surface, depth_surface, fb_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
FramebufferHandle RasterizerCache::GetFramebuffer(const Surface& color, const Surface& depth_stencil) {
|
||||||
const FramebufferInfo framebuffer_info = {
|
const FramebufferInfo framebuffer_info = {
|
||||||
.color = using_color_fb ? color_surface->texture : TextureHandle{},
|
.color = color ? color->texture : TextureHandle{},
|
||||||
.depth_stencil = using_depth_fb ? depth_surface->texture : TextureHandle{}
|
.depth_stencil = depth_stencil ? depth_stencil->texture : TextureHandle{}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Search the framebuffer cache, otherwise create new framebuffer
|
// Search the framebuffer cache, otherwise create new framebuffer
|
||||||
@@ -1270,7 +1274,6 @@ FramebufferHandle RasterizerCache::GetFramebufferSurfaces(bool using_color_fb, b
|
|||||||
framebuffer_cache.emplace(framebuffer_info, framebuffer);
|
framebuffer_cache.emplace(framebuffer_info, framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
framebuffer->SetDrawRect(fb_rect);
|
|
||||||
return framebuffer;
|
return framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,14 +4,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <boost/icl/interval_map.hpp>
|
#include <boost/icl/interval_map.hpp>
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/math_util.h"
|
|
||||||
#include "core/custom_tex_cache.h"
|
#include "core/custom_tex_cache.h"
|
||||||
#include "video_core/common/surface_params.h"
|
#include "video_core/common/surface_params.h"
|
||||||
#include "video_core/common/texture.h"
|
#include "video_core/common/texture.h"
|
||||||
@@ -233,9 +230,12 @@ public:
|
|||||||
const CachedTextureCube& GetTextureCube(const TextureCubeConfig& config);
|
const CachedTextureCube& GetTextureCube(const TextureCubeConfig& config);
|
||||||
|
|
||||||
// Get the color and depth surfaces based on the framebuffer configuration
|
// Get the color and depth surfaces based on the framebuffer configuration
|
||||||
FramebufferHandle GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
|
SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
|
||||||
Common::Rectangle<s32> viewport_rect);
|
Common::Rectangle<s32> viewport_rect);
|
||||||
|
|
||||||
|
// Get the framebuffer for the provided color and depth surfaces
|
||||||
|
FramebufferHandle GetFramebuffer(const Surface& color, const Surface& depth_stencil);
|
||||||
|
|
||||||
// Get a surface that matches the fill config
|
// Get a surface that matches the fill config
|
||||||
Surface GetFillSurface(const GPU::Regs::MemoryFillConfig& config);
|
Surface GetFillSurface(const GPU::Regs::MemoryFillConfig& config);
|
||||||
|
|
||||||
|
@@ -112,6 +112,9 @@ public:
|
|||||||
u32 src_level = 0, u32 dest_level = 0,
|
u32 src_level = 0, u32 dest_level = 0,
|
||||||
u32 src_layer = 0, u32 dest_layer = 0) {};
|
u32 src_layer = 0, u32 dest_layer = 0) {};
|
||||||
|
|
||||||
|
// Copies texture data from the source texture
|
||||||
|
virtual void CopyFrom(TextureHandle source) {};
|
||||||
|
|
||||||
// Generates all possible mipmaps from the texture
|
// Generates all possible mipmaps from the texture
|
||||||
virtual void GenerateMipmaps() {};
|
virtual void GenerateMipmaps() {};
|
||||||
|
|
||||||
|
@@ -161,6 +161,7 @@ struct FramebufferRegs {
|
|||||||
} stencil_test;
|
} stencil_test;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
u32 depth_color_mask;
|
||||||
BitField<0, 1, u32> depth_test_enable;
|
BitField<0, 1, u32> depth_test_enable;
|
||||||
BitField<4, 3, CompareFunc> depth_test_func;
|
BitField<4, 3, CompareFunc> depth_test_func;
|
||||||
BitField<8, 1, u32> red_enable;
|
BitField<8, 1, u32> red_enable;
|
||||||
|
@@ -84,9 +84,17 @@ struct PipelineRegs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 GetElementSizeInBytes(std::size_t n) const {
|
u32 GetElementSizeInBytes(std::size_t n) const {
|
||||||
return (GetFormat(n) == VertexAttributeFormat::FLOAT)
|
switch (GetFormat(n)) {
|
||||||
? 4
|
case VertexAttributeFormat::FLOAT:
|
||||||
: (GetFormat(n) == VertexAttributeFormat::SHORT) ? 2 : 1;
|
return 4;
|
||||||
|
case VertexAttributeFormat::SHORT:
|
||||||
|
return 2;
|
||||||
|
case VertexAttributeFormat::BYTE:
|
||||||
|
case VertexAttributeFormat::UBYTE:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
LOG_ERROR(HW_GPU, "Unknown vertex attribute format {}!", GetFormat(n));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetStride(std::size_t n) const {
|
u32 GetStride(std::size_t n) const {
|
||||||
|
@@ -67,6 +67,9 @@ u32 AttribBytes(VertexAttribute attrib) {
|
|||||||
return sizeof(u32) * attrib.components;
|
return sizeof(u32) * attrib.components;
|
||||||
case AttribType::Short:
|
case AttribType::Short:
|
||||||
return sizeof(u16) * attrib.components;
|
return sizeof(u16) * attrib.components;
|
||||||
|
case AttribType::Byte:
|
||||||
|
case AttribType::Ubyte:
|
||||||
|
return sizeof(u8) * attrib.components;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +211,12 @@ Pipeline::Pipeline(Instance& instance, PipelineLayout& owner, PipelineType type,
|
|||||||
|
|
||||||
// Create a graphics pipeline
|
// Create a graphics pipeline
|
||||||
if (type == PipelineType::Graphics) {
|
if (type == PipelineType::Graphics) {
|
||||||
|
/**
|
||||||
|
* Most modern graphics APIs don't natively support constant attributes. To avoid duplicating
|
||||||
|
* the data and increasing data bandwith, we reserve the last binding for fixed attributes,
|
||||||
|
* which are always interleaved and specify VK_VERTEX_INPUT_RATE_INSTANCE as the input rate.
|
||||||
|
* Since we are always rendering 1 instance, the shader will always read the single attribute
|
||||||
|
*/
|
||||||
const vk::VertexInputBindingDescription binding_desc = {
|
const vk::VertexInputBindingDescription binding_desc = {
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.stride = info.vertex_layout.stride
|
.stride = info.vertex_layout.stride
|
||||||
|
Reference in New Issue
Block a user