video_core: Commonise rasterizer class

* Also added some comments providing some details about attribute loaders
This commit is contained in:
emufan4568
2022-08-09 18:56:14 +03:00
parent 1ded25f68b
commit 2397c82b85
16 changed files with 549 additions and 695 deletions

View File

@@ -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};
} }

View File

@@ -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,

View File

@@ -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;
}; };

View File

@@ -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;
}; };

View File

@@ -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

View File

@@ -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>;

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -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() {};

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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