summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorMarkus Wick <degasus@users.noreply.github.com>2015-12-28 10:09:11 +0100
committerMarkus Wick <degasus@users.noreply.github.com>2015-12-28 10:09:11 +0100
commit281860eafa65d7f65b02cc449ac94397d0f111f4 (patch)
tree23cfbe61f97089c1806eeb1e1d249d0b43fa622a /Source/Core/VideoCommon
parentcec1a759769bea2d7a224f99d6ee34ad9a602bed (diff)
parentc5f123a70b2bb9db5721383b07a7343b78693883 (diff)
Merge pull request #3400 from lioncash/shadergen
ShaderGen: Get rid of static buffers
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/GeometryShaderGen.cpp24
-rw-r--r--Source/Core/VideoCommon/ImageWrite.cpp2
-rw-r--r--Source/Core/VideoCommon/ImageWrite.h2
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp43
-rw-r--r--Source/Core/VideoCommon/ShaderGenCommon.h60
-rw-r--r--Source/Core/VideoCommon/VertexShaderGen.cpp18
6 files changed, 48 insertions, 101 deletions
diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp
index bf054464c2..9c1ccd3071 100644
--- a/Source/Core/VideoCommon/GeometryShaderGen.cpp
+++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp
@@ -7,10 +7,8 @@
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/GeometryShaderGen.h"
#include "VideoCommon/LightingShaderGen.h"
-#include "VideoCommon/VertexShaderGen.h"
#include "VideoCommon/VideoConfig.h"
-static char text[16384];
static const char* primitives_ogl[] =
{
@@ -26,11 +24,11 @@ static const char* primitives_d3d[] =
"triangle"
};
-template<class T> static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex = false);
-template<class T> static inline void EndPrimitive(T& out, API_TYPE ApiType);
+template<class T> static void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex = false);
+template<class T> static void EndPrimitive(T& out, API_TYPE ApiType);
template<class T>
-static inline T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
+static T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
{
T out;
// Non-uid template parameters will write to the dummy data (=> gets optimized out)
@@ -39,12 +37,6 @@ static inline T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
if (uid_data == nullptr)
uid_data = &dummy_data;
- out.SetBuffer(text);
- const bool is_writing_shadercode = (out.GetBuffer() != nullptr);
-
- if (is_writing_shadercode)
- text[sizeof(text) - 1] = 0x7C; // canary
-
uid_data->primitive_type = primitive_type;
const unsigned int vertex_in = primitive_type + 1;
unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4;
@@ -288,17 +280,11 @@ static inline T GenerateGeometryShader(u32 primitive_type, API_TYPE ApiType)
out.Write("}\n");
- if (is_writing_shadercode)
- {
- if (text[sizeof(text) - 1] != 0x7C)
- PanicAlert("GeometryShader generator - buffer too small, canary has been eaten!");
- }
-
return out;
}
template<class T>
-static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex)
+static void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex)
{
if (g_ActiveConfig.bWireFrame && first_vertex)
out.Write("\tif (i == 0) first = %s;\n", vertex);
@@ -319,7 +305,7 @@ static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool
out.Write("\toutput.Append(ps);\n");
}
template<class T>
-static inline void EndPrimitive(T& out, API_TYPE ApiType)
+static void EndPrimitive(T& out, API_TYPE ApiType)
{
if (g_ActiveConfig.bWireFrame)
EmitVertex<T>(out, "first", ApiType);
diff --git a/Source/Core/VideoCommon/ImageWrite.cpp b/Source/Core/VideoCommon/ImageWrite.cpp
index f50c5d02b4..e8c55088c1 100644
--- a/Source/Core/VideoCommon/ImageWrite.cpp
+++ b/Source/Core/VideoCommon/ImageWrite.cpp
@@ -12,7 +12,7 @@
#include "Common/Logging/Log.h"
#include "VideoCommon/ImageWrite.h"
-bool SaveData(const std::string& filename, const char* data)
+bool SaveData(const std::string& filename, const std::string& data)
{
std::ofstream f;
OpenFStream(f, filename, std::ios::binary);
diff --git a/Source/Core/VideoCommon/ImageWrite.h b/Source/Core/VideoCommon/ImageWrite.h
index 730b3f7540..880d99e431 100644
--- a/Source/Core/VideoCommon/ImageWrite.h
+++ b/Source/Core/VideoCommon/ImageWrite.h
@@ -7,5 +7,5 @@
#include <string>
#include "Common/CommonTypes.h"
-bool SaveData(const std::string& filename, const char* pdata);
+bool SaveData(const std::string& filename, const std::string& data);
bool TextureToPng(u8* data, int row_stride, const std::string& filename, int width, int height, bool saveAlpha = true);
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index 3439481da5..957c0b0fe7 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -9,13 +9,10 @@
#include "Common/Common.h"
#include "VideoCommon/BoundingBox.h"
#include "VideoCommon/BPMemory.h"
-#include "VideoCommon/ConstantManager.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/LightingShaderGen.h"
-#include "VideoCommon/NativeVertexFormat.h"
#include "VideoCommon/PixelShaderGen.h"
#include "VideoCommon/VertexLoaderManager.h"
-#include "VideoCommon/VertexShaderGen.h"
#include "VideoCommon/VideoConfig.h"
#include "VideoCommon/XFMemory.h" // for texture projection mode
@@ -157,16 +154,14 @@ static const char *tevRasTable[] =
static const char *tevCOutputTable[] = { "prev.rgb", "c0.rgb", "c1.rgb", "c2.rgb" };
static const char *tevAOutputTable[] = { "prev.a", "c0.a", "c1.a", "c2.a" };
-static char text[32768];
-
-template<class T> static inline void WriteStage(T& out, pixel_shader_uid_data* uid_data, int n, API_TYPE ApiType, const char swapModeTable[4][5]);
-template<class T> static inline void WriteTevRegular(T& out, const char* components, int bias, int op, int clamp, int shift);
-template<class T> static inline void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
-template<class T> static inline void WriteAlphaTest(T& out, pixel_shader_uid_data* uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth);
-template<class T> static inline void WriteFog(T& out, pixel_shader_uid_data* uid_data);
+template<class T> static void WriteStage(T& out, pixel_shader_uid_data* uid_data, int n, API_TYPE ApiType, const char swapModeTable[4][5]);
+template<class T> static void WriteTevRegular(T& out, const char* components, int bias, int op, int clamp, int shift);
+template<class T> static void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
+template<class T> static void WriteAlphaTest(T& out, pixel_shader_uid_data* uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth);
+template<class T> static void WriteFog(T& out, pixel_shader_uid_data* uid_data);
template<class T>
-static inline T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType)
+static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType)
{
T out;
const u32 components = VertexLoaderManager::g_current_components;
@@ -176,12 +171,6 @@ static inline T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
if (uid_data == nullptr)
uid_data = &dummy_data;
- out.SetBuffer(text);
- const bool is_writing_shadercode = (out.GetBuffer() != nullptr);
-
- if (is_writing_shadercode)
- text[sizeof(text) - 1] = 0x7C; // canary
-
unsigned int numStages = bpmem.genMode.numtevstages + 1;
unsigned int numTexgen = bpmem.genMode.numtexgens;
@@ -339,7 +328,7 @@ static inline T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
out.Write("[earlydepthstencil]\n");
}
}
- else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) && is_writing_shadercode)
+ else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED))
{
static bool warn_once = true;
if (warn_once)
@@ -663,18 +652,12 @@ static inline T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
out.Write("}\n");
- if (is_writing_shadercode)
- {
- if (text[sizeof(text) - 1] != 0x7C)
- PanicAlert("PixelShader generator - buffer too small, canary has been eaten!");
- }
-
return out;
}
template<class T>
-static inline void WriteStage(T& out, pixel_shader_uid_data* uid_data, int n, API_TYPE ApiType, const char swapModeTable[4][5])
+static void WriteStage(T& out, pixel_shader_uid_data* uid_data, int n, API_TYPE ApiType, const char swapModeTable[4][5])
{
int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1);
bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens;
@@ -958,7 +941,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data* uid_data, int n, AP
}
template<class T>
-static inline void WriteTevRegular(T& out, const char* components, int bias, int op, int clamp, int shift)
+static void WriteTevRegular(T& out, const char* components, int bias, int op, int clamp, int shift)
{
const char *tevScaleTableLeft[] =
{
@@ -1011,7 +994,7 @@ static inline void WriteTevRegular(T& out, const char* components, int bias, int
}
template<class T>
-static inline void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType)
+static void SampleTexture(T& out, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType)
{
out.SetConstantsUsed(C_TEXDIMS+texmap,C_TEXDIMS+texmap);
@@ -1042,7 +1025,7 @@ static const char *tevAlphaFunclogicTable[] =
};
template<class T>
-static inline void WriteAlphaTest(T& out, pixel_shader_uid_data* uid_data, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth)
+static void WriteAlphaTest(T& out, pixel_shader_uid_data* uid_data, API_TYPE ApiType, DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth)
{
static const char *alphaRef[2] =
{
@@ -1117,7 +1100,7 @@ static const char *tevFogFuncsTable[] =
};
template<class T>
-static inline void WriteFog(T& out, pixel_shader_uid_data* uid_data)
+static void WriteFog(T& out, pixel_shader_uid_data* uid_data)
{
uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel;
if (bpmem.fog.c_proj_fsel.fsel == 0)
@@ -1165,7 +1148,7 @@ static inline void WriteFog(T& out, pixel_shader_uid_data* uid_data)
}
else
{
- if (bpmem.fog.c_proj_fsel.fsel != 2 && out.GetBuffer() != nullptr)
+ if (bpmem.fog.c_proj_fsel.fsel != 2)
WARN_LOG(VIDEO, "Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel);
}
diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h
index 11c4e2870e..e8ceafe239 100644
--- a/Source/Core/VideoCommon/ShaderGenCommon.h
+++ b/Source/Core/VideoCommon/ShaderGenCommon.h
@@ -27,34 +27,31 @@
class ShaderGeneratorInterface
{
public:
+ virtual ~ShaderGeneratorInterface()
+ {
+ }
+
+ /*
+ * Returns a read pointer to the internal buffer.
+ */
+ const std::string& GetBuffer() const { return m_buffer; }
+
/*
* Used when the shader generator would write a piece of ShaderCode.
* Can be used like printf.
* @note In the ShaderCode implementation, this does indeed write the parameter string to an internal buffer. However, you're free to do whatever you like with the parameter.
*/
- void Write(const char*, ...)
+ virtual void Write(const char*, ...)
#ifdef __GNUC__
__attribute__((format(printf, 2, 3)))
#endif
- {}
-
- /*
- * Returns a read pointer to the internal buffer.
- * @note When implementing this method in a child class, you likely want to return the argument of the last SetBuffer call here
- * @note SetBuffer() should be called before using GetBuffer().
- */
- const char* GetBuffer() { return nullptr; }
-
- /*
- * Can be used to give the object a place to write to. This should be called before using Write().
- * @param buffer pointer to a char buffer that the object can write to
- */
- void SetBuffer(char* buffer) { }
+ {
+ }
/*
* Tells us that a specific constant range (including last_index) is being used by the shader
*/
- inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {}
+ virtual void SetConstantsUsed(unsigned int first_index, unsigned int last_index) {}
/*
* Returns a pointer to an internally stored object of the uid_data type.
@@ -62,6 +59,9 @@ public:
*/
template<class uid_data>
uid_data* GetUidData() { return nullptr; }
+
+protected:
+ std::string m_buffer;
};
/**
@@ -114,27 +114,21 @@ private:
class ShaderCode : public ShaderGeneratorInterface
{
public:
- ShaderCode() : buf(nullptr), write_ptr(nullptr)
+ ShaderCode()
{
+ m_buffer.reserve(16384);
}
- void Write(const char* fmt, ...)
+ void Write(const char* fmt, ...) override
#ifdef __GNUC__
__attribute__((format(printf, 2, 3)))
#endif
{
va_list arglist;
va_start(arglist, fmt);
- write_ptr += vsprintf(write_ptr, fmt, arglist);
+ m_buffer += StringFromFormatV(fmt, arglist);
va_end(arglist);
}
-
- const char* GetBuffer() { return buf; }
- void SetBuffer(char* buffer) { buf = buffer; write_ptr = buffer; }
-
-private:
- const char* buf;
- char* write_ptr;
};
/**
@@ -145,13 +139,13 @@ class ShaderConstantProfile : public ShaderGeneratorInterface
public:
ShaderConstantProfile(int num_constants) { constant_usage.resize(num_constants); }
- inline void SetConstantsUsed(unsigned int first_index, unsigned int last_index)
+ void SetConstantsUsed(unsigned int first_index, unsigned int last_index) override
{
for (unsigned int i = first_index; i < last_index + 1; ++i)
constant_usage[i] = true;
}
- inline bool ConstantIsUsed(unsigned int index)
+ bool ConstantIsUsed(unsigned int index) const
{
// TODO: Not ready for usage yet
return true;
@@ -185,7 +179,7 @@ public:
{
// uid is already in the index => check if there's a shader with the same uid but different code
auto& old_code = m_shaders[new_uid];
- if (strcmp(old_code.c_str(), new_code.GetBuffer()) != 0)
+ if (old_code != new_code.GetBuffer())
{
static int num_failures = 0;
@@ -226,7 +220,7 @@ private:
};
template<class T>
-static void DefineOutputMember(T& object, API_TYPE api_type, const char* qualifier, const char* type, const char* name, int var_index, const char* semantic = "", int semantic_index = -1)
+inline void DefineOutputMember(T& object, API_TYPE api_type, const char* qualifier, const char* type, const char* name, int var_index, const char* semantic = "", int semantic_index = -1)
{
if (qualifier != nullptr)
object.Write("\t%s %s %s", qualifier, type, name);
@@ -248,7 +242,7 @@ static void DefineOutputMember(T& object, API_TYPE api_type, const char* qualifi
}
template<class T>
-static inline void GenerateVSOutputMembers(T& object, API_TYPE api_type, const char* qualifier = nullptr)
+inline void GenerateVSOutputMembers(T& object, API_TYPE api_type, const char* qualifier = nullptr)
{
DefineOutputMember(object, api_type, qualifier, "float4", "pos", -1, "POSITION");
DefineOutputMember(object, api_type, qualifier, "float4", "colors_", 0, "COLOR", 0);
@@ -267,7 +261,7 @@ static inline void GenerateVSOutputMembers(T& object, API_TYPE api_type, const c
}
template<class T>
-static inline void AssignVSOutputMembers(T& object, const char* a, const char* b)
+inline void AssignVSOutputMembers(T& object, const char* a, const char* b)
{
object.Write("\t%s.pos = %s.pos;\n", a, b);
object.Write("\t%s.colors_0 = %s.colors_0;\n", a, b);
@@ -293,7 +287,7 @@ static inline void AssignVSOutputMembers(T& object, const char* a, const char* b
// As a workaround, we interpolate at the centroid of the coveraged pixel, which
// is always inside the primitive.
// Without MSAA, this flag is defined to have no effect.
-static inline const char* GetInterpolationQualifier(API_TYPE api_type, bool in = true, bool in_out = false)
+inline const char* GetInterpolationQualifier(API_TYPE api_type, bool in = true, bool in_out = false)
{
if (g_ActiveConfig.iMultisamples <= 1)
return "";
diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp
index 4f6331cfde..3a9a167a64 100644
--- a/Source/Core/VideoCommon/VertexShaderGen.cpp
+++ b/Source/Core/VideoCommon/VertexShaderGen.cpp
@@ -5,18 +5,14 @@
#include <cmath>
#include "VideoCommon/BPMemory.h"
-#include "VideoCommon/CPMemory.h"
-#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/LightingShaderGen.h"
#include "VideoCommon/NativeVertexFormat.h"
#include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexShaderGen.h"
#include "VideoCommon/VideoConfig.h"
-static char text[16768];
-
template<class T>
-static inline T GenerateVertexShader(API_TYPE api_type)
+static T GenerateVertexShader(API_TYPE api_type)
{
T out;
const u32 components = VertexLoaderManager::g_current_components;
@@ -26,12 +22,6 @@ static inline T GenerateVertexShader(API_TYPE api_type)
if (uid_data == nullptr)
uid_data = &dummy_data;
- out.SetBuffer(text);
- const bool is_writing_shadercode = (out.GetBuffer() != nullptr);
-
- if (is_writing_shadercode)
- text[sizeof(text) - 1] = 0x7C; // canary
-
_assert_(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens);
_assert_(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans);
@@ -390,12 +380,6 @@ static inline T GenerateVertexShader(API_TYPE api_type)
}
out.Write("}\n");
- if (is_writing_shadercode)
- {
- if (text[sizeof(text) - 1] != 0x7C)
- PanicAlert("VertexShader generator - buffer too small, canary has been eaten!");
- }
-
return out;
}