Merge pull request #8141 from lioncash/init

VideoCommon/ShaderGenCommon: Simplify initialization of ShaderUid class
This commit is contained in:
Léo Lam 2019-05-30 14:15:02 +02:00 committed by GitHub
commit 90c9991086
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 42 additions and 66 deletions

View File

@ -5,7 +5,6 @@
#include "VideoCommon/GeometryShaderGen.h" #include "VideoCommon/GeometryShaderGen.h"
#include <cmath> #include <cmath>
#include <cstring>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "VideoCommon/DriverDetails.h" #include "VideoCommon/DriverDetails.h"
@ -27,10 +26,9 @@ bool geometry_shader_uid_data::IsPassthrough() const
GeometryShaderUid GetGeometryShaderUid(PrimitiveType primitive_type) GeometryShaderUid GetGeometryShaderUid(PrimitiveType primitive_type)
{ {
ShaderUid<geometry_shader_uid_data> out; GeometryShaderUid out;
geometry_shader_uid_data* uid_data = out.GetUidData<geometry_shader_uid_data>();
memset(uid_data, 0, sizeof(geometry_shader_uid_data));
geometry_shader_uid_data* const uid_data = out.GetUidData();
uid_data->primitive_type = static_cast<u32>(primitive_type); uid_data->primitive_type = static_cast<u32>(primitive_type);
uid_data->numTexGens = xfmem.numTexGen.numTexGens; uid_data->numTexGens = xfmem.numTexGen.numTexGens;
@ -364,7 +362,6 @@ static void EndPrimitive(ShaderCode& out, const ShaderHostConfig& host_config,
void EnumerateGeometryShaderUids(const std::function<void(const GeometryShaderUid&)>& callback) void EnumerateGeometryShaderUids(const std::function<void(const GeometryShaderUid&)>& callback)
{ {
GeometryShaderUid uid; GeometryShaderUid uid;
std::memset(&uid, 0, sizeof(uid));
const std::array<PrimitiveType, 3> primitive_lut = { const std::array<PrimitiveType, 3> primitive_lut = {
{g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip : {g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? PrimitiveType::TriangleStrip :
@ -372,7 +369,7 @@ void EnumerateGeometryShaderUids(const std::function<void(const GeometryShaderUi
PrimitiveType::Lines, PrimitiveType::Points}}; PrimitiveType::Lines, PrimitiveType::Points}};
for (PrimitiveType primitive : primitive_lut) for (PrimitiveType primitive : primitive_lut)
{ {
auto* guid = uid.GetUidData<geometry_shader_uid_data>(); geometry_shader_uid_data* const guid = uid.GetUidData();
guid->primitive_type = static_cast<u32>(primitive); guid->primitive_type = static_cast<u32>(primitive);
for (u32 texgens = 0; texgens <= 8; texgens++) for (u32 texgens = 0; texgens <= 8; texgens++)

View File

@ -12,7 +12,6 @@
enum class APIType; enum class APIType;
#pragma pack(1) #pragma pack(1)
struct geometry_shader_uid_data struct geometry_shader_uid_data
{ {
u32 NumValues() const { return sizeof(geometry_shader_uid_data); } u32 NumValues() const { return sizeof(geometry_shader_uid_data); }
@ -21,10 +20,9 @@ struct geometry_shader_uid_data
u32 numTexGens : 4; u32 numTexGens : 4;
u32 primitive_type : 2; u32 primitive_type : 2;
}; };
#pragma pack() #pragma pack()
typedef ShaderUid<geometry_shader_uid_data> GeometryShaderUid; using GeometryShaderUid = ShaderUid<geometry_shader_uid_data>;
ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& host_config, ShaderCode GenerateGeometryShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
const geometry_shader_uid_data* uid_data); const geometry_shader_uid_data* uid_data);

View File

@ -6,7 +6,6 @@
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
#include <cstring>
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -162,9 +161,8 @@ static const char* tevAOutputTable[] = {"prev.a", "c0.a", "c1.a", "c2.a"};
PixelShaderUid GetPixelShaderUid() PixelShaderUid GetPixelShaderUid()
{ {
PixelShaderUid out; PixelShaderUid out;
pixel_shader_uid_data* uid_data = out.GetUidData<pixel_shader_uid_data>();
memset(uid_data, 0, sizeof(*uid_data));
pixel_shader_uid_data* const uid_data = out.GetUidData();
uid_data->useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && uid_data->useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
@ -340,7 +338,7 @@ PixelShaderUid GetPixelShaderUid()
void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config, void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
PixelShaderUid* uid) PixelShaderUid* uid)
{ {
pixel_shader_uid_data* uid_data = uid->GetUidData<pixel_shader_uid_data>(); pixel_shader_uid_data* const uid_data = uid->GetUidData();
// OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation. // OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation.
// Therefore, it is not necessary to use a uint output on these backends. We also disable the // Therefore, it is not necessary to use a uint output on these backends. We also disable the

View File

@ -162,7 +162,7 @@ struct pixel_shader_uid_data
}; };
#pragma pack() #pragma pack()
typedef ShaderUid<pixel_shader_uid_data> PixelShaderUid; using PixelShaderUid = ShaderUid<pixel_shader_uid_data>;
ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config, ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
const pixel_shader_uid_data* uid_data); const pixel_shader_uid_data* uid_data);

View File

@ -8,6 +8,7 @@
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <string> #include <string>
#include <type_traits>
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -48,17 +49,6 @@ public:
* Tells us that a specific constant range (including last_index) is being used by the shader * Tells us that a specific constant range (including last_index) is being used by the shader
*/ */
void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {} void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {}
/*
* Returns a pointer to an internally stored object of the uid_data type.
* @warning since most child classes use the default implementation you shouldn't access this
* directly without adding precautions against nullptr access (e.g. via adding a dummy structure,
* cf. the vertex/pixel shader generators)
*/
template <class uid_data>
uid_data* GetUidData()
{
return nullptr;
}
}; };
/* /*
@ -74,37 +64,36 @@ template <class uid_data>
class ShaderUid : public ShaderGeneratorInterface class ShaderUid : public ShaderGeneratorInterface
{ {
public: public:
static_assert(std::is_trivially_copyable_v<uid_data>,
"uid_data must be a trivially copyable type");
bool operator==(const ShaderUid& obj) const bool operator==(const ShaderUid& obj) const
{ {
return memcmp(this->values, obj.values, data.NumValues() * sizeof(*values)) == 0; return memcmp(&data, &obj.data, data.NumValues() * sizeof(data)) == 0;
} }
bool operator!=(const ShaderUid& obj) const bool operator!=(const ShaderUid& obj) const { return !operator==(obj); }
{
return memcmp(this->values, obj.values, data.NumValues() * sizeof(*values)) != 0;
}
// determines the storage order inside STL containers // determines the storage order inside STL containers
bool operator<(const ShaderUid& obj) const bool operator<(const ShaderUid& obj) const
{ {
return memcmp(this->values, obj.values, data.NumValues() * sizeof(*values)) < 0; return memcmp(&data, &obj.data, data.NumValues() * sizeof(data)) < 0;
} }
template <class uid_data2> // Returns a pointer to an internally stored object of the uid_data type.
uid_data2* GetUidData() uid_data* GetUidData() { return &data; }
{
return &data; // Returns a pointer to an internally stored object of the uid_data type.
}
const uid_data* GetUidData() const { return &data; } const uid_data* GetUidData() const { return &data; }
const u8* GetUidDataRaw() const { return &values[0]; }
size_t GetUidDataSize() const { return sizeof(values); } // Returns the raw bytes that make up the shader UID.
const u8* GetUidDataRaw() const { return reinterpret_cast<const u8*>(&data); }
// Returns the size of the underlying UID data structure in bytes.
size_t GetUidDataSize() const { return sizeof(data); }
private: private:
union uid_data data{};
{
uid_data data;
u8 values[sizeof(uid_data)];
};
}; };
class ShaderCode : public ShaderGeneratorInterface class ShaderCode : public ShaderGeneratorInterface

View File

@ -2,13 +2,11 @@
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <array> #include "VideoCommon/TextureConverterShaderGen.h"
#include <cstring>
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/TextureConverterShaderGen.h"
#include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
@ -18,9 +16,8 @@ TCShaderUid GetShaderUid(EFBCopyFormat dst_format, bool is_depth_copy, bool is_i
bool scale_by_half, bool copy_filter) bool scale_by_half, bool copy_filter)
{ {
TCShaderUid out; TCShaderUid out;
UidData* uid_data = out.GetUidData<UidData>();
memset(uid_data, 0, sizeof(*uid_data));
UidData* const uid_data = out.GetUidData();
uid_data->dst_format = dst_format; uid_data->dst_format = dst_format;
uid_data->efb_has_alpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; uid_data->efb_has_alpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
uid_data->is_depth_copy = is_depth_copy; uid_data->is_depth_copy = is_depth_copy;

View File

@ -14,8 +14,8 @@ namespace UberShader
PixelShaderUid GetPixelShaderUid() PixelShaderUid GetPixelShaderUid()
{ {
PixelShaderUid out; PixelShaderUid out;
pixel_ubershader_uid_data* uid_data = out.GetUidData<pixel_ubershader_uid_data>();
memset(uid_data, 0, sizeof(*uid_data)); pixel_ubershader_uid_data* const uid_data = out.GetUidData();
uid_data->num_texgens = xfmem.numTexGen.numTexGens; uid_data->num_texgens = xfmem.numTexGen.numTexGens;
uid_data->early_depth = uid_data->early_depth =
bpmem.UseEarlyDepthTest() && bpmem.UseEarlyDepthTest() &&
@ -26,13 +26,14 @@ PixelShaderUid GetPixelShaderUid()
(!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !uid_data->early_depth) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !uid_data->early_depth) ||
(bpmem.zmode.testenable && bpmem.genMode.zfreeze); (bpmem.zmode.testenable && bpmem.genMode.zfreeze);
uid_data->uint_output = bpmem.blendmode.UseLogicOp(); uid_data->uint_output = bpmem.blendmode.UseLogicOp();
return out; return out;
} }
void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config, void ClearUnusedPixelShaderUidBits(APIType ApiType, const ShaderHostConfig& host_config,
PixelShaderUid* uid) PixelShaderUid* uid)
{ {
pixel_ubershader_uid_data* uid_data = uid->GetUidData<pixel_ubershader_uid_data>(); pixel_ubershader_uid_data* const uid_data = uid->GetUidData();
// OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation. // OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation.
// Therefore, it is not necessary to use a uint output on these backends. We also disable the // Therefore, it is not necessary to use a uint output on these backends. We also disable the
@ -1390,11 +1391,10 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
void EnumeratePixelShaderUids(const std::function<void(const PixelShaderUid&)>& callback) void EnumeratePixelShaderUids(const std::function<void(const PixelShaderUid&)>& callback)
{ {
PixelShaderUid uid; PixelShaderUid uid;
std::memset(&uid, 0, sizeof(uid));
for (u32 texgens = 0; texgens <= 8; texgens++) for (u32 texgens = 0; texgens <= 8; texgens++)
{ {
auto* puid = uid.GetUidData<UberShader::pixel_ubershader_uid_data>(); pixel_ubershader_uid_data* const puid = uid.GetUidData();
puid->num_texgens = texgens; puid->num_texgens = texgens;
for (u32 early_depth = 0; early_depth < 2; early_depth++) for (u32 early_depth = 0; early_depth < 2; early_depth++)

View File

@ -21,7 +21,7 @@ struct pixel_ubershader_uid_data
}; };
#pragma pack() #pragma pack()
typedef ShaderUid<pixel_ubershader_uid_data> PixelShaderUid; using PixelShaderUid = ShaderUid<pixel_ubershader_uid_data>;
PixelShaderUid GetPixelShaderUid(); PixelShaderUid GetPixelShaderUid();

View File

@ -15,9 +15,10 @@ namespace UberShader
VertexShaderUid GetVertexShaderUid() VertexShaderUid GetVertexShaderUid()
{ {
VertexShaderUid out; VertexShaderUid out;
vertex_ubershader_uid_data* uid_data = out.GetUidData<vertex_ubershader_uid_data>();
memset(uid_data, 0, sizeof(*uid_data)); vertex_ubershader_uid_data* const uid_data = out.GetUidData();
uid_data->num_texgens = xfmem.numTexGen.numTexGens; uid_data->num_texgens = xfmem.numTexGen.numTexGens;
return out; return out;
} }
@ -487,11 +488,10 @@ void GenVertexShaderTexGens(APIType ApiType, u32 numTexgen, ShaderCode& out)
void EnumerateVertexShaderUids(const std::function<void(const VertexShaderUid&)>& callback) void EnumerateVertexShaderUids(const std::function<void(const VertexShaderUid&)>& callback)
{ {
VertexShaderUid uid; VertexShaderUid uid;
std::memset(&uid, 0, sizeof(uid));
for (u32 texgens = 0; texgens <= 8; texgens++) for (u32 texgens = 0; texgens <= 8; texgens++)
{ {
auto* vuid = uid.GetUidData<UberShader::vertex_ubershader_uid_data>(); vertex_ubershader_uid_data* const vuid = uid.GetUidData();
vuid->num_texgens = texgens; vuid->num_texgens = texgens;
callback(uid); callback(uid);
} }

View File

@ -18,7 +18,7 @@ struct vertex_ubershader_uid_data
}; };
#pragma pack() #pragma pack()
typedef ShaderUid<vertex_ubershader_uid_data> VertexShaderUid; using VertexShaderUid = ShaderUid<vertex_ubershader_uid_data>;
VertexShaderUid GetVertexShaderUid(); VertexShaderUid GetVertexShaderUid();

View File

@ -2,7 +2,7 @@
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <cstring> #include "VideoCommon/VertexShaderGen.h"
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -10,20 +10,17 @@
#include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/LightingShaderGen.h"
#include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/NativeVertexFormat.h"
#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexShaderGen.h"
#include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
#include "VideoCommon/XFMemory.h" #include "VideoCommon/XFMemory.h"
VertexShaderUid GetVertexShaderUid() VertexShaderUid GetVertexShaderUid()
{ {
VertexShaderUid out;
vertex_shader_uid_data* uid_data = out.GetUidData<vertex_shader_uid_data>();
memset(uid_data, 0, sizeof(*uid_data));
ASSERT(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens); ASSERT(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens);
ASSERT(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans); ASSERT(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans);
VertexShaderUid out;
vertex_shader_uid_data* const uid_data = out.GetUidData();
uid_data->numTexGens = xfmem.numTexGen.numTexGens; uid_data->numTexGens = xfmem.numTexGen.numTexGens;
uid_data->components = VertexLoaderManager::g_current_components; uid_data->components = VertexLoaderManager::g_current_components;
uid_data->numColorChans = xfmem.numChan.numColorChans; uid_data->numColorChans = xfmem.numChan.numColorChans;

View File

@ -65,7 +65,7 @@ struct vertex_shader_uid_data
}; };
#pragma pack() #pragma pack()
typedef ShaderUid<vertex_shader_uid_data> VertexShaderUid; using VertexShaderUid = ShaderUid<vertex_shader_uid_data>;
VertexShaderUid GetVertexShaderUid(); VertexShaderUid GetVertexShaderUid();
ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& host_config, ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& host_config,