shader: Implement tessellation shaders, polygon mode and invocation id
This commit is contained in:
parent
34519d3fc6
commit
183855e396
28 changed files with 605 additions and 91 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
|
|
28
src/shader_recompiler/frontend/ir/patch.cpp
Normal file
28
src/shader_recompiler/frontend/ir/patch.cpp
Normal 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
|
149
src/shader_recompiler/frontend/ir/patch.h
Normal file
149
src/shader_recompiler/frontend/ir/patch.h
Normal 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
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue