Merge pull request #9633 from Pokechu22/BitfieldExtract-pointer-to-member

Change BitfieldExtract to use a pointer to the bitfield member
This commit is contained in:
Léo Lam 2021-05-08 00:21:15 +02:00 committed by GitHub
commit a6f6211dde
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 164 additions and 79 deletions

View file

@ -155,8 +155,8 @@ public:
constexpr T Value() const { return Value(std::is_signed<T>()); }
constexpr operator T() const { return Value(); }
constexpr std::size_t StartBit() const { return position; }
constexpr std::size_t NumBits() const { return bits; }
static constexpr std::size_t StartBit() { return position; }
static constexpr std::size_t NumBits() { return bits; }
private:
// Unsigned version of StorageType

View file

@ -125,6 +125,7 @@ add_library(common
TraversalClient.cpp
TraversalClient.h
TraversalProto.h
TypeUtils.h
UPnP.cpp
UPnP.h
VariantUtil.h

View file

@ -0,0 +1,70 @@
// Copyright 2021 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <type_traits>
namespace Common
{
template <typename>
struct MemberPointerInfo;
// Helper to get information about a pointer to a data member.
// See https://en.cppreference.com/w/cpp/language/pointer#Pointers_to_members
// This template takes the type for a member pointer.
template <typename M, typename O>
struct MemberPointerInfo<M O::*>
{
using MemberType = M;
using ObjectType = O;
};
// This template takes a specific member pointer.
template <auto member_pointer>
using MemberType = typename MemberPointerInfo<decltype(member_pointer)>::MemberType;
// This template takes a specific member pointer.
template <auto member_pointer>
using ObjectType = typename MemberPointerInfo<decltype(member_pointer)>::ObjectType;
namespace detail
{
template <int x>
struct Data
{
static constexpr int GetX() { return x; }
};
struct Foo
{
Data<1> a;
Data<2> b;
int c;
};
struct Bar : Foo
{
int d;
};
static_assert(std::is_same_v<MemberType<&Foo::a>, Data<1>>);
static_assert(MemberType<&Foo::a>::GetX() == 1);
static_assert(std::is_same_v<MemberType<&Foo::b>, Data<2>>);
static_assert(MemberType<&Foo::b>::GetX() == 2);
static_assert(std::is_same_v<MemberType<&Foo::c>, int>);
static_assert(std::is_same_v<ObjectType<&Foo::a>, Foo>);
static_assert(std::is_same_v<ObjectType<&Foo::b>, Foo>);
static_assert(std::is_same_v<ObjectType<&Foo::c>, Foo>);
static_assert(std::is_same_v<MemberType<&Foo::c>, MemberPointerInfo<int Foo::*>::MemberType>);
static_assert(std::is_same_v<ObjectType<&Foo::c>, MemberPointerInfo<int Foo::*>::ObjectType>);
static_assert(std::is_same_v<MemberType<&Bar::c>, int>);
static_assert(std::is_same_v<MemberType<&Bar::d>, int>);
static_assert(std::is_same_v<ObjectType<&Bar::d>, Bar>);
// Somewhat unexpected behavior:
static_assert(std::is_same_v<ObjectType<&Bar::c>, Foo>);
static_assert(!std::is_same_v<ObjectType<&Bar::c>, Bar>);
} // namespace detail
} // namespace Common

View file

@ -152,6 +152,7 @@
<ClInclude Include="Common\Timer.h" />
<ClInclude Include="Common\TraversalClient.h" />
<ClInclude Include="Common\TraversalProto.h" />
<ClInclude Include="Common\TypeUtils.h" />
<ClInclude Include="Common\UPnP.h" />
<ClInclude Include="Common\VariantUtil.h" />
<ClInclude Include="Common\Version.h" />

View file

@ -103,29 +103,29 @@ void WriteVertexLighting(ShaderCode& out, APIType api_type, std::string_view wor
" int4 lacc = int4(255, 255, 255, 255);\n"
"\n");
out.Write(" if ({} != 0u)\n", BitfieldExtract("colorreg", LitChannel().matsource));
out.Write(" if ({} != 0u)\n", BitfieldExtract<&LitChannel::matsource>("colorreg"));
out.Write(" mat.xyz = int3(round(((chan == 0u) ? {}.xyz : {}.xyz) * 255.0));\n",
in_color_0_var, in_color_1_var);
out.Write(" if ({} != 0u)\n", BitfieldExtract("alphareg", LitChannel().matsource));
out.Write(" if ({} != 0u)\n", BitfieldExtract<&LitChannel::matsource>("alphareg"));
out.Write(" mat.w = int(round(((chan == 0u) ? {}.w : {}.w) * 255.0));\n", in_color_0_var,
in_color_1_var);
out.Write(" else\n"
" mat.w = " I_MATERIALS " [chan + 2u].w;\n"
"\n");
out.Write(" if ({} != 0u) {{\n", BitfieldExtract("colorreg", LitChannel().enablelighting));
out.Write(" if ({} != 0u)\n", BitfieldExtract("colorreg", LitChannel().ambsource));
out.Write(" if ({} != 0u) {{\n", BitfieldExtract<&LitChannel::enablelighting>("colorreg"));
out.Write(" if ({} != 0u)\n", BitfieldExtract<&LitChannel::ambsource>("colorreg"));
out.Write(" lacc.xyz = int3(round(((chan == 0u) ? {}.xyz : {}.xyz) * 255.0));\n",
in_color_0_var, in_color_1_var);
out.Write(" else\n"
" lacc.xyz = " I_MATERIALS " [chan].xyz;\n"
"\n");
out.Write(" uint light_mask = {} | ({} << 4u);\n",
BitfieldExtract("colorreg", LitChannel().lightMask0_3),
BitfieldExtract("colorreg", LitChannel().lightMask4_7));
out.Write(" uint attnfunc = {};\n", BitfieldExtract("colorreg", LitChannel().attnfunc));
out.Write(" uint diffusefunc = {};\n", BitfieldExtract("colorreg", LitChannel().diffusefunc));
BitfieldExtract<&LitChannel::lightMask0_3>("colorreg"),
BitfieldExtract<&LitChannel::lightMask4_7>("colorreg"));
out.Write(" uint attnfunc = {};\n", BitfieldExtract<&LitChannel::attnfunc>("colorreg"));
out.Write(" uint diffusefunc = {};\n", BitfieldExtract<&LitChannel::diffusefunc>("colorreg"));
out.Write(
" for (uint light_index = 0u; light_index < 8u; light_index++) {{\n"
" if ((light_mask & (1u << light_index)) != 0u)\n"
@ -135,8 +135,8 @@ void WriteVertexLighting(ShaderCode& out, APIType api_type, std::string_view wor
" }}\n"
"\n");
out.Write(" if ({} != 0u) {{\n", BitfieldExtract("alphareg", LitChannel().enablelighting));
out.Write(" if ({} != 0u) {{\n", BitfieldExtract("alphareg", LitChannel().ambsource));
out.Write(" if ({} != 0u) {{\n", BitfieldExtract<&LitChannel::enablelighting>("alphareg"));
out.Write(" if ({} != 0u) {{\n", BitfieldExtract<&LitChannel::ambsource>("alphareg"));
out.Write(" if ((components & ({}u << chan)) != 0u) // VB_HAS_COL0\n", VB_HAS_COL0);
out.Write(" lacc.w = int(round(((chan == 0u) ? {}.w : {}.w) * 255.0));\n", in_color_0_var,
in_color_1_var);
@ -149,10 +149,10 @@ void WriteVertexLighting(ShaderCode& out, APIType api_type, std::string_view wor
" }}\n"
"\n");
out.Write(" uint light_mask = {} | ({} << 4u);\n",
BitfieldExtract("alphareg", LitChannel().lightMask0_3),
BitfieldExtract("alphareg", LitChannel().lightMask4_7));
out.Write(" uint attnfunc = {};\n", BitfieldExtract("alphareg", LitChannel().attnfunc));
out.Write(" uint diffusefunc = {};\n", BitfieldExtract("alphareg", LitChannel().diffusefunc));
BitfieldExtract<&LitChannel::lightMask0_3>("alphareg"),
BitfieldExtract<&LitChannel::lightMask4_7>("alphareg"));
out.Write(" uint attnfunc = {};\n", BitfieldExtract<&LitChannel::attnfunc>("alphareg"));
out.Write(" uint diffusefunc = {};\n", BitfieldExtract<&LitChannel::diffusefunc>("alphareg"));
out.Write(" for (uint light_index = 0u; light_index < 8u; light_index++) {{\n\n"
" if ((light_mask & (1u << light_index)) != 0u)\n\n"
" lacc.w += CalculateLighting(light_index, attnfunc, diffusefunc, {}, {}).w;\n",

View file

@ -10,6 +10,7 @@
#include <fmt/format.h>
#include "Common/CommonTypes.h"
#include "Common/TypeUtils.h"
class ShaderCode;
enum class APIType;
@ -29,10 +30,11 @@ void WriteVertexLighting(ShaderCode& out, APIType api_type, std::string_view wor
std::string_view out_color_1_var);
// bitfieldExtract generator for BitField types
template <typename T>
std::string BitfieldExtract(std::string_view source, T type)
template <auto ptr_to_bitfield_member>
std::string BitfieldExtract(std::string_view source)
{
return fmt::format("bitfieldExtract({}, {}, {})", source, static_cast<u32>(type.StartBit()),
static_cast<u32>(type.NumBits()));
using BitFieldT = Common::MemberType<ptr_to_bitfield_member>;
return fmt::format("bitfieldExtract({}, {}, {})", source, static_cast<u32>(BitFieldT::StartBit()),
static_cast<u32>(BitFieldT::NumBits()));
}
} // namespace UberShader

View file

@ -261,12 +261,12 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" // AKA: Color Channel Swapping\n"
"\n"
" int4 ret;\n");
out.Write(" ret.r = color[{}];\n", BitfieldExtract("bpmem_tevksel(s * 2u)", TevKSel().swap1));
out.Write(" ret.g = color[{}];\n", BitfieldExtract("bpmem_tevksel(s * 2u)", TevKSel().swap2));
out.Write(" ret.r = color[{}];\n", BitfieldExtract<&TevKSel::swap1>("bpmem_tevksel(s * 2u)"));
out.Write(" ret.g = color[{}];\n", BitfieldExtract<&TevKSel::swap2>("bpmem_tevksel(s * 2u)"));
out.Write(" ret.b = color[{}];\n",
BitfieldExtract("bpmem_tevksel(s * 2u + 1u)", TevKSel().swap1));
BitfieldExtract<&TevKSel::swap1>("bpmem_tevksel(s * 2u + 1u)"));
out.Write(" ret.a = color[{}];\n",
BitfieldExtract("bpmem_tevksel(s * 2u + 1u)", TevKSel().swap2));
BitfieldExtract<&TevKSel::swap2>("bpmem_tevksel(s * 2u + 1u)"));
out.Write(" return ret;\n"
"}}\n\n");
@ -765,7 +765,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
}
out.Write(" uint num_stages = {};\n\n",
BitfieldExtract("bpmem_genmode", bpmem.genMode.numtevstages));
BitfieldExtract<&GenMode::numtevstages>("bpmem_genmode"));
out.Write(" // Main tev loop\n");
if (ApiType == APIType::D3D)
@ -789,7 +789,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
if (numTexgen != 0)
{
out.Write(" uint tex_coord = {};\n",
BitfieldExtract("ss.order", TwoTevStageOrders().texcoord0));
BitfieldExtract<&TwoTevStageOrders::texcoord0>("ss.order"));
out.Write(" float3 uv = getTexCoord(tex_coord);\n"
" int2 fixedPoint_uv = int2((uv.z == 0.0 ? uv.xy : (uv.xy / uv.z)) * " I_TEXDIMS
"[tex_coord].zw);\n"
@ -802,11 +802,11 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" if (tevind != 0u)\n"
" {{\n"
" uint bs = {};\n",
BitfieldExtract("tevind", TevStageIndirect().bs));
out.Write(" uint fmt = {};\n", BitfieldExtract("tevind", TevStageIndirect().fmt));
out.Write(" uint bias = {};\n", BitfieldExtract("tevind", TevStageIndirect().bias));
out.Write(" uint bt = {};\n", BitfieldExtract("tevind", TevStageIndirect().bt));
out.Write(" uint mid = {};\n", BitfieldExtract("tevind", TevStageIndirect().mid));
BitfieldExtract<&TevStageIndirect::bs>("tevind"));
out.Write(" uint fmt = {};\n", BitfieldExtract<&TevStageIndirect::fmt>("tevind"));
out.Write(" uint bias = {};\n", BitfieldExtract<&TevStageIndirect::bias>("tevind"));
out.Write(" uint bt = {};\n", BitfieldExtract<&TevStageIndirect::bt>("tevind"));
out.Write(" uint mid = {};\n", BitfieldExtract<&TevStageIndirect::mid>("tevind"));
out.Write("\n");
out.Write(" int3 indcoord;\n");
LookupIndirectTexture("indcoord", "bt");
@ -873,8 +873,8 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
"\n"
" // Wrapping\n"
" uint sw = {};\n",
BitfieldExtract("tevind", TevStageIndirect().sw));
out.Write(" uint tw = {}; \n", BitfieldExtract("tevind", TevStageIndirect().tw));
BitfieldExtract<&TevStageIndirect::sw>("tevind"));
out.Write(" uint tw = {}; \n", BitfieldExtract<&TevStageIndirect::tw>("tevind"));
out.Write(
" int2 wrapped_coord = int2(Wrap(fixedPoint_uv.x, sw), Wrap(fixedPoint_uv.y, tw));\n"
"\n"
@ -895,12 +895,13 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" // Sample texture for stage\n"
" if (texture_enabled) {{\n"
" uint sampler_num = {};\n",
BitfieldExtract("ss.order", TwoTevStageOrders().texmap0));
BitfieldExtract<&TwoTevStageOrders::texmap0>("ss.order"));
out.Write("\n"
" float2 uv = (float2(tevcoord.xy)) * " I_TEXDIMS "[sampler_num].xy;\n");
out.Write(" int4 color = sampleTexture(sampler_num, float3(uv, {}));\n",
stereo ? "float(layer)" : "0.0");
out.Write(" uint swap = {};\n", BitfieldExtract("ss.ac", TevStageCombiner().alphaC.tswap));
out.Write(" uint swap = {};\n",
BitfieldExtract<&TevStageCombiner::AlphaCombiner::tswap>("ss.ac"));
out.Write(" s.TexColor = Swizzle(swap, color);\n");
out.Write(" }} else {{\n"
" // Texture is disabled\n"
@ -912,21 +913,25 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
out.Write(" // This is the Meat of TEV\n"
" {{\n"
" // Color Combiner\n");
out.Write(" uint color_a = {};\n", BitfieldExtract("ss.cc", TevStageCombiner().colorC.a));
out.Write(" uint color_b = {};\n", BitfieldExtract("ss.cc", TevStageCombiner().colorC.b));
out.Write(" uint color_c = {};\n", BitfieldExtract("ss.cc", TevStageCombiner().colorC.c));
out.Write(" uint color_d = {};\n", BitfieldExtract("ss.cc", TevStageCombiner().colorC.d));
out.Write(" uint color_a = {};\n",
BitfieldExtract<&TevStageCombiner::ColorCombiner::a>("ss.cc"));
out.Write(" uint color_b = {};\n",
BitfieldExtract<&TevStageCombiner::ColorCombiner::b>("ss.cc"));
out.Write(" uint color_c = {};\n",
BitfieldExtract<&TevStageCombiner::ColorCombiner::c>("ss.cc"));
out.Write(" uint color_d = {};\n",
BitfieldExtract<&TevStageCombiner::ColorCombiner::d>("ss.cc"));
out.Write(" uint color_bias = {};\n",
BitfieldExtract("ss.cc", TevStageCombiner().colorC.bias));
BitfieldExtract<&TevStageCombiner::ColorCombiner::bias>("ss.cc"));
out.Write(" bool color_op = bool({});\n",
BitfieldExtract("ss.cc", TevStageCombiner().colorC.op));
BitfieldExtract<&TevStageCombiner::ColorCombiner::op>("ss.cc"));
out.Write(" bool color_clamp = bool({});\n",
BitfieldExtract("ss.cc", TevStageCombiner().colorC.clamp));
BitfieldExtract<&TevStageCombiner::ColorCombiner::clamp>("ss.cc"));
out.Write(" uint color_shift = {};\n",
BitfieldExtract("ss.cc", TevStageCombiner().colorC.scale));
BitfieldExtract<&TevStageCombiner::ColorCombiner::scale>("ss.cc"));
out.Write(" uint color_dest = {};\n",
BitfieldExtract("ss.cc", TevStageCombiner().colorC.dest));
BitfieldExtract<&TevStageCombiner::ColorCombiner::dest>("ss.cc"));
out.Write(
" uint color_compare_op = color_shift << 1 | uint(color_op);\n"
@ -978,21 +983,25 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
// Alpha combiner
out.Write(" // Alpha Combiner\n");
out.Write(" uint alpha_a = {};\n", BitfieldExtract("ss.ac", TevStageCombiner().alphaC.a));
out.Write(" uint alpha_b = {};\n", BitfieldExtract("ss.ac", TevStageCombiner().alphaC.b));
out.Write(" uint alpha_c = {};\n", BitfieldExtract("ss.ac", TevStageCombiner().alphaC.c));
out.Write(" uint alpha_d = {};\n", BitfieldExtract("ss.ac", TevStageCombiner().alphaC.d));
out.Write(" uint alpha_a = {};\n",
BitfieldExtract<&TevStageCombiner::AlphaCombiner::a>("ss.ac"));
out.Write(" uint alpha_b = {};\n",
BitfieldExtract<&TevStageCombiner::AlphaCombiner::b>("ss.ac"));
out.Write(" uint alpha_c = {};\n",
BitfieldExtract<&TevStageCombiner::AlphaCombiner::c>("ss.ac"));
out.Write(" uint alpha_d = {};\n",
BitfieldExtract<&TevStageCombiner::AlphaCombiner::d>("ss.ac"));
out.Write(" uint alpha_bias = {};\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.bias));
BitfieldExtract<&TevStageCombiner::AlphaCombiner::bias>("ss.ac"));
out.Write(" bool alpha_op = bool({});\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.op));
BitfieldExtract<&TevStageCombiner::AlphaCombiner::op>("ss.ac"));
out.Write(" bool alpha_clamp = bool({});\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.clamp));
BitfieldExtract<&TevStageCombiner::AlphaCombiner::clamp>("ss.ac"));
out.Write(" uint alpha_shift = {};\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.scale));
BitfieldExtract<&TevStageCombiner::AlphaCombiner::scale>("ss.ac"));
out.Write(" uint alpha_dest = {};\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.dest));
BitfieldExtract<&TevStageCombiner::AlphaCombiner::dest>("ss.ac"));
out.Write(
" uint alpha_compare_op = alpha_shift << 1 | uint(alpha_op);\n"
@ -1043,10 +1052,12 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
// Select the output color and alpha registers from the last stage.
out.Write(" int4 TevResult;\n");
out.Write(" TevResult.xyz = getTevReg(s, {}).xyz;\n",
BitfieldExtract("bpmem_combiners(num_stages).x", TevStageCombiner().colorC.dest));
out.Write(" TevResult.w = getTevReg(s, {}).w;\n",
BitfieldExtract("bpmem_combiners(num_stages).y", TevStageCombiner().alphaC.dest));
out.Write(
" TevResult.xyz = getTevReg(s, {}).xyz;\n",
BitfieldExtract<&TevStageCombiner::ColorCombiner::dest>("bpmem_combiners(num_stages).x"));
out.Write(
" TevResult.w = getTevReg(s, {}).w;\n",
BitfieldExtract<&TevStageCombiner::AlphaCombiner::dest>("bpmem_combiners(num_stages).y"));
out.Write(" TevResult &= 255;\n\n");
@ -1117,14 +1128,14 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
out.Write(" // Alpha Test\n"
" if (bpmem_alphaTest != 0u) {{\n"
" bool comp0 = alphaCompare(TevResult.a, " I_ALPHA ".r, {});\n",
BitfieldExtract("bpmem_alphaTest", AlphaTest().comp0));
BitfieldExtract<&AlphaTest::comp0>("bpmem_alphaTest"));
out.Write(" bool comp1 = alphaCompare(TevResult.a, " I_ALPHA ".g, {});\n",
BitfieldExtract("bpmem_alphaTest", AlphaTest().comp1));
BitfieldExtract<&AlphaTest::comp1>("bpmem_alphaTest"));
out.Write("\n"
" // These if statements are written weirdly to work around intel and Qualcomm "
"bugs with handling booleans.\n"
" switch ({}) {{\n",
BitfieldExtract("bpmem_alphaTest", AlphaTest().logic));
BitfieldExtract<&AlphaTest::logic>("bpmem_alphaTest"));
out.Write(" case 0u: // AND\n"
" if (comp0 && comp1) break; else discard; break;\n"
" case 1u: // OR\n"
@ -1156,12 +1167,12 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
// Should be fixed point, and should not make guesses about Range-Based adjustments.
out.Write(" // Fog\n"
" uint fog_function = {};\n",
BitfieldExtract("bpmem_fogParam3", FogParam3().fsel));
BitfieldExtract<&FogParam3::fsel>("bpmem_fogParam3"));
out.Write(" if (fog_function != {:s}) {{\n", FogType::Off);
out.Write(" // TODO: This all needs to be converted from float to fixed point\n"
" float ze;\n"
" if ({} == 0u) {{\n",
BitfieldExtract("bpmem_fogParam3", FogParam3().proj));
BitfieldExtract<&FogParam3::proj>("bpmem_fogParam3"));
out.Write(" // perspective\n"
" // ze = A/(B - (Zs >> B_SHF)\n"
" ze = (" I_FOGF ".x * 16777216.0) / float(" I_FOGI ".y - (zCoord >> " I_FOGI
@ -1173,7 +1184,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" }}\n"
"\n"
" if (bool({})) {{\n",
BitfieldExtract("bpmem_fogRangeBase", FogRangeParams::RangeBase().Enabled));
BitfieldExtract<&FogRangeParams::RangeBase::Enabled>("bpmem_fogRangeBase"));
out.Write(" // x_adjust = sqrt((x-center)^2 + k^2)/k\n"
" // ze *= x_adjust\n"
" float offset = (2.0 * (rawpos.x / " I_FOGF ".w)) - 1.0 - " I_FOGF ".z;\n"
@ -1234,7 +1245,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
"\n"
" if (bpmem_dstalpha != 0u)\n");
out.Write(" ocol0.a = float({} >> 2) / 63.0;\n",
BitfieldExtract("bpmem_dstalpha", ConstantAlpha().alpha));
BitfieldExtract<&ConstantAlpha::alpha>("bpmem_dstalpha"));
out.Write(" else\n"
" ocol0.a = float(TevResult.a >> 2) / 63.0;\n"
" \n");
@ -1353,11 +1364,11 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
"int4 getRasColor(State s, StageState ss, float4 colors_0, float4 colors_1) {{\n"
" // Select Ras for stage\n"
" uint ras = {};\n",
BitfieldExtract("ss.order", TwoTevStageOrders().colorchan0));
BitfieldExtract<&TwoTevStageOrders::colorchan0>("ss.order"));
out.Write(" if (ras < 2u) {{ // Lighting Channel 0 or 1\n"
" int4 color = iround(((ras == 0u) ? colors_0 : colors_1) * 255.0);\n"
" uint swap = {};\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.rswap));
BitfieldExtract<&TevStageCombiner::AlphaCombiner::rswap>("ss.ac"));
out.Write(" return Swizzle(swap, color);\n");
out.Write(" }} else if (ras == 5u) {{ // Alpha Bumb\n"
" return int4(s.AlphaBump, s.AlphaBump, s.AlphaBump, s.AlphaBump);\n"
@ -1376,12 +1387,12 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" uint tevksel = bpmem_tevksel(ss.stage>>1);\n"
" if ((ss.stage & 1u) == 0u)\n"
" return int4(konstLookup[{}].rgb, konstLookup[{}].a);\n",
BitfieldExtract("tevksel", bpmem.tevksel[0].kcsel0),
BitfieldExtract("tevksel", bpmem.tevksel[0].kasel0));
BitfieldExtract<&TevKSel::kcsel0>("tevksel"),
BitfieldExtract<&TevKSel::kasel0>("tevksel"));
out.Write(" else\n"
" return int4(konstLookup[{}].rgb, konstLookup[{}].a);\n",
BitfieldExtract("tevksel", bpmem.tevksel[0].kcsel1),
BitfieldExtract("tevksel", bpmem.tevksel[0].kasel1));
BitfieldExtract<&TevKSel::kcsel1>("tevksel"),
BitfieldExtract<&TevKSel::kasel1>("tevksel"));
out.Write("}}\n");
return out;

View file

@ -402,7 +402,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" // Texcoord transforms\n");
out.Write(" float4 coord = float4(0.0, 0.0, 1.0, 1.0);\n"
" uint texMtxInfo = xfmem_texMtxInfo(texgen);\n");
out.Write(" switch ({}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().sourcerow));
out.Write(" switch ({}) {{\n", BitfieldExtract<&TexMtxInfo::sourcerow>("texMtxInfo"));
out.Write(" case {:s}:\n", SourceRow::Geom);
out.Write(" coord.xyz = rawpos.xyz;\n");
out.Write(" break;\n\n");
@ -435,21 +435,21 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" // Input form of AB11 sets z element to 1.0\n");
out.Write(" if ({} == {:s}) // inputform == AB11\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().inputform), TexInputForm::AB11);
BitfieldExtract<&TexMtxInfo::inputform>("texMtxInfo"), TexInputForm::AB11);
out.Write(" coord.z = 1.0f;\n"
"\n");
out.Write(" // first transformation\n");
out.Write(" uint texgentype = {};\n", BitfieldExtract("texMtxInfo", TexMtxInfo().texgentype));
out.Write(" uint texgentype = {};\n", BitfieldExtract<&TexMtxInfo::texgentype>("texMtxInfo"));
out.Write(" float3 output_tex;\n"
" switch (texgentype)\n"
" {{\n");
out.Write(" case {:s}:\n", TexGenType::EmbossMap);
out.Write(" {{\n");
out.Write(" uint light = {};\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().embosslightshift));
BitfieldExtract<&TexMtxInfo::embosslightshift>("texMtxInfo"));
out.Write(" uint source = {};\n",
BitfieldExtract("texMtxInfo", TexMtxInfo().embosssourceshift));
BitfieldExtract<&TexMtxInfo::embosssourceshift>("texMtxInfo"));
out.Write(" switch (source) {{\n");
for (u32 i = 0; i < num_texgen; i++)
out.Write(" case {}u: output_tex.xyz = o.tex{}; break;\n", i, i);
@ -481,7 +481,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" case {}u: tmp = int(rawtex{}.z); break;\n", i, i);
out.Write(" }}\n"
"\n");
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract<&TexMtxInfo::projection>("texMtxInfo"),
TexSize::STQ);
out.Write(" output_tex.xyz = float3(dot(coord, " I_TRANSFORMMATRICES "[tmp]),\n"
" dot(coord, " I_TRANSFORMMATRICES "[tmp + 1]),\n"
@ -492,7 +492,7 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
" 1.0);\n"
" }}\n"
" }} else {{\n");
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract("texMtxInfo", TexMtxInfo().projection),
out.Write(" if ({} == {:s}) {{\n", BitfieldExtract<&TexMtxInfo::projection>("texMtxInfo"),
TexSize::STQ);
out.Write(" output_tex.xyz = float3(dot(coord, " I_TEXMATRICES "[3u * texgen]),\n"
" dot(coord, " I_TEXMATRICES "[3u * texgen + 1u]),\n"
@ -510,12 +510,12 @@ static void GenVertexShaderTexGens(APIType api_type, u32 num_texgen, ShaderCode&
out.Write(" if (xfmem_dualTexInfo != 0u) {{\n");
out.Write(" uint postMtxInfo = xfmem_postMtxInfo(texgen);");
out.Write(" uint base_index = {};\n", BitfieldExtract("postMtxInfo", PostMtxInfo().index));
out.Write(" uint base_index = {};\n", BitfieldExtract<&PostMtxInfo::index>("postMtxInfo"));
out.Write(" float4 P0 = " I_POSTTRANSFORMMATRICES "[base_index & 0x3fu];\n"
" float4 P1 = " I_POSTTRANSFORMMATRICES "[(base_index + 1u) & 0x3fu];\n"
" float4 P2 = " I_POSTTRANSFORMMATRICES "[(base_index + 2u) & 0x3fu];\n"
"\n");
out.Write(" if ({} != 0u)\n", BitfieldExtract("postMtxInfo", PostMtxInfo().normalize));
out.Write(" if ({} != 0u)\n", BitfieldExtract<&PostMtxInfo::normalize>("postMtxInfo"));
out.Write(" output_tex.xyz = normalize(output_tex.xyz);\n"
"\n"
" // multiply by postmatrix\n"