shader: Implement tessellation shaders, polygon mode and invocation id

This commit is contained in:
ReinUsesLisp 2021-04-15 22:46:11 -03:00 committed by ameerj
parent 34519d3fc6
commit 183855e396
28 changed files with 605 additions and 91 deletions

View file

@ -331,6 +331,14 @@ void IREmitter::SetAttributeIndexed(const U32& phys_address, const F32& value, c
Inst(Opcode::SetAttributeIndexed, phys_address, value, vertex);
}
F32 IREmitter::GetPatch(Patch patch) {
return Inst<F32>(Opcode::GetPatch, patch);
}
void IREmitter::SetPatch(Patch patch, const F32& value) {
Inst(Opcode::SetPatch, patch, value);
}
void IREmitter::SetFragColor(u32 index, u32 component, const F32& value) {
Inst(Opcode::SetFragColor, Imm32(index), Imm32(component), value);
}
@ -363,6 +371,10 @@ U32 IREmitter::LocalInvocationIdZ() {
return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 2)};
}
U32 IREmitter::InvocationId() {
return Inst<U32>(Opcode::InvocationId);
}
U1 IREmitter::IsHelperInvocation() {
return Inst<U1>(Opcode::IsHelperInvocation);
}

View file

@ -84,6 +84,9 @@ public:
[[nodiscard]] F32 GetAttributeIndexed(const U32& phys_address, const U32& vertex);
void SetAttributeIndexed(const U32& phys_address, const F32& value, const U32& vertex);
[[nodiscard]] F32 GetPatch(Patch patch);
void SetPatch(Patch patch, const F32& value);
void SetFragColor(u32 index, u32 component, const F32& value);
void SetFragDepth(const F32& value);
@ -95,6 +98,7 @@ public:
[[nodiscard]] U32 LocalInvocationIdY();
[[nodiscard]] U32 LocalInvocationIdZ();
[[nodiscard]] U32 InvocationId();
[[nodiscard]] U1 IsHelperInvocation();
[[nodiscard]] U32 LaneId();

View file

@ -73,6 +73,7 @@ bool Inst::MayHaveSideEffects() const noexcept {
case Opcode::EndPrimitive:
case Opcode::SetAttribute:
case Opcode::SetAttributeIndexed:
case Opcode::SetPatch:
case Opcode::SetFragColor:
case Opcode::SetFragDepth:
case Opcode::WriteGlobalU8:

View file

@ -24,6 +24,7 @@ constexpr Type Label{Type::Label};
constexpr Type Reg{Type::Reg};
constexpr Type Pred{Type::Pred};
constexpr Type Attribute{Type::Attribute};
constexpr Type Patch{Type::Patch};
constexpr Type U1{Type::U1};
constexpr Type U8{Type::U8};
constexpr Type U16{Type::U16};

View file

@ -48,6 +48,8 @@ OPCODE(GetAttribute, F32, Attr
OPCODE(SetAttribute, Void, Attribute, F32, U32, )
OPCODE(GetAttributeIndexed, F32, U32, U32, )
OPCODE(SetAttributeIndexed, Void, U32, F32, U32, )
OPCODE(GetPatch, F32, Patch, )
OPCODE(SetPatch, Void, Patch, F32, )
OPCODE(SetFragColor, Void, U32, U32, F32, )
OPCODE(SetFragDepth, Void, F32, )
OPCODE(GetZFlag, U1, Void, )
@ -60,6 +62,7 @@ OPCODE(SetCFlag, Void, U1,
OPCODE(SetOFlag, Void, U1, )
OPCODE(WorkgroupId, U32x3, )
OPCODE(LocalInvocationId, U32x3, )
OPCODE(InvocationId, U32, )
OPCODE(IsHelperInvocation, U1, )
// Undefined

View file

@ -0,0 +1,28 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "shader_recompiler/frontend/ir/patch.h"
#include "shader_recompiler/exception.h"
namespace Shader::IR {
bool IsGeneric(Patch patch) noexcept {
return patch >= Patch::Component0 && patch <= Patch::Component119;
}
u32 GenericPatchIndex(Patch patch) {
if (!IsGeneric(patch)) {
throw InvalidArgument("Patch {} is not generic", patch);
}
return (static_cast<u32>(patch) - static_cast<u32>(Patch::Component0)) / 4;
}
u32 GenericPatchElement(Patch patch) {
if (!IsGeneric(patch)) {
throw InvalidArgument("Patch {} is not generic", patch);
}
return (static_cast<u32>(patch) - static_cast<u32>(Patch::Component0)) % 4;
}
} // namespace Shader::IR

View file

@ -0,0 +1,149 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace Shader::IR {
enum class Patch : u64 {
TessellationLodLeft,
TessellationLodTop,
TessellationLodRight,
TessellationLodBottom,
TessellationLodInteriorU,
TessellationLodInteriorV,
ComponentPadding0,
ComponentPadding1,
Component0,
Component1,
Component2,
Component3,
Component4,
Component5,
Component6,
Component7,
Component8,
Component9,
Component10,
Component11,
Component12,
Component13,
Component14,
Component15,
Component16,
Component17,
Component18,
Component19,
Component20,
Component21,
Component22,
Component23,
Component24,
Component25,
Component26,
Component27,
Component28,
Component29,
Component30,
Component31,
Component32,
Component33,
Component34,
Component35,
Component36,
Component37,
Component38,
Component39,
Component40,
Component41,
Component42,
Component43,
Component44,
Component45,
Component46,
Component47,
Component48,
Component49,
Component50,
Component51,
Component52,
Component53,
Component54,
Component55,
Component56,
Component57,
Component58,
Component59,
Component60,
Component61,
Component62,
Component63,
Component64,
Component65,
Component66,
Component67,
Component68,
Component69,
Component70,
Component71,
Component72,
Component73,
Component74,
Component75,
Component76,
Component77,
Component78,
Component79,
Component80,
Component81,
Component82,
Component83,
Component84,
Component85,
Component86,
Component87,
Component88,
Component89,
Component90,
Component91,
Component92,
Component93,
Component94,
Component95,
Component96,
Component97,
Component98,
Component99,
Component100,
Component101,
Component102,
Component103,
Component104,
Component105,
Component106,
Component107,
Component108,
Component109,
Component110,
Component111,
Component112,
Component113,
Component114,
Component115,
Component116,
Component117,
Component118,
Component119,
};
static_assert(static_cast<u64>(Patch::Component119) == 127);
[[nodiscard]] bool IsGeneric(Patch patch) noexcept;
[[nodiscard]] u32 GenericPatchIndex(Patch patch);
[[nodiscard]] u32 GenericPatchElement(Patch patch);
} // namespace Shader::IR

View file

@ -20,26 +20,27 @@ enum class Type {
Reg = 1 << 2,
Pred = 1 << 3,
Attribute = 1 << 4,
U1 = 1 << 5,
U8 = 1 << 6,
U16 = 1 << 7,
U32 = 1 << 8,
U64 = 1 << 9,
F16 = 1 << 10,
F32 = 1 << 11,
F64 = 1 << 12,
U32x2 = 1 << 13,
U32x3 = 1 << 14,
U32x4 = 1 << 15,
F16x2 = 1 << 16,
F16x3 = 1 << 17,
F16x4 = 1 << 18,
F32x2 = 1 << 19,
F32x3 = 1 << 20,
F32x4 = 1 << 21,
F64x2 = 1 << 22,
F64x3 = 1 << 23,
F64x4 = 1 << 24,
Patch = 1 << 5,
U1 = 1 << 6,
U8 = 1 << 7,
U16 = 1 << 8,
U32 = 1 << 9,
U64 = 1 << 10,
F16 = 1 << 11,
F32 = 1 << 12,
F64 = 1 << 13,
U32x2 = 1 << 14,
U32x3 = 1 << 15,
U32x4 = 1 << 16,
F16x2 = 1 << 17,
F16x3 = 1 << 18,
F16x4 = 1 << 19,
F32x2 = 1 << 20,
F32x3 = 1 << 21,
F32x4 = 1 << 22,
F64x2 = 1 << 23,
F64x3 = 1 << 24,
F64x4 = 1 << 25,
};
DECLARE_ENUM_FLAG_OPERATORS(Type)

View file

@ -18,6 +18,8 @@ Value::Value(IR::Pred value) noexcept : type{Type::Pred}, pred{value} {}
Value::Value(IR::Attribute value) noexcept : type{Type::Attribute}, attribute{value} {}
Value::Value(IR::Patch value) noexcept : type{Type::Patch}, patch{value} {}
Value::Value(bool value) noexcept : type{Type::U1}, imm_u1{value} {}
Value::Value(u8 value) noexcept : type{Type::U8}, imm_u8{value} {}
@ -109,6 +111,11 @@ IR::Attribute Value::Attribute() const {
return attribute;
}
IR::Patch Value::Patch() const {
ValidateAccess(Type::Patch);
return patch;
}
bool Value::U1() const {
if (IsIdentity()) {
return inst->Arg(0).U1();
@ -182,6 +189,8 @@ bool Value::operator==(const Value& other) const {
return pred == other.pred;
case Type::Attribute:
return attribute == other.attribute;
case Type::Patch:
return patch == other.patch;
case Type::U1:
return imm_u1 == other.imm_u1;
case Type::U8:

View file

@ -9,6 +9,7 @@
#include "shader_recompiler/frontend/ir/attribute.h"
#include "shader_recompiler/frontend/ir/pred.h"
#include "shader_recompiler/frontend/ir/reg.h"
#include "shader_recompiler/frontend/ir/patch.h"
#include "shader_recompiler/frontend/ir/type.h"
namespace Shader::IR {
@ -24,6 +25,7 @@ public:
explicit Value(IR::Reg value) noexcept;
explicit Value(IR::Pred value) noexcept;
explicit Value(IR::Attribute value) noexcept;
explicit Value(IR::Patch value) noexcept;
explicit Value(bool value) noexcept;
explicit Value(u8 value) noexcept;
explicit Value(u16 value) noexcept;
@ -46,6 +48,7 @@ public:
[[nodiscard]] IR::Reg Reg() const;
[[nodiscard]] IR::Pred Pred() const;
[[nodiscard]] IR::Attribute Attribute() const;
[[nodiscard]] IR::Patch Patch() const;
[[nodiscard]] bool U1() const;
[[nodiscard]] u8 U8() const;
[[nodiscard]] u16 U16() const;
@ -67,6 +70,7 @@ private:
IR::Reg reg;
IR::Pred pred;
IR::Attribute attribute;
IR::Patch patch;
bool imm_u1;
u8 imm_u8;
u16 imm_u16;