Remove use of legacy StringFormat::snprintf variants

This commit is contained in:
baldurk
2019-12-16 18:10:32 +00:00
parent 0e3b1f4129
commit 05a70164f6
40 changed files with 500 additions and 744 deletions
+3 -3
View File
@@ -176,7 +176,7 @@ struct ShaderVariable
}
ShaderVariable(const ShaderVariable &) = default;
ShaderVariable &operator=(const ShaderVariable &) = default;
ShaderVariable(const char *n, float x, float y, float z, float w)
ShaderVariable(const rdcstr &n, float x, float y, float z, float w)
{
name = n;
rows = 1;
@@ -190,7 +190,7 @@ struct ShaderVariable
value.f.z = z;
value.f.w = w;
}
ShaderVariable(const char *n, int x, int y, int z, int w)
ShaderVariable(const rdcstr &n, int x, int y, int z, int w)
{
name = n;
rows = 1;
@@ -204,7 +204,7 @@ struct ShaderVariable
value.i.z = z;
value.i.w = w;
}
ShaderVariable(const char *n, uint32_t x, uint32_t y, uint32_t z, uint32_t w)
ShaderVariable(const rdcstr &n, uint32_t x, uint32_t y, uint32_t z, uint32_t w)
{
name = n;
rows = 1;
+13 -10
View File
@@ -30,6 +30,9 @@
#include "os/os_specific.h"
#include "strings/string_utils.h"
int utf8printv(char *buf, size_t bufsize, const char *fmt, va_list args);
int utf8printf(char *str, size_t bufSize, const char *fmt, ...);
void rdcassert(const char *msg, const char *file, unsigned int line, const char *func)
{
rdclog_direct(FILL_AUTO_VALUE, FILL_AUTO_VALUE, LogType::Error, RDCLOG_PROJECT, file, line,
@@ -357,16 +360,16 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
va_list args2;
va_copy(args2, args);
char timestamp[64] = {0};
rdcstr timestamp;
#if ENABLED(INCLUDE_TIMESTAMP_IN_LOG)
StringFormat::sntimef(utcTime, timestamp, 63, "[%H:%M:%S] ");
timestamp = StringFormat::sntimef(utcTime, "[%H:%M:%S] ");
#endif
char location[64] = {0};
#if ENABLED(INCLUDE_LOCATION_IN_LOG)
rdcstr loc;
loc = get_basename(file);
StringFormat::snprintf(location, 63, "% 20s(%4d) - ", loc.c_str(), line);
utf8printf(location, 63, "% 20s(%4d) - ", loc.c_str(), line);
#endif
const char *typestr[(uint32_t)LogType::Count] = {
@@ -384,8 +387,8 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
char *base = output;
int numWritten = StringFormat::snprintf(output, available, "% 4s %06u: %s%s%s - ", project, pid,
timestamp, location, typestr[(uint32_t)type]);
int numWritten = utf8printf(output, available, "% 4s %06u: %s%s%s - ", project, pid,
timestamp.c_str(), location, typestr[(uint32_t)type]);
if(numWritten < 0)
{
@@ -403,7 +406,7 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
int totalWritten = numWritten;
numWritten = StringFormat::vsnprintf(output, available, fmt, args);
numWritten = utf8printv(output, available, fmt, args);
totalWritten += numWritten;
@@ -426,9 +429,9 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
oversizedBuffer = output = new char[available + 3];
base = output;
numWritten = StringFormat::snprintf(output, available, "% 4s %06u: %s%s%s - ", project,
Process::GetCurrentPID(), timestamp, location,
typestr[(uint32_t)type]);
numWritten =
utf8printf(output, available, "% 4s %06u: %s%s%s - ", project, Process::GetCurrentPID(),
timestamp.c_str(), location, typestr[(uint32_t)type]);
output += numWritten;
available -= numWritten;
@@ -437,7 +440,7 @@ void rdclog_direct(time_t utcTime, uint32_t pid, LogType type, const char *proje
noPrefixOutput = (output - 3 - (sizeof(typestr[(uint32_t)type]) - 1));
numWritten = StringFormat::vsnprintf(output, available, fmt, args2);
numWritten = utf8printv(output, available, fmt, args2);
output += numWritten;
+4 -12
View File
@@ -103,21 +103,12 @@ private:
class ScopedTimer
{
public:
ScopedTimer(const char *file, unsigned int line, const char *fmt, ...)
ScopedTimer(const char *file, unsigned int line, const rdcstr &msg)
{
m_File = file;
m_Line = line;
va_list args;
va_start(args, fmt);
char buf[1024];
buf[1023] = 0;
StringFormat::vsnprintf(buf, 1023, fmt, args);
m_Message = buf;
va_end(args);
m_Message = msg;
}
~ScopedTimer()
@@ -133,4 +124,5 @@ private:
PerformanceTimer m_Timer;
};
#define SCOPED_TIMER(...) ScopedTimer CONCAT(timer, __LINE__)(__FILE__, __LINE__, __VA_ARGS__);
#define SCOPED_TIMER(...) \
ScopedTimer CONCAT(timer, __LINE__)(__FILE__, __LINE__, StringFormat::Fmt(__VA_ARGS__));
+4 -4
View File
@@ -1948,8 +1948,9 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
m_TextRenderer->SetOutputDimensions(swapper->GetWidth(), swapper->GetHeight());
m_TextRenderer->SetOutputWindow(swapper->GetHWND());
m_TextRenderer->RenderText(0.0f, 0.0f, "Failed to capture frame %u: %s",
m_CapturedFrames.back().frameNumber, reasonString);
m_TextRenderer->RenderText(
0.0f, 0.0f, StringFormat::Fmt("Failed to capture frame %u: %s",
m_CapturedFrames.back().frameNumber, reasonString));
}
old.ApplyState(m_pImmediateContext);
@@ -2263,8 +2264,7 @@ HRESULT WrappedID3D11Device::Present(IDXGISwapper *swapper, UINT SyncInterval, U
overlayText += StringFormat::Fmt(" %s\n", reasonString);
}
if(!overlayText.empty())
m_TextRenderer->RenderText(0.0f, 0.0f, overlayText.c_str());
m_TextRenderer->RenderText(0.0f, 0.0f, overlayText);
old.ApplyState(m_pImmediateContext);
}
+13 -25
View File
@@ -25,6 +25,7 @@
#include "d3d11_rendertext.h"
#include "maths/matrix.h"
#include "stb/stb_truetype.h"
#include "strings/string_utils.h"
#include "d3d11_context.h"
#include "d3d11_device.h"
#include "d3d11_resources.h"
@@ -341,38 +342,25 @@ void D3D11TextRenderer::SetOutputWindow(HWND w)
}
}
void D3D11TextRenderer::RenderText(float x, float y, const char *textfmt, ...)
void D3D11TextRenderer::RenderText(float x, float y, const rdcstr &text)
{
static char tmpBuf[4096];
rdcarray<rdcstr> lines;
split(text, lines, '\n');
va_list args;
va_start(args, textfmt);
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
tmpBuf[4095] = '\0';
va_end(args);
RenderTextInternal(x, y, tmpBuf);
for(const rdcstr &line : lines)
RenderTextInternal(x, y, line);
}
void D3D11TextRenderer::RenderTextInternal(float x, float y, const char *text)
void D3D11TextRenderer::RenderTextInternal(float x, float y, const rdcstr &text)
{
if(char *t = strchr((char *)text, '\n'))
{
*t = 0;
RenderTextInternal(x, y, text);
RenderTextInternal(x, y + 1.0f, t + 1);
*t = '\n';
if(text.empty())
return;
}
if(strlen(text) == 0)
return;
RDCASSERT(text.size() < FONT_MAX_CHARS);
if(!VS || !PS)
return;
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
FontCBuffer data = {};
data.TextPosition.x = x;
@@ -421,14 +409,14 @@ void D3D11TextRenderer::RenderTextInternal(float x, float y, const char *text)
{
unsigned long *texs = (unsigned long *)mapped.pData;
for(size_t i = 0; i < strlen(text); i++)
for(size_t i = 0; i < text.size(); i++)
texs[i * 4] = (text[i] - ' ');
}
else
{
Vec4f *texs = (Vec4f *)mapped.pData;
for(size_t i = 0; i < strlen(text); i++)
for(size_t i = 0; i < text.size(); i++)
{
texs[i * 6 + 0] = Vec4f(quadPos[0].x, quadPos[0].y, float(i), float(text[i] - ' '));
texs[i * 6 + 1] = Vec4f(quadPos[1].x, quadPos[1].y, float(i), float(text[i] - ' '));
@@ -487,8 +475,8 @@ void D3D11TextRenderer::RenderTextInternal(float x, float y, const char *text)
m_pImmediateContext->OMSetBlendState(BlendState, factor, 0xffffffff);
if(modern)
m_pImmediateContext->DrawInstanced(4, (uint32_t)strlen(text), 0, 0);
m_pImmediateContext->DrawInstanced(4, (uint32_t)text.size(), 0, 0);
else
m_pImmediateContext->Draw(6 * (uint32_t)strlen(text), 0);
m_pImmediateContext->Draw(6 * (uint32_t)text.size(), 0);
}
}
+2 -2
View File
@@ -45,7 +45,7 @@ public:
int GetHeight() { return RDCMAX(1, m_height); }
void SetOutputWindow(HWND w);
void RenderText(float x, float y, const char *textfmt, ...);
void RenderText(float x, float y, const rdcstr &text);
private:
int m_width = 1, m_height = 1;
@@ -54,7 +54,7 @@ private:
WrappedID3D11Device *m_pDevice = NULL;
WrappedID3D11DeviceContext *m_pImmediateContext = NULL;
void RenderTextInternal(float x, float y, const char *text);
void RenderTextInternal(float x, float y, const rdcstr &text);
static const int FONT_TEX_WIDTH = 256;
static const int FONT_TEX_HEIGHT = 128;
+99 -120
View File
@@ -766,12 +766,11 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_UNUSED
};
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%s4", typeStr[resourceData.retType]);
rdcstr type = StringFormat::Fmt("%s4", typeStr[resourceData.retType]);
if(retFmt == DXGI_FORMAT_UNKNOWN)
{
funcRet = buf;
funcRet = type;
retFmt = fmts[resourceData.retType];
}
@@ -779,13 +778,10 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
resourceData.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY)
{
if(resourceData.sampleCount > 0)
StringFormat::snprintf(buf, 63, "%s4, %d", typeStr[resourceData.retType],
resourceData.sampleCount);
type += StringFormat::Fmt(", %d", resourceData.sampleCount);
}
textureDecl += "<";
textureDecl += buf;
textureDecl += "> t";
textureDecl += "<" + type + "> t";
}
char *formats[4][2] = {
@@ -870,66 +866,35 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
}
}
char buf[256] = {0};
char buf2[256] = {0};
char buf3[256] = {0};
rdcstr texcoords;
// because of unions in .value we can pass the float versions and printf will interpret it as
// the right type according to formats
if(texcoordType == 0)
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
uv.value.f.y, uv.value.f.z, uv.value.f.w);
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
uv.value.f.y, uv.value.f.z, uv.value.f.w);
else
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
uv.value.i.y, uv.value.i.z, uv.value.i.w);
if(ddxType == 0)
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
else
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
if(ddyType == 0)
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
else
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
rdcstr texcoords = buf;
rdcstr ddx = buf2;
rdcstr ddy = buf3;
if(opcode == OPCODE_LD_MS)
{
StringFormat::snprintf(buf, 255, formats[0][1], multisampleIndex);
}
rdcstr sampleIdx = buf;
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
uv.value.i.y, uv.value.i.z, uv.value.i.w);
rdcstr offsets = "";
if(useOffsets)
{
if(offsetDim == 1)
StringFormat::snprintf(buf, 255, ", int(%d)", texelOffsets[0]);
offsets = StringFormat::Fmt(", int(%d)", texelOffsets[0]);
else if(offsetDim == 2)
StringFormat::snprintf(buf, 255, ", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
offsets = StringFormat::Fmt(", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
else if(offsetDim == 3)
StringFormat::snprintf(buf, 255, ", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1],
texelOffsets[2]);
offsets =
StringFormat::Fmt(", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1], texelOffsets[2]);
// texdim == 4 is cube arrays, no offset supported
offsets = buf;
}
char elems[] = "xyzw";
rdcstr strSwizzle = ".";
for(int i = 0; i < 4; ++i)
{
strSwizzle += elems[swizzle[i]];
}
rdcstr strGatherChannel;
switch(gatherChannel)
@@ -948,120 +913,134 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
if(opcode == OPCODE_SAMPLE || opcode == OPCODE_SAMPLE_B || opcode == OPCODE_SAMPLE_D)
{
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
rdcstr ddx;
if(ddxType == 0)
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
else
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
rdcstr ddy;
if(ddyType == 0)
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
else
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
textureDecl.c_str(), samplerDecl.c_str());
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram +=
"t.SampleGrad(s, " + texcoords + ", " + ddx + ", " + ddy + offsets + ")" + strSwizzle + ";";
sampleProgram += "\n}\n";
StringFormat::Fmt("return t.SampleGrad(s, %s, %s, %s %s)%s;\n", texcoords.c_str(),
ddx.c_str(), ddy.c_str(), offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
else if(opcode == OPCODE_SAMPLE_L)
{
// lod selection
StringFormat::snprintf(buf, 255, "%.10f", lodOrCompareValue);
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += "t.SampleLevel(s, " + texcoords + ", " + buf + offsets + ")" + strSwizzle + ";";
sampleProgram += "\n}\n";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
textureDecl.c_str(), samplerDecl.c_str());
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram +=
StringFormat::Fmt("return t.SampleLevel(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
else if(opcode == OPCODE_SAMPLE_C || opcode == OPCODE_LOD)
{
// these operations need derivatives but have no hlsl function to call to provide them, so
// we fake it in the vertex shader
rdcstr uvDim = "1";
uvDim[0] += char(texdim + texdimOffs - 1);
rdcstr uvdecl = StringFormat::Fmt("float%d uv : uvs", texdim + texdimOffs);
vsProgram = "void main(uint id : SV_VertexID, out float4 pos : SV_Position, out float" + uvDim +
" uv : uvs) {\n";
vsProgram =
"void main(uint id : SV_VertexID, out float4 pos : SV_Position, out " + uvdecl + ") {\n";
StringFormat::snprintf(
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
uv.value.f.x + ddyCalc.value.f.x * 2.0f, uv.value.f.y + ddyCalc.value.f.y * 2.0f,
uv.value.f.z + ddyCalc.value.f.z * 2.0f, uv.value.f.w + ddyCalc.value.f.w * 2.0f);
rdcstr uvPlusDDX = StringFormat::Fmt(
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddyCalc.value.f.x * 2.0f,
uv.value.f.y + ddyCalc.value.f.y * 2.0f, uv.value.f.z + ddyCalc.value.f.z * 2.0f,
uv.value.f.w + ddyCalc.value.f.w * 2.0f);
vsProgram += "if(id == 0) uv = " + rdcstr(buf) + ";\n";
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
uv.value.f.y, uv.value.f.z, uv.value.f.w);
vsProgram += "if(id == 1) uv = " + rdcstr(buf) + ";\n";
StringFormat::snprintf(
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
uv.value.f.x + ddxCalc.value.f.x * 2.0f, uv.value.f.y + ddxCalc.value.f.y * 2.0f,
uv.value.f.z + ddxCalc.value.f.z * 2.0f, uv.value.f.w + ddxCalc.value.f.w * 2.0f);
vsProgram += "if(id == 2) uv = " + rdcstr(buf) + ";\n";
rdcstr uvPlusDDY = StringFormat::Fmt(
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddxCalc.value.f.x * 2.0f,
uv.value.f.y + ddxCalc.value.f.y * 2.0f, uv.value.f.z + ddxCalc.value.f.z * 2.0f,
uv.value.f.w + ddxCalc.value.f.w * 2.0f);
vsProgram += "if(id == 0) uv = " + uvPlusDDX + ";\n";
vsProgram += "if(id == 1) uv = " + texcoords + ";\n";
vsProgram += "if(id == 2) uv = " + uvPlusDDY + ";\n";
vsProgram += "pos = float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n";
vsProgram += "}";
if(opcode == OPCODE_SAMPLE_C)
{
// comparison value
StringFormat::snprintf(buf, 255, "%.10f", lodOrCompareValue);
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
" uv : uvs) : SV_Target0\n{\n";
sampleProgram += "return t.SampleCmpLevelZero(s, uv, " + rdcstr(buf) + offsets + ").xxxx;";
sampleProgram += "\n}\n";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
textureDecl.c_str(), samplerDecl.c_str());
sampleProgram +=
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("return t.SampleCmpLevelZero(s, uv, %.10f %s).xxxx;\n",
lodOrCompareValue, offsets.c_str());
sampleProgram += "}\n";
}
else if(opcode == OPCODE_LOD)
{
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
" uv : uvs) : SV_Target0\n{\n";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
textureDecl.c_str(), samplerDecl.c_str());
sampleProgram +=
"return float4(t.CalculateLevelOfDetail(s, uv), t.CalculateLevelOfDetailUnclamped(s, "
"uv), 0.0f, 0.0f);";
sampleProgram += "\n}\n";
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
sampleProgram +=
"return float4(t.CalculateLevelOfDetail(s, uv),\n"
" t.CalculateLevelOfDetailUnclamped(s, uv),\n"
" 0.0f, 0.0f);\n";
sampleProgram += "}\n";
}
}
else if(opcode == OPCODE_SAMPLE_C_LZ)
{
// comparison value
StringFormat::snprintf(buf, 255, "%.10f", lodOrCompareValue);
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
textureDecl.c_str(), samplerDecl.c_str());
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram +=
"t.SampleCmpLevelZero(s, " + texcoords + ", " + buf + offsets + ")" + strSwizzle + ";";
sampleProgram += "\n}\n";
StringFormat::Fmt("return t.SampleCmpLevelZero(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
else if(opcode == OPCODE_LD)
{
sampleProgram = textureDecl + " : register(t0);\n\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += "t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n\n", textureDecl.c_str());
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += "return t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
sampleProgram += "\n}\n";
}
else if(opcode == OPCODE_LD_MS)
{
sampleProgram = textureDecl + " : register(t0);\n\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += "t.Load(" + texcoords + ", " + sampleIdx + offsets + ")" + strSwizzle + ";";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n\n", textureDecl.c_str());
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("t.Load(%s, int(%d) %s)%s;\n", texcoords.c_str(),
multisampleIndex, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "\n}\n";
}
else if(opcode == OPCODE_GATHER4 || opcode == OPCODE_GATHER4_PO)
{
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram +=
"t.Gather" + strGatherChannel + "(s, " + texcoords + offsets + ")" + strSwizzle + ";";
sampleProgram += "\n}\n";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
textureDecl.c_str(), samplerDecl.c_str());
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("return t.Gather%s(s, %s %s)%s;\n", strGatherChannel.c_str(),
texcoords.c_str(), offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
else if(opcode == OPCODE_GATHER4_C || opcode == OPCODE_GATHER4_PO_C)
{
// comparison value
StringFormat::snprintf(buf, 255, ", %.10f", lodOrCompareValue);
sampleProgram = textureDecl + " : register(t0);\n" + samplerDecl + " : register(s0);\n\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += "t.GatherCmp" + strGatherChannel + "(s, " + texcoords + buf + offsets + ")" +
strSwizzle + ";";
sampleProgram += "\n}\n";
sampleProgram = StringFormat::Fmt("%s : register(t0);\n%s : register(s0);\n\n",
textureDecl.c_str(), samplerDecl.c_str());
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("return t.GatherCmp%s(s, %s, %.10f %s)%s;\n",
strGatherChannel.c_str(), texcoords.c_str(),
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
ID3D11VertexShader *vs =
+1 -4
View File
@@ -737,10 +737,7 @@ rdcstr PIX3SprintfParams(const rdcstr &Format, const UINT64 *pData)
// numerical values
else
{
static const UINT MAX_CHARACTERS_FOR_VALUE = 32;
char formattedValue[MAX_CHARACTERS_FOR_VALUE];
StringFormat::snprintf(formattedValue, MAX_CHARACTERS_FOR_VALUE, formatPart.c_str(), *pData);
finalString += formattedValue;
finalString += StringFormat::Fmt(formatPart.c_str(), *pData);
++pData;
}
+1 -2
View File
@@ -1590,8 +1590,7 @@ HRESULT WrappedID3D12Device::Present(ID3D12GraphicsCommandList *pOverlayCommandL
if(m_InvalidPSO)
overlayText += "ERROR: Invalid PSO created, likely using DXIL which is not supported.\n";
if(!overlayText.empty())
m_TextRenderer->RenderText(list, 0.0f, 0.0f, overlayText.c_str());
m_TextRenderer->RenderText(list, 0.0f, 0.0f, overlayText);
// transition backbuffer back again
std::swap(barrier.Transition.StateBefore, barrier.Transition.StateAfter);
+12 -24
View File
@@ -27,6 +27,7 @@
#include "maths/matrix.h"
#include "maths/vec.h"
#include "stb/stb_truetype.h"
#include "strings/string_utils.h"
#include "d3d12_device.h"
#include "d3d12_shader_cache.h"
@@ -444,35 +445,22 @@ D3D12TextRenderer::~D3D12TextRenderer()
}
void D3D12TextRenderer::RenderText(ID3D12GraphicsCommandList *list, float x, float y,
const char *textfmt, ...)
const rdcstr &text)
{
static char tmpBuf[4096];
rdcarray<rdcstr> lines;
split(text, lines, '\n');
va_list args;
va_start(args, textfmt);
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
tmpBuf[4095] = '\0';
va_end(args);
RenderTextInternal(list, x, y, tmpBuf);
for(const rdcstr &line : lines)
RenderTextInternal(list, x, y, line);
}
void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, float x, float y,
const char *text)
const rdcstr &text)
{
if(char *t = strchr((char *)text, '\n'))
{
*t = 0;
RenderTextInternal(list, x, y, text);
RenderTextInternal(list, x, y + 1.0f, t + 1);
*t = '\n';
return;
}
if(strlen(text) == 0)
if(text.empty())
return;
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
RDCASSERT(text.size() < FONT_MAX_CHARS);
FontCBuffer data = {};
@@ -508,7 +496,7 @@ void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
Constants->Unmap(0, &range);
}
size_t chars = strlen(text);
size_t chars = text.size();
size_t charOffset = CharOffset;
@@ -530,7 +518,7 @@ void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
texs += charOffset * 4;
for(size_t i = 0; i < strlen(text); i++)
for(size_t i = 0; i < chars; i++)
texs[i * 4] = (text[i] - ' ');
CharBuffer->Unmap(0, NULL);
@@ -563,7 +551,7 @@ void D3D12TextRenderer::RenderTextInternal(ID3D12GraphicsCommandList *list, floa
2, CharBuffer->GetGPUVirtualAddress() + charOffset * sizeof(Vec4f));
list->SetGraphicsRootDescriptorTable(3, descHeap->GetGPUDescriptorHandleForHeapStart());
list->DrawInstanced(4, (uint32_t)strlen(text), 0, 0);
list->DrawInstanced(4, (uint32_t)chars, 0, 0);
}
ConstRingIdx++;
+2 -2
View File
@@ -47,7 +47,7 @@ public:
}
int GetWidth() { return RDCMAX(1, m_width); }
int GetHeight() { return RDCMAX(1, m_height); }
void RenderText(ID3D12GraphicsCommandList *list, float x, float y, const char *textfmt, ...);
void RenderText(ID3D12GraphicsCommandList *list, float x, float y, const rdcstr &text);
private:
int m_width = 1, m_height = 1;
@@ -59,7 +59,7 @@ private:
FMTNUM_BACKBUFFER,
} m_BBFmtIdx;
void RenderTextInternal(ID3D12GraphicsCommandList *list, float x, float y, const char *text);
void RenderTextInternal(ID3D12GraphicsCommandList *list, float x, float y, const rdcstr &text);
static const int FONT_TEX_WIDTH = 256;
static const int FONT_TEX_HEIGHT = 128;
+78 -98
View File
@@ -254,12 +254,11 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_UNUSED
};
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%s4", typeStr[resourceData.retType]);
rdcstr type = StringFormat::Fmt("%s4", typeStr[resourceData.retType]);
if(retFmt == DXGI_FORMAT_UNKNOWN)
{
funcRet = buf;
funcRet = type;
retFmt = fmts[resourceData.retType];
}
@@ -267,13 +266,10 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
resourceData.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY)
{
if(resourceData.sampleCount > 0)
StringFormat::snprintf(buf, 63, "%s4, %d", typeStr[resourceData.retType],
resourceData.sampleCount);
type += StringFormat::Fmt(", %d", resourceData.sampleCount);
}
textureDecl += "<";
textureDecl += buf;
textureDecl += "> t";
textureDecl += "<" + type + "> t";
}
char *formats[4][2] = {
@@ -358,65 +354,35 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
}
}
char buf[256] = {0};
char buf2[256] = {0};
char buf3[256] = {0};
rdcstr texcoords;
// because of unions in .value we can pass the float versions and printf will interpret it as
// the right type according to formats
if(texcoordType == 0)
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
uv.value.f.y, uv.value.f.z, uv.value.f.w);
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
uv.value.f.y, uv.value.f.z, uv.value.f.w);
else
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
uv.value.i.y, uv.value.i.z, uv.value.i.w);
texcoords = StringFormat::Fmt(formats[texdim + texdimOffs - 1][texcoordType], uv.value.i.x,
uv.value.i.y, uv.value.i.z, uv.value.i.w);
if(ddxType == 0)
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
else
StringFormat::snprintf(buf2, 255, formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
if(ddyType == 0)
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
else
StringFormat::snprintf(buf3, 255, formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
rdcstr texcoords = buf;
rdcstr ddx = buf2;
rdcstr ddy = buf3;
if(opcode == OPCODE_LD_MS)
{
StringFormat::snprintf(buf, 255, formats[0][1], multisampleIndex);
}
rdcstr sampleIdx = buf;
rdcstr offsets = "";
if(useOffsets)
{
if(offsetDim == 1)
StringFormat::snprintf(buf, 255, ", int(%d)", texelOffsets[0]);
offsets = StringFormat::Fmt(", int(%d)", texelOffsets[0]);
else if(offsetDim == 2)
StringFormat::snprintf(buf, 255, ", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
offsets = StringFormat::Fmt(", int2(%d, %d)", texelOffsets[0], texelOffsets[1]);
else if(offsetDim == 3)
StringFormat::snprintf(buf, 255, ", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1],
texelOffsets[2]);
offsets =
StringFormat::Fmt(", int3(%d, %d, %d)", texelOffsets[0], texelOffsets[1], texelOffsets[2]);
// texdim == 4 is cube arrays, no offset supported
offsets = buf;
}
char elems[] = "xyzw";
rdcstr strSwizzle = ".";
for(int i = 0; i < 4; ++i)
{
strSwizzle += elems[swizzle[i]];
}
rdcstr strGatherChannel;
switch(gatherChannel)
@@ -438,12 +404,30 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
if(opcode == OPCODE_SAMPLE || opcode == OPCODE_SAMPLE_B || opcode == OPCODE_SAMPLE_D)
{
rdcstr ddx;
if(ddxType == 0)
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.f.x,
ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w);
else
ddx = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddxType], ddxCalc.value.i.x,
ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w);
rdcstr ddy;
if(ddyType == 0)
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.f.x,
ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w);
else
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += StringFormat::Fmt("t.SampleGrad(s, %s, %s, %s%s)%s;", texcoords.c_str(),
sampleProgram += StringFormat::Fmt("t.SampleGrad(s, %s, %s, %s %s)%s;\n", texcoords.c_str(),
ddx.c_str(), ddy.c_str(), offsets.c_str(), strSwizzle.c_str());
sampleProgram += "\n}\n";
sampleProgram += "}\n";
}
else if(opcode == OPCODE_SAMPLE_L)
{
@@ -451,40 +435,33 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += StringFormat::Fmt("t.SampleLevel(s, %s, %.10f%s)%s;", texcoords.c_str(),
sampleProgram += StringFormat::Fmt("t.SampleLevel(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "\n}\n";
sampleProgram += "}\n";
}
else if(opcode == OPCODE_SAMPLE_C || opcode == OPCODE_LOD)
{
// these operations need derivatives but have no hlsl function to call to provide them, so
// we fake it in the vertex shader
rdcstr uvDim = "1";
uvDim[0] += char(texdim + texdimOffs - 1);
rdcstr uvdecl = StringFormat::Fmt("float%d uv : uvs", texdim + texdimOffs);
vsProgram = "void main(uint id : SV_VertexID, out float4 pos : SV_Position, out float" + uvDim +
" uv : uvs) {\n";
vsProgram =
"void main(uint id : SV_VertexID, out float4 pos : SV_Position, out " + uvdecl + ") {\n";
StringFormat::snprintf(
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
uv.value.f.x + ddyCalc.value.f.x * 2.0f, uv.value.f.y + ddyCalc.value.f.y * 2.0f,
uv.value.f.z + ddyCalc.value.f.z * 2.0f, uv.value.f.w + ddyCalc.value.f.w * 2.0f);
rdcstr uvPlusDDX = StringFormat::Fmt(
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddyCalc.value.f.x * 2.0f,
uv.value.f.y + ddyCalc.value.f.y * 2.0f, uv.value.f.z + ddyCalc.value.f.z * 2.0f,
uv.value.f.w + ddyCalc.value.f.w * 2.0f);
vsProgram += "if(id == 0) uv = " + rdcstr(buf) + ";\n";
StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x,
uv.value.f.y, uv.value.f.z, uv.value.f.w);
vsProgram += "if(id == 1) uv = " + rdcstr(buf) + ";\n";
StringFormat::snprintf(
buf, 255, formats[texdim + texdimOffs - 1][texcoordType],
uv.value.f.x + ddxCalc.value.f.x * 2.0f, uv.value.f.y + ddxCalc.value.f.y * 2.0f,
uv.value.f.z + ddxCalc.value.f.z * 2.0f, uv.value.f.w + ddxCalc.value.f.w * 2.0f);
vsProgram += "if(id == 2) uv = " + rdcstr(buf) + ";\n";
rdcstr uvPlusDDY = StringFormat::Fmt(
formats[texdim + texdimOffs - 1][texcoordType], uv.value.f.x + ddxCalc.value.f.x * 2.0f,
uv.value.f.y + ddxCalc.value.f.y * 2.0f, uv.value.f.z + ddxCalc.value.f.z * 2.0f,
uv.value.f.w + ddxCalc.value.f.w * 2.0f);
vsProgram += "if(id == 0) uv = " + uvPlusDDX + ";\n";
vsProgram += "if(id == 1) uv = " + texcoords + ";\n";
vsProgram += "if(id == 2) uv = " + uvPlusDDY + ";\n";
vsProgram += "pos = float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n";
vsProgram += "}";
@@ -493,22 +470,23 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
// comparison value
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
" uv : uvs) : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("return t.SampleCmpLevelZero(s, uv, %.10f%s).xxxx;",
sampleProgram +=
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("t.SampleCmpLevelZero(s, uv, %.10f %s).xxxx;\n",
lodOrCompareValue, offsets.c_str());
sampleProgram += "\n}\n";
sampleProgram += "}\n";
}
else if(opcode == OPCODE_LOD)
{
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim +
" uv : uvs) : SV_Target0\n{\n";
sampleProgram +=
"return float4(t.CalculateLevelOfDetail(s, uv), t.CalculateLevelOfDetailUnclamped(s, "
"uv), 0.0f, 0.0f);";
sampleProgram += "\n}\n";
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
sampleProgram +=
"return float4(t.CalculateLevelOfDetail(s, uv),\n"
" t.CalculateLevelOfDetailUnclamped(s, uv),\n"
" 0.0f, 0.0f);\n";
sampleProgram += "}\n";
}
}
else if(opcode == OPCODE_SAMPLE_C_LZ)
@@ -516,44 +494,46 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
// comparison value
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += StringFormat::Fmt("t.SampleCmpLevelZero(s, %s, %.10f%s)%s;", texcoords.c_str(),
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "\n}\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram +=
StringFormat::Fmt("return t.SampleCmpLevelZero(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
else if(opcode == OPCODE_LD)
{
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n\n", textureDecl.c_str(), texSlot);
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += "t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += "return t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
sampleProgram += "\n}\n";
}
else if(opcode == OPCODE_LD_MS)
{
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n\n", textureDecl.c_str(), texSlot);
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += "t.Load(" + texcoords + ", " + sampleIdx + offsets + ")" + strSwizzle + ";";
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("t.Load(%s, int(%d) %s)%s;\n", texcoords.c_str(),
multisampleIndex, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "\n}\n";
}
else if(opcode == OPCODE_GATHER4 || opcode == OPCODE_GATHER4_PO)
{
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram +=
"t.Gather" + strGatherChannel + "(s, " + texcoords + offsets + ")" + strSwizzle + ";";
sampleProgram += "\n}\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("return t.Gather%s(s, %s %s)%s;\n", strGatherChannel.c_str(),
texcoords.c_str(), offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
else if(opcode == OPCODE_GATHER4_C || opcode == OPCODE_GATHER4_PO_C)
{
// comparison value
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
sampleProgram += StringFormat::Fmt("t.GatherCmp%s(s, %s, %.10f%s)%s;", strGatherChannel.c_str(),
texcoords.c_str(), lodOrCompareValue, offsets.c_str(),
strSwizzle.c_str());
sampleProgram += "\n}\n";
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
sampleProgram += StringFormat::Fmt("return t.GatherCmp%s(s, %s, %.10f %s)%s;\n",
strGatherChannel.c_str(), texcoords.c_str(),
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
sampleProgram += "}\n";
}
// Create VS/PS to fetch the sample
+10 -22
View File
@@ -25,6 +25,7 @@
#include "d3d8_debug.h"
#include "os/os_specific.h"
#include "stb/stb_truetype.h"
#include "strings/string_utils.h"
D3D8DebugManager::D3D8DebugManager(WrappedD3DDevice8 *wrapper)
: m_WrappedDevice(wrapper), m_fvf(D3DFVF_XYZ | D3DFVF_TEX1)
@@ -127,34 +128,21 @@ void D3D8DebugManager::SetOutputWindow(HWND w)
// m_supersamplingY = float(m_height) / float(rect.bottom - rect.top);
}
void D3D8DebugManager::RenderText(float x, float y, const char *textfmt, ...)
void D3D8DebugManager::RenderText(float x, float y, const rdcstr &text)
{
static char tmpBuf[4096];
rdcarray<rdcstr> lines;
split(text, lines, '\n');
va_list args;
va_start(args, textfmt);
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
tmpBuf[4095] = '\0';
va_end(args);
RenderTextInternal(x, y, tmpBuf);
for(const rdcstr &line : lines)
RenderTextInternal(x, y, line);
}
void D3D8DebugManager::RenderTextInternal(float x, float y, const char *text)
void D3D8DebugManager::RenderTextInternal(float x, float y, const rdcstr &text)
{
if(char *t = strchr((char *)text, '\n'))
{
*t = 0;
RenderTextInternal(x, y, text);
RenderTextInternal(x, y + 1.0f, t + 1);
*t = '\n';
return;
}
if(strlen(text) == 0)
if(text.empty())
return;
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
RDCASSERT(text.size() < FONT_MAX_CHARS);
// transforms
float width = (float)m_width;
@@ -265,7 +253,7 @@ void D3D8DebugManager::RenderTextInternal(float x, float y, const char *text)
Quad background;
UINT triangleCount = 0;
{
UINT quadCount = (UINT)strlen(text); // calculate string length
UINT quadCount = (UINT)text.size(); // calculate string length
triangleCount = quadCount * 2;
// create text VB
+2 -2
View File
@@ -36,7 +36,7 @@ public:
D3D8DebugManager(WrappedD3DDevice8 *wrapper);
~D3D8DebugManager();
void RenderText(float x, float y, const char *textfmt, ...);
void RenderText(float x, float y, const rdcstr &text);
void SetOutputDimensions(int w, int h)
{
@@ -49,7 +49,7 @@ public:
bool InitFontRendering();
void ShutdownFontRendering();
void RenderTextInternal(float x, float y, const char *text);
void RenderTextInternal(float x, float y, const rdcstr &text);
static const int FONT_TEX_WIDTH = 256;
static const int FONT_TEX_HEIGHT = 128;
+1 -2
View File
@@ -283,8 +283,7 @@ HRESULT __stdcall WrappedD3DDevice8::Present(CONST RECT *pSourceRect, CONST RECT
overlayText += "Captures not supported with D3D8\n";
if(!overlayText.empty())
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText.c_str());
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText);
stateBlockRes = m_device->ApplyStateBlock(stateBlock);
res |= m_device->EndScene();
+10 -22
View File
@@ -25,6 +25,7 @@
#include "d3d9_debug.h"
#include "os/os_specific.h"
#include "stb/stb_truetype.h"
#include "strings/string_utils.h"
D3D9DebugManager::D3D9DebugManager(WrappedD3DDevice9 *wrapper)
: m_WrappedDevice(wrapper), m_fvf(D3DFVF_XYZ | D3DFVF_TEX1)
@@ -127,34 +128,21 @@ void D3D9DebugManager::SetOutputWindow(HWND w)
// m_supersamplingY = float(m_height) / float(rect.bottom - rect.top);
}
void D3D9DebugManager::RenderText(float x, float y, const char *textfmt, ...)
void D3D9DebugManager::RenderText(float x, float y, const rdcstr &text)
{
static char tmpBuf[4096];
rdcarray<rdcstr> lines;
split(text, lines, '\n');
va_list args;
va_start(args, textfmt);
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
tmpBuf[4095] = '\0';
va_end(args);
RenderTextInternal(x, y, tmpBuf);
for(const rdcstr &line : lines)
RenderTextInternal(x, y, line);
}
void D3D9DebugManager::RenderTextInternal(float x, float y, const char *text)
void D3D9DebugManager::RenderTextInternal(float x, float y, const rdcstr &text)
{
if(char *t = strchr((char *)text, '\n'))
{
*t = 0;
RenderTextInternal(x, y, text);
RenderTextInternal(x, y + 1.0f, t + 1);
*t = '\n';
return;
}
if(strlen(text) == 0)
if(text.empty())
return;
RDCASSERT(strlen(text) < FONT_MAX_CHARS);
RDCASSERT(text.size() < FONT_MAX_CHARS);
// transforms
float width = (float)m_width;
@@ -272,7 +260,7 @@ void D3D9DebugManager::RenderTextInternal(float x, float y, const char *text)
Quad background;
UINT triangleCount = 0;
{
UINT quadCount = (UINT)strlen(text); // calculate string length
UINT quadCount = (UINT)text.size(); // calculate string length
triangleCount = quadCount * 2;
// create text VB
+2 -2
View File
@@ -36,7 +36,7 @@ public:
D3D9DebugManager(WrappedD3DDevice9 *wrapper);
~D3D9DebugManager();
void RenderText(float x, float y, const char *textfmt, ...);
void RenderText(float x, float y, const rdcstr &text);
void SetOutputDimensions(int w, int h)
{
@@ -49,7 +49,7 @@ public:
bool InitFontRendering();
void ShutdownFontRendering();
void RenderTextInternal(float x, float y, const char *text);
void RenderTextInternal(float x, float y, const rdcstr &text);
static const int FONT_TEX_WIDTH = 256;
static const int FONT_TEX_HEIGHT = 128;
+1 -2
View File
@@ -251,8 +251,7 @@ HRESULT __stdcall WrappedD3DDevice9::Present(CONST RECT *pSourceRect, CONST RECT
overlayText += "Captures not supported with D3D9\n";
if(!overlayText.empty())
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText.c_str());
GetDebugManager()->RenderText(0.0f, 0.0f, overlayText);
stateBlockRes = stateBlock->Apply();
res |= m_device->EndScene();
+3 -4
View File
@@ -2033,8 +2033,7 @@ void WrappedOpenGL::SwapBuffers(WindowingSystem winSystem, void *windowHandle)
overlayText += StringFormat::Fmt(" %s\n", reasonString);
}
if(!overlayText.empty())
RenderOverlayText(0.0f, 0.0f, overlayText.c_str());
RenderText(0.0f, 0.0f, overlayText);
// swallow all errors we might have inadvertantly caused. This is
// better than letting an error propagate and maybe screw up the
@@ -2380,8 +2379,8 @@ bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd)
{
ContextData &ctxdata = GetCtxData();
RenderOverlayText(0.0f, 0.0f, "Failed to capture frame %u: %s",
m_CapturedFrames.back().frameNumber, reasonString);
RenderText(0.0f, 0.0f, StringFormat::Fmt("Failed to capture frame %u: %s",
m_CapturedFrames.back().frameNumber, reasonString));
// swallow all errors we might have inadvertantly caused. This is
// better than letting an error propagate and maybe screw up the
+5 -12
View File
@@ -531,8 +531,8 @@ private:
static const int FONT_TEX_HEIGHT = 128;
static const int FONT_MAX_CHARS = 256;
void RenderOverlayText(float x, float y, const char *fmt, ...);
void RenderOverlayStr(float x, float y, const char *str);
void RenderText(float x, float y, const rdcstr &text);
void RenderTextInternal(float x, float y, const rdcstr &text);
void CreateReplayBackbuffer(const GLInitParams &params, ResourceId fboOrigId, GLuint &fbo,
rdcstr bbname);
@@ -593,7 +593,7 @@ public:
}
SDFile &GetStructuredFile() { return *m_StructuredFile; }
void SetFetchCounters(bool in) { m_FetchCounters = in; };
void SetDebugMsgContext(const char *context) { m_DebugMsgContext = context; }
void SetDebugMsgContext(const rdcstr &context) { m_DebugMsgContext = context; }
void AddDebugMessage(DebugMessage msg)
{
if(IsReplayMode(m_State))
@@ -2496,17 +2496,10 @@ public:
class ScopedDebugContext
{
public:
ScopedDebugContext(WrappedOpenGL *driver, const char *fmt, ...)
ScopedDebugContext(WrappedOpenGL *driver, const rdcstr &msg)
{
va_list args;
va_start(args, fmt);
char buf[1024];
buf[1023] = 0;
StringFormat::vsnprintf(buf, 1023, fmt, args);
va_end(args);
m_Driver = driver;
m_Driver->SetDebugMsgContext(buf);
m_Driver->SetDebugMsgContext(msg);
}
~ScopedDebugContext() { m_Driver->SetDebugMsgContext(""); }
+16 -28
View File
@@ -277,42 +277,29 @@ void WrappedOpenGL::ContextData::CreateDebugData()
}
}
void WrappedOpenGL::RenderOverlayText(float x, float y, const char *fmt, ...)
void WrappedOpenGL::RenderText(float x, float y, const rdcstr &text)
{
static char tmpBuf[4096];
va_list args;
va_start(args, fmt);
StringFormat::vsnprintf(tmpBuf, 4095, fmt, args);
tmpBuf[4095] = '\0';
va_end(args);
ContextData &ctxdata = GetCtxData();
GLPushPopState textState;
textState.Push(ctxdata.Modern());
RenderOverlayStr(x, y, tmpBuf);
rdcarray<rdcstr> lines;
split(text, lines, '\n');
for(const rdcstr &line : lines)
RenderTextInternal(x, y, line);
textState.Pop(ctxdata.Modern());
}
void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
void WrappedOpenGL::RenderTextInternal(float x, float y, const rdcstr &text)
{
if(char *t = strchr((char *)text, '\n'))
{
*t = 0;
RenderOverlayStr(x, y, text);
RenderOverlayStr(x, y + 1.0f, t + 1);
*t = '\n';
return;
}
if(strlen(text) == 0)
if(text.empty())
return;
RDCASSERT(strlen(text) < (size_t)FONT_MAX_CHARS);
RDCASSERT(text.size() < FONT_MAX_CHARS);
ContextData &ctxdata = GetCtxData();
@@ -324,7 +311,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
{
GL.glBindBuffer(eGL_ARRAY_BUFFER, ctxdata.ArrayBuffer);
size_t len = strlen(text);
size_t len = text.size();
if((int)len > FONT_MAX_CHARS)
{
@@ -334,7 +321,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
if(!printedWarning)
{
printedWarning = true;
RDCWARN("log string '%s' is too long", text, (int)len);
RDCWARN("log string '%s' is too long", text.c_str(), (int)len);
}
len = FONT_MAX_CHARS;
@@ -520,7 +507,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
stbtt_aligned_quad q;
const char *prepass = text;
const char *prepass = text.c_str();
while(*prepass)
{
char c = *prepass;
@@ -554,9 +541,10 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
float mul = ctxdata.initParams.isYFlipped ? -1.0f : 1.0f;
while(*text)
const char *str = text.c_str();
while(*str)
{
char c = *text;
char c = *str;
if(c > FONT_FIRST_CHAR && c < FONT_LAST_CHAR)
{
stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - FONT_FIRST_CHAR - 1, &x,
@@ -574,7 +562,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text)
{
x += chardata[0].xadvance;
}
++text;
++str;
}
}
m_Platform.DrawQuads((float)ctxdata.initParams.width, (float)ctxdata.initParams.height, vertices);
+2 -8
View File
@@ -144,10 +144,7 @@ rdcstr DoStringise(const UniformType &el)
default: break;
}
char tostrBuf[256] = {0};
StringFormat::snprintf(tostrBuf, 255, "WrappedOpenGL::UniformType<%d>", el);
return tostrBuf;
return StringFormat::Fmt("UniformType(%d)", el);
}
template <>
@@ -4118,10 +4115,7 @@ rdcstr DoStringise(const RDCGLenum &el)
default: break;
}
char tostrBuf[256] = {0};
StringFormat::snprintf(tostrBuf, 255, "GLenum<%x>", (uint32_t)el);
return tostrBuf;
return StringFormat::Fmt("GLenum(%x)", el);
#define GLenum RDCGLenum
}
+10 -28
View File
@@ -46,8 +46,6 @@ DXBC::Reflection *Program::GuessReflection()
// useful reflection is present
DXBC::Reflection *ret = new DXBC::Reflection;
char buf[64] = {0};
for(size_t i = 0; i < m_Declarations.size(); i++)
{
Declaration &dcl = m_Declarations[i];
@@ -64,9 +62,7 @@ DXBC::Reflection *Program::GuessReflection()
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
StringFormat::snprintf(buf, 63, "sampler%u", idx);
desc.name = buf;
desc.name = StringFormat::Fmt("sampler%u", idx);
desc.type = DXBC::ShaderInputBind::TYPE_SAMPLER;
desc.space = dcl.space;
desc.reg = idx;
@@ -97,9 +93,7 @@ DXBC::Reflection *Program::GuessReflection()
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
StringFormat::snprintf(buf, 63, "texture%u", idx);
desc.name = buf;
desc.name = StringFormat::Fmt("texture%u", idx);
desc.type = DXBC::ShaderInputBind::TYPE_TEXTURE;
desc.space = dcl.space;
desc.reg = idx;
@@ -170,10 +164,8 @@ DXBC::Reflection *Program::GuessReflection()
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
StringFormat::snprintf(buf, 63, "%sbytebuffer%u",
dcl.operand.type != TYPE_RESOURCE ? "rw" : "", idx);
desc.name = buf;
desc.name =
StringFormat::Fmt("%sbytebuffer%u", dcl.operand.type != TYPE_RESOURCE ? "rw" : "", idx);
desc.type = dcl.operand.type == TYPE_RESOURCE
? DXBC::ShaderInputBind::TYPE_BYTEADDRESS
: DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS;
@@ -209,9 +201,7 @@ DXBC::Reflection *Program::GuessReflection()
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
StringFormat::snprintf(buf, 63, "structuredbuffer%u", idx);
desc.name = buf;
desc.name = StringFormat::Fmt("structuredbuffer%u", idx);
desc.type = DXBC::ShaderInputBind::TYPE_STRUCTURED;
desc.space = dcl.space;
desc.reg = idx;
@@ -242,9 +232,7 @@ DXBC::Reflection *Program::GuessReflection()
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
StringFormat::snprintf(buf, 63, "uav%u", idx);
desc.name = buf;
desc.name = StringFormat::Fmt("uav%u", idx);
desc.type =
DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED; // doesn't seem to be anything that
// determines append vs consume vs
@@ -280,9 +268,7 @@ DXBC::Reflection *Program::GuessReflection()
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
StringFormat::snprintf(buf, 63, "uav%u", idx);
desc.name = buf;
desc.name = StringFormat::Fmt("uav%u", idx);
desc.type = DXBC::ShaderInputBind::TYPE_UAV_RWTYPED;
desc.space = dcl.space;
desc.reg = idx;
@@ -346,9 +332,7 @@ DXBC::Reflection *Program::GuessReflection()
uint32_t idx = (uint32_t)dcl.operand.indices[0].index;
uint32_t numVecs = (uint32_t)dcl.operand.indices[1].index;
StringFormat::snprintf(buf, 63, "cbuffer%u", idx);
desc.name = buf;
desc.name = StringFormat::Fmt("cbuffer%u", idx);
desc.type = DXBC::ShaderInputBind::TYPE_CBUFFER;
desc.space = dcl.space;
desc.reg = idx;
@@ -386,11 +370,9 @@ DXBC::Reflection *Program::GuessReflection()
DXBC::CBufferVariable var;
if(desc.space > 0)
StringFormat::snprintf(buf, 63, "cb%u_%u_v%u", desc.space, desc.reg, v);
var.name = StringFormat::Fmt("cb%u_%u_v%u", desc.space, desc.reg, v);
else
StringFormat::snprintf(buf, 63, "cb%u_v%u", desc.reg, v);
var.name = buf;
var.name = StringFormat::Fmt("cb%u_v%u", desc.reg, v);
var.descriptor.defaultValue.resize(4 * sizeof(float));
@@ -342,27 +342,18 @@ rdcstr TypeName(CBufferVariableType::Descriptor desc)
ret = "<unnamed>";
else
{
char buf[64] = {0};
if(desc.rows > 1)
{
StringFormat::snprintf(buf, 63, "%s%dx%d", type, desc.rows, desc.cols);
ret = StringFormat::Fmt("%s%dx%d", type, desc.rows, desc.cols);
if(desc.varClass == CLASS_MATRIX_ROWS)
{
ret = "row_major ";
ret += buf;
}
else
{
ret = buf;
ret = "row_major " + ret;
}
}
else if(desc.cols > 1)
{
StringFormat::snprintf(buf, 63, "%s%d", type, desc.cols);
ret = buf;
ret = StringFormat::Fmt("%s%d", type, desc.cols);
}
else
{
@@ -400,9 +391,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte
}
else
{
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "unnamed_iface_0x%08x", typeOffset);
ret.descriptor.name += " " + rdcstr(buf);
ret.descriptor.name += StringFormat::Fmt(" unnamed_iface_0x%08x", typeOffset);
}
}
@@ -415,9 +404,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte
}
else
{
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "unnamed_struct_0x%08x", typeOffset);
ret.descriptor.name = buf;
ret.descriptor.name = StringFormat::Fmt("unnamed_struct_0x%08x", typeOffset);
}
}
+4 -11
View File
@@ -1093,11 +1093,7 @@ void State::Init()
for(uint32_t t = 0; t < decl.numTemps; t++)
{
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "r%d", t);
registers.push_back(ShaderVariable(buf, 0l, 0l, 0l, 0l));
registers.push_back(ShaderVariable(StringFormat::Fmt("r%u", t), 0l, 0l, 0l, 0l));
}
}
if(decl.declaration == OPCODE_DCL_INDEXABLE_TEMP)
@@ -1115,18 +1111,15 @@ void State::Init()
{
indexableTemps.resize(indexTempSizes.size());
for(int32_t i = 0; i < (int32_t)indexTempSizes.size(); i++)
for(size_t i = 0; i < indexTempSizes.size(); i++)
{
if(indexTempSizes[i] > 0)
{
indexableTemps[i].members.resize(indexTempSizes[i]);
for(uint32_t t = 0; t < indexTempSizes[i]; t++)
{
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "x%u[%u]", i, t);
indexableTemps[i].members[t] = ShaderVariable(buf, 0l, 0l, 0l, 0l);
indexableTemps[i].members[t] =
ShaderVariable(StringFormat::Fmt("x%zu[%u]", i, t), 0l, 0l, 0l, 0l);
}
}
}
@@ -608,13 +608,15 @@ void Program::MakeDisassemblyString()
prevLineInfo = lineInfo;
}
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "% 4u", i);
m_Disassembly += buf;
m_Disassembly += ": ";
for(int in = 0; in < indent - (m_Instructions[i].operation == OPCODE_ELSE ? 1 : 0); in++)
m_Disassembly += " ";
m_Disassembly += m_Instructions[i].str + "\n";
int curIndent = indent;
if(m_Instructions[i].operation == OPCODE_ELSE)
curIndent--;
rdcstr whitespace;
whitespace.fill(curIndent * 2, ' ');
m_Disassembly +=
StringFormat::Fmt("% 4u: %s%s\n", i, whitespace.c_str(), m_Instructions[i].str.c_str());
if(m_Instructions[i].operation == OPCODE_IF || m_Instructions[i].operation == OPCODE_LOOP)
{
@@ -750,24 +752,18 @@ bool Program::ExtractOperand(uint32_t *&tokenStream, ToString flags, Operand &re
RDCASSERT(ret);
}
if(retOper.indices[idx].relative)
retOper.indices[idx].str =
"[" + retOper.indices[idx].operand.toString(m_Reflection, flags | ToString::ShowSwizzle) +
" + ";
if(retOper.indices[idx].absolute)
{
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%llu", retOper.indices[idx].index);
retOper.indices[idx].str += buf;
}
else if(retOper.indices[idx].relative)
retOper.indices[idx].str += "0";
if(retOper.indices[idx].relative)
retOper.indices[idx].str += "]";
RDCASSERT(retOper.indices[idx].relative || retOper.indices[idx].absolute);
if(retOper.indices[idx].relative)
{
retOper.indices[idx].str = StringFormat::Fmt(
"[%s + 0]",
retOper.indices[idx].operand.toString(m_Reflection, flags | ToString::ShowSwizzle).c_str());
}
else
{
retOper.indices[idx].str = ToStr(retOper.indices[idx].index);
}
}
if(retOper.type == TYPE_RESOURCE || retOper.type == TYPE_SAMPLER ||
@@ -847,16 +843,9 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con
}
else if(type == TYPE_INTERFACE)
{
str = "fp";
RDCASSERT(indices.size() == 2);
str += indices[0].str;
str += "[" + indices[1].str + "]";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "[%u]", funcNum);
str += buf;
str = StringFormat::Fmt("fp%s[%s][%u]", indices[0].str.c_str(), indices[1].str.c_str(), funcNum);
}
else if(type == TYPE_RESOURCE || type == TYPE_SAMPLER || type == TYPE_UNORDERED_ACCESS_VIEW)
{
@@ -1195,9 +1184,7 @@ rdcstr Operand::toString(const DXBC::Reflection *reflection, ToString flags) con
else if(type == TYPE_IMMEDIATE64)
{
double *dv = (double *)values;
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "d(%lfl, %lfl)", dv[0], dv[1]);
str += buf;
str += StringFormat::Fmt("d(%lfl, %lfl)", dv[0], dv[1]);
}
else if(type == TYPE_RASTERIZER)
str = "rasterizer";
@@ -1503,20 +1490,14 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
}
else if(op == OPCODE_DCL_TEMPS)
{
retDecl.str += " ";
retDecl.numTemps = tokenStream[0];
tokenStream++;
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.numTemps);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" %u", retDecl.numTemps);
}
else if(op == OPCODE_DCL_INDEXABLE_TEMP)
{
retDecl.str += " ";
retDecl.tempReg = tokenStream[0];
tokenStream++;
@@ -1526,10 +1507,8 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
retDecl.tempComponentCount = tokenStream[0];
tokenStream++;
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "x%u[%u], %u", retDecl.tempReg, retDecl.numTemps,
retDecl.tempComponentCount);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" x%u[%u], %u", retDecl.tempReg, retDecl.numTemps,
retDecl.tempComponentCount);
}
else if(op == OPCODE_DCL_OUTPUT)
{
@@ -1548,9 +1527,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
tokenStream++;
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.maxOut);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" %u", retDecl.maxOut);
}
else if(op == OPCODE_DCL_INPUT_SIV || op == OPCODE_DCL_INPUT_SGV ||
op == OPCODE_DCL_INPUT_PS_SIV || op == OPCODE_DCL_INPUT_PS_SGV ||
@@ -1686,15 +1663,10 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
retDecl.indexRange = tokenStream[0];
tokenStream++;
retDecl.str += " ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.indexRange);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" %u", retDecl.indexRange);
}
else if(op == OPCODE_DCL_THREAD_GROUP)
{
retDecl.str += " ";
retDecl.groupSize[0] = tokenStream[0];
tokenStream++;
@@ -1703,17 +1675,9 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
retDecl.groupSize[2] = tokenStream[0];
tokenStream++;
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[0]);
retDecl.str += buf;
retDecl.str += ", ";
StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[1]);
retDecl.str += buf;
retDecl.str += ", ";
StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[2]);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" %u, %u, %u", retDecl.groupSize[0], retDecl.groupSize[1],
retDecl.groupSize[2]);
}
else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW)
{
@@ -1726,11 +1690,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
tokenStream++;
retDecl.str += retDecl.operand.toString(m_Reflection, flags);
retDecl.str += ", ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.count);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(", %u", retDecl.count);
}
else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED)
{
@@ -1746,25 +1706,13 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
tokenStream++;
retDecl.str += retDecl.operand.toString(m_Reflection, flags);
retDecl.str += ", ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.stride);
retDecl.str += buf;
retDecl.str += ", ";
StringFormat::snprintf(buf, 63, "%u", retDecl.count);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(", %u, %u", retDecl.stride, retDecl.count);
}
else if(op == OPCODE_DCL_INPUT_CONTROL_POINT_COUNT || op == OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT)
{
retDecl.str += " ";
retDecl.controlPointCount = Decl::ControlPointCount.Get(OpcodeToken0);
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.controlPointCount);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" %u", retDecl.controlPointCount);
}
else if(op == OPCODE_DCL_TESS_DOMAIN)
{
@@ -1814,11 +1762,8 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
else if(retDecl.inPrim >= PRIMITIVE_1_CONTROL_POINT_PATCH &&
retDecl.inPrim <= PRIMITIVE_32_CONTROL_POINT_PATCH)
{
retDecl.str += "control_point_patch_";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u",
1 + int(retDecl.inPrim - PRIMITIVE_1_CONTROL_POINT_PATCH));
retDecl.str += buf;
retDecl.str += StringFormat::Fmt("control_point_patch_%u",
1 + int(retDecl.inPrim - PRIMITIVE_1_CONTROL_POINT_PATCH));
}
else
RDCERR("Unexpected primitive type");
@@ -1921,11 +1866,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
tokenStream++;
retDecl.str += retDecl.operand.toString(m_Reflection, flags);
retDecl.str += ", ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.stride);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(", %u", retDecl.stride);
if(retDecl.hasCounter)
retDecl.str += ", hasOrderPreservingCounter";
@@ -2016,11 +1957,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
retDecl.instanceCount = tokenStream[0];
tokenStream++;
retDecl.str += " ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.instanceCount);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" %u", retDecl.instanceCount);
}
else if(op == OPCODE_DCL_HS_MAX_TESSFACTOR)
{
@@ -2028,33 +1965,21 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
retDecl.maxTessFactor = *f;
tokenStream++;
retDecl.str += " ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "l(%f)", retDecl.maxTessFactor);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" l(%f)", retDecl.maxTessFactor);
}
else if(op == OPCODE_DCL_FUNCTION_BODY)
{
retDecl.functionBody = tokenStream[0];
tokenStream++;
retDecl.str += " ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "fb%u", retDecl.functionBody);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" fb%u", retDecl.functionBody);
}
else if(op == OPCODE_DCL_FUNCTION_TABLE)
{
retDecl.functionTable = tokenStream[0];
tokenStream++;
retDecl.str += " ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "ft%u", retDecl.functionTable);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" ft%u", retDecl.functionTable);
uint32_t TableLength = tokenStream[0];
tokenStream++;
@@ -2063,8 +1988,7 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
for(uint32_t i = 0; i < TableLength; i++)
{
StringFormat::snprintf(buf, 63, "fb%u", tokenStream[0]);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt("fb%u", tokenStream[0]);
if(i + 1 < TableLength)
retDecl.str += ", ";
@@ -2089,19 +2013,14 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
retDecl.numInterfaces = Decl::NumInterfaces.Get(CountToken);
uint32_t TableLength = Decl::TableLength.Get(CountToken);
retDecl.str += " ";
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "fp%u[%u][%u]", retDecl.interfaceID, retDecl.numInterfaces,
retDecl.numTypes);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt(" fp%u[%u][%u]", retDecl.interfaceID, retDecl.numInterfaces,
retDecl.numTypes);
retDecl.str += " = {";
for(uint32_t i = 0; i < TableLength; i++)
{
StringFormat::snprintf(buf, 63, "ft%u", tokenStream[0]);
retDecl.str += buf;
retDecl.str += StringFormat::Fmt("ft%u", tokenStream[0]);
if(i + 1 < TableLength)
retDecl.str += ", ";
@@ -2113,7 +2032,8 @@ bool Program::ExtractDecl(uint32_t *&tokenStream, Declaration &retDecl, bool fri
retDecl.str += "}";
}
else if(op == OPCODE_HS_DECLS)
;
{
}
else
{
RDCERR("Unexpected opcode decl %d", op);
@@ -2232,10 +2152,8 @@ bool Program::ExtractOperation(uint32_t *&tokenStream, Operation &retOp, bool fr
if(retOp.texelOffset[2] > 7)
retOp.texelOffset[2] -= 16;
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "(%d,%d,%d)", retOp.texelOffset[0], retOp.texelOffset[1],
retOp.texelOffset[2]);
retOp.str += buf;
retOp.str += StringFormat::Fmt("(%d,%d,%d)", retOp.texelOffset[0], retOp.texelOffset[1],
retOp.texelOffset[2]);
}
else if(type == EXTENDED_OPCODE_RESOURCE_DIM)
{
@@ -2243,16 +2161,10 @@ bool Program::ExtractOperation(uint32_t *&tokenStream, Operation &retOp, bool fr
if(op == OPCODE_LD_STRUCTURED)
{
retOp.str += "_indexable(";
retOp.str += toString(retOp.resDim);
retOp.stride = ExtendedOpcode::BufferStride.Get(OpcodeTokenN);
char buf[64] = {0};
StringFormat::snprintf(buf, 63, ", stride=%u", retOp.stride);
retOp.str += buf;
retOp.str += ")";
retOp.str +=
StringFormat::Fmt("_indexable(%s, stride=%u)", toString(retOp.resDim), retOp.stride);
}
else
{
@@ -2646,20 +2558,18 @@ rdcstr toString(const uint32_t values[], uint32_t numComps)
float *vf = (float *)&values[i];
int32_t *vi = (int32_t *)&values[i];
char buf[64] = {0};
if(!floatOutput)
if(floatOutput)
{
str += ToStr(vf[0]);
}
else
{
// print small ints straight up, otherwise as hex
if(vi[0] <= 10000 && vi[0] >= -10000)
StringFormat::snprintf(buf, 63, "%d", vi[0]);
str += ToStr(vi[0]);
else
StringFormat::snprintf(buf, 63, "0x%08x", vi[0]);
str += StringFormat::Fmt("0x%08x", vi[0]);
}
else
StringFormat::snprintf(buf, 63, "%f", vf[0]);
str += buf;
if(i + 1 < numComps)
str += ", ";
+11 -23
View File
@@ -25,6 +25,7 @@
#include "vk_rendertext.h"
#include "3rdparty/stb/stb_truetype.h"
#include "maths/matrix.h"
#include "strings/string_utils.h"
#include "vk_shader_cache.h"
#define VULKAN 1
@@ -597,32 +598,19 @@ void VulkanTextRenderer::BeginText(const TextPrintState &textstate)
}
void VulkanTextRenderer::RenderText(const TextPrintState &textstate, float x, float y,
const char *textfmt, ...)
const rdcstr &text)
{
static char tmpBuf[4096];
rdcarray<rdcstr> lines;
split(text, lines, '\n');
va_list args;
va_start(args, textfmt);
StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args);
tmpBuf[4095] = '\0';
va_end(args);
RenderTextInternal(textstate, x, y, tmpBuf);
for(const rdcstr &line : lines)
RenderTextInternal(textstate, x, y, line);
}
void VulkanTextRenderer::RenderTextInternal(const TextPrintState &textstate, float x, float y,
const char *text)
const rdcstr &text)
{
if(char *t = strchr((char *)text, '\n'))
{
*t = 0;
RenderTextInternal(textstate, x, y, text);
RenderTextInternal(textstate, x, y + 1.0f, t + 1);
*t = '\n';
return;
}
if(strlen(text) == 0)
if(text.empty())
return;
uint32_t offsets[2] = {0};
@@ -643,14 +631,14 @@ void VulkanTextRenderer::RenderTextInternal(const TextPrintState &textstate, flo
m_TextGeneralUBO.Unmap();
size_t len = strlen(text);
size_t len = text.size();
RDCASSERT(len <= MAX_SINGLE_LINE_LENGTH);
// only map enough for our string
StringUBOData *stringData = (StringUBOData *)m_TextStringUBO.Map(&offsets[1], len * sizeof(Vec4u));
for(size_t i = 0; i < strlen(text); i++)
for(size_t i = 0; i < len; i++)
stringData->chars[i].x = uint32_t(text[i] - ' ');
m_TextStringUBO.Unmap();
@@ -659,7 +647,7 @@ void VulkanTextRenderer::RenderTextInternal(const TextPrintState &textstate, flo
->CmdBindDescriptorSets(Unwrap(textstate.cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
Unwrap(m_TextPipeLayout), 0, 1, UnwrapPtr(m_TextDescSet), 2, offsets);
ObjDisp(textstate.cmd)->CmdDraw(Unwrap(textstate.cmd), 6 * (uint32_t)strlen(text), 1, 0, 0);
ObjDisp(textstate.cmd)->CmdDraw(Unwrap(textstate.cmd), 6 * (uint32_t)len, 1, 0, 0);
}
void VulkanTextRenderer::EndText(const TextPrintState &textstate)
+2 -2
View File
@@ -44,11 +44,11 @@ public:
~VulkanTextRenderer();
void BeginText(const TextPrintState &textstate);
void RenderText(const TextPrintState &textstate, float x, float y, const char *fmt, ...);
void RenderText(const TextPrintState &textstate, float x, float y, const rdcstr &text);
void EndText(const TextPrintState &textstate);
private:
void RenderTextInternal(const TextPrintState &textstate, float x, float y, const char *text);
void RenderTextInternal(const TextPrintState &textstate, float x, float y, const rdcstr &text);
static const uint32_t FONT_TEX_WIDTH = 256;
static const uint32_t FONT_TEX_HEIGHT = 128;
@@ -25,7 +25,7 @@
#include "../vk_core.h"
#include "api/replay/version.h"
static char fakeRenderDocUUID[VK_UUID_SIZE + 1] = {};
static char fakeRenderDocUUID[VK_UUID_SIZE] = {};
void MakeFakeUUID()
{
@@ -37,7 +37,9 @@ void MakeFakeUUID()
// rdocyymmddHHMMSS
// we pass size+1 so that there's room for a null terminator (the UUID doesn't
// need a null terminator as it's a fixed size non-string array)
StringFormat::sntimef(fakeRenderDocUUID, VK_UUID_SIZE + 1, "rdoc%y%m%d%H%M%S");
rdcstr uuid = StringFormat::sntimef(Timing::GetUTCTime(), "rdoc%y%m%d%H%M%S");
RDCASSERT(uuid.size() == sizeof(fakeRenderDocUUID));
memcpy(fakeRenderDocUUID, uuid.c_str(), RDCMIN(VK_UUID_SIZE, uuid.count()));
}
}
@@ -832,15 +832,17 @@ VkResult WrappedVulkan::vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR
SubmitAndFlushExtQueue(swapQueueIndex);
}
m_TextRenderer->BeginText(textstate);
int flags = activeWindow ? RenderDoc::eOverlay_ActiveWindow : 0;
rdcstr overlayText = RenderDoc::Inst().GetOverlayText(RDCDriver::Vulkan, m_FrameCounter, flags);
if(!overlayText.empty())
m_TextRenderer->RenderText(textstate, 0.0f, 0.0f, overlayText.c_str());
{
m_TextRenderer->BeginText(textstate);
m_TextRenderer->EndText(textstate);
m_TextRenderer->RenderText(textstate, 0.0f, 0.0f, overlayText);
m_TextRenderer->EndText(textstate);
}
std::swap(bbBarrier.srcQueueFamilyIndex, bbBarrier.dstQueueFamilyIndex);
std::swap(bbBarrier.oldLayout, bbBarrier.newLayout);
+5 -29
View File
@@ -27,32 +27,10 @@
#include "api/replay/control_types.h"
#include "strings/string_utils.h"
int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args);
int utf8printv(char *buf, size_t bufsize, const char *fmt, va_list args);
namespace StringFormat
{
int snprintf(char *str, size_t bufSize, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = StringFormat::vsnprintf(str, bufSize, fmt, args);
va_end(args);
return ret;
}
void sntimef(char *str, size_t bufSize, const char *format)
{
StringFormat::sntimef(Timing::GetUTCTime(), str, bufSize, format);
}
int vsnprintf(char *str, size_t bufSize, const char *format, va_list args)
{
return ::utf8printf(str, bufSize, format, args);
}
rdcstr Fmt(const char *format, ...)
{
va_list args;
@@ -61,11 +39,11 @@ rdcstr Fmt(const char *format, ...)
va_list args2;
va_copy(args2, args);
int size = StringFormat::vsnprintf(NULL, 0, format, args2);
int size = ::utf8printv(NULL, 0, format, args2);
rdcstr ret;
ret.resize(size);
StringFormat::vsnprintf(ret.data(), size + 1, format, args);
::utf8printv(ret.data(), size + 1, format, args);
va_end(args);
va_end(args2);
@@ -93,11 +71,9 @@ rdcstr Callstack::AddressDetails::formattedString(const char *commonPath)
}
if(line > 0)
StringFormat::snprintf(fmt, 511, "%s line %d", function.c_str(), line);
return StringFormat::Fmt("%s line %d", function.c_str(), line);
else
StringFormat::snprintf(fmt, 511, "%s", function.c_str());
return fmt;
return function;
}
rdcstr OSUtility::MakeMachineIdentString(uint64_t ident)
+1 -11
View File
@@ -434,7 +434,7 @@ struct rdcwstr : private rdcarray<wchar_t>
// implemented per-platform
namespace StringFormat
{
void sntimef(time_t utcTime, char *str, size_t bufSize, const char *format);
rdcstr sntimef(time_t utcTime, const char *format);
rdcstr Wide2UTF8(const rdcwstr &str);
rdcwstr UTF82Wide(const rdcstr &s);
@@ -442,16 +442,6 @@ rdcwstr UTF82Wide(const rdcstr &s);
void Shutdown();
};
// utility functions, implemented in os_specific.cpp, not per-platform (assuming standard stdarg.h)
// forwarded to custom printf implementation in utf8printf.cpp
namespace StringFormat
{
int vsnprintf(char *str, size_t bufSize, const char *format, va_list v);
int snprintf(char *str, size_t bufSize, const char *format, ...);
void sntimef(char *str, size_t bufSize, const char *format);
};
namespace OSUtility
{
inline void ForceCrash();
@@ -26,6 +26,7 @@
#include <fcntl.h>
#include <unistd.h>
#include "common/common.h"
#include "common/formatting.h"
#include "os/os_specific.h"
#define LOGCAT_TAG "renderdoc"
@@ -77,13 +78,11 @@ rdcstr GetAppFolderFilename(const rdcstr &filename)
// For other APKs, we use it to get the writable temp directory.
void GetExecutableFilename(rdcstr &selfName)
{
char buf[4096];
snprintf(buf, sizeof(buf), "/proc/%u/cmdline", getpid());
int fd = open(buf, O_RDONLY);
int fd = open(StringFormat::Fmt("/proc/%u/cmdline", getpid()).c_str(), O_RDONLY);
if(fd < 0)
{
return;
}
char buf[4096];
ssize_t len = read(fd, buf, sizeof(buf));
close(fd);
if(len < 0 || len == sizeof(buf))
+7 -11
View File
@@ -388,9 +388,6 @@ Socket *CreateTCPServerSocket(const char *bindaddr, uint16_t port, int queuesize
Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
{
char socketName[17] = {0};
StringFormat::snprintf(socketName, 16, "renderdoc_%d", port);
int socketNameLength = strlen(socketName);
int s = socket(AF_UNIX, SOCK_STREAM, 0);
if(s == -1)
@@ -399,18 +396,20 @@ Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
return NULL;
}
rdcstr socketName = StringFormat::Fmt("renderdoc_%d", port);
sockaddr_un addr;
RDCEraseEl(addr);
addr.sun_family = AF_UNIX;
// first char is '\0'
addr.sun_path[0] = '\0';
strncpy(addr.sun_path + 1, socketName, socketNameLength + 1);
strncpy(addr.sun_path + 1, socketName.c_str(), socketName.size() + 1);
int result = bind(s, (sockaddr *)&addr, offsetof(sockaddr_un, sun_path) + 1 + socketNameLength);
int result = bind(s, (sockaddr *)&addr, socketName.size());
if(result == -1)
{
RDCWARN("Failed to create abstract socket: %s", socketName);
RDCWARN("Failed to create abstract socket: %s", socketName.c_str());
close(s);
return NULL;
}
@@ -419,7 +418,7 @@ Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
result = listen(s, queuesize);
if(result == -1)
{
RDCWARN("Failed to listen on %s", socketName);
RDCWARN("Failed to listen on %s", socketName.c_str());
close(s);
return NULL;
}
@@ -432,9 +431,6 @@ Socket *CreateAbstractServerSocket(uint16_t port, int queuesize)
Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS)
{
char portstr[7] = {0};
StringFormat::snprintf(portstr, 6, "%d", port);
addrinfo hints;
RDCEraseEl(hints);
hints.ai_family = AF_INET;
@@ -442,7 +438,7 @@ Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS)
hints.ai_protocol = IPPROTO_TCP;
addrinfo *addrResult = NULL;
int res = getaddrinfo(host, portstr, &hints, &addrResult);
int res = getaddrinfo(host, ToStr(port).c_str(), &hints, &addrResult);
if(res != 0)
{
RDCDEBUG("%s", gai_strerror(res));
+38 -14
View File
@@ -38,6 +38,7 @@
#include <unistd.h>
#include "api/app/renderdoc_app.h"
#include "api/replay/data_types.h"
#include "common/formatting.h"
#include "common/threading.h"
#include "os/os_specific.h"
#include "strings/string_utils.h"
@@ -221,24 +222,18 @@ void GetDefaultFiles(const char *logBaseName, rdcstr &capture_filename, rdcstr &
temp_folder[--len] = 0;
}
char temp_filename[2048 + 128] = {0};
snprintf(temp_filename, sizeof(temp_filename) - 1, "%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.rdc",
temp_folder, mod, 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour,
now.tm_min);
capture_filename = rdcstr(temp_filename);
snprintf(temp_filename, sizeof(temp_filename) - 1,
"%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.%02d.log", temp_folder, logBaseName,
1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
capture_filename =
StringFormat::Fmt("%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.rdc", temp_folder, mod,
1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min);
// set by UI when launching programs so all logging goes to the same file
char *logfile_override = getenv("RENDERDOC_DEBUG_LOG_FILE");
if(logfile_override)
logging_filename = rdcstr(logfile_override);
else
logging_filename = rdcstr(temp_filename);
logging_filename = StringFormat::Fmt(
"%s/RenderDoc/%s_%04d.%02d.%02d_%02d.%02d.%02d.log", temp_folder, logBaseName,
1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
}
uint64_t GetModifiedTimestamp(const rdcstr &filename)
@@ -568,10 +563,39 @@ void logfile_close(LogFileHandle *logHandle, const char *deleteFilename)
namespace StringFormat
{
void sntimef(time_t utcTime, char *str, size_t bufSize, const char *format)
rdcstr sntimef(time_t utcTime, const char *format)
{
tm *tmv = localtime(&utcTime);
strftime(str, bufSize, format, tmv);
// conservatively assume that most formatters will replace like-for-like (e.g. %H with 12) and
// a few will increase (%Y to 2019) but generally the string will stay the same size.
size_t len = strlen(format) + 16;
size_t ret = 0;
char *buf = NULL;
// loop until we have successfully formatted
while(ret == 0)
{
// delete any previous buffer
delete[] buf;
// alloate new one of the new size
buf = new char[len + 1];
buf[len] = 0;
// try formatting
ret = strftime(buf, len, format, tmv);
// double the length for next time, if this failed
len *= 2;
}
rdcstr str = buf;
// delete successful buffer
delete[] buf;
return str;
}
};
+2 -3
View File
@@ -397,9 +397,8 @@ Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS)
wchar_t portwstr[7] = {0};
{
char buf[7] = {0};
int n = StringFormat::snprintf(buf, 6, "%d", port);
for(int i = 0; i < n && i < 6; i++)
rdcstr buf = ToStr(port);
for(size_t i = 0; i < buf.size(); i++)
portwstr[i] = (wchar_t)buf[i];
}
+29 -10
View File
@@ -745,26 +745,45 @@ void logfile_close(LogFileHandle *logHandle, const char *deleteFilename)
namespace StringFormat
{
void sntimef(time_t utcTime, char *str, size_t bufSize, const char *format)
rdcstr sntimef(time_t utcTime, const char *format)
{
tm tmv;
localtime_s(&tmv, &utcTime);
wchar_t *buf = new wchar_t[bufSize + 1];
buf[bufSize] = 0;
rdcstr result;
rdcwstr wfmt = StringFormat::UTF82Wide(format);
wcsftime(buf, bufSize, wfmt.c_str(), &tmv);
// conservatively assume that most formatters will replace like-for-like (e.g. %H with 12) and
// a few will increase (%Y to 2019) but generally the string will stay the same size.
size_t len = strlen(format) + 16;
rdcstr result = StringFormat::Wide2UTF8(buf);
size_t ret = 0;
wchar_t *buf = NULL;
// loop until we have successfully formatted
while(ret == 0)
{
// delete any previous buffer
delete[] buf;
// alloate new one of the new size
buf = new wchar_t[len + 1];
buf[len] = 0;
// try formatting
ret = wcsftime(buf, len, wfmt.c_str(), &tmv);
// double the length for next time, if this failed
len *= 2;
}
rdcstr str = StringFormat::Wide2UTF8(buf);
// delete successful buffer
delete[] buf;
if(result.length() + 1 <= bufSize)
{
memcpy(str, result.c_str(), result.length());
str[result.length()] = 0;
}
return str;
}
void Shutdown()
+2 -3
View File
@@ -304,9 +304,8 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_CreateBugReport(const char
if(report.empty())
{
char filename[128] = {};
StringFormat::sntimef(filename, 127, "/renderdoc_report_%H%M%S.zip");
report = FileIO::GetTempFolderFilename() + filename;
report = FileIO::GetTempFolderFilename() +
StringFormat::sntimef(Timing::GetUTCTime(), "/renderdoc_report_%H%M%S.zip");
}
FileIO::Delete(report.c_str());
+16
View File
@@ -1368,6 +1368,11 @@ rdcstr DoStringise(const TestBitfield &el)
END_BITFIELD_STRINGISE();
}
void test(const char *aasd)
{
RDCLOG("got a test of %s", aasd);
}
TEST_CASE("Test stringification works as expected", "[tostr]")
{
SECTION("Enum classes")
@@ -1391,6 +1396,17 @@ TEST_CASE("Test stringification works as expected", "[tostr]")
CHECK(ToStr(foo) == "TestEnumClass(0)");
};
SECTION("integers")
{
uint16_t a = 54;
uint32_t b = 22;
uint8_t c = 99;
test(ToStr(a).c_str());
test(ToStr(b).c_str());
test(ToStr(c).c_str());
};
SECTION("plain enums")
{
TestEnum foo = TestA;
+14 -14
View File
@@ -1180,7 +1180,7 @@ void formatargument(char type, void *rawarg, FormatterParams formatter, char *&o
}
}
int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args)
int utf8printv(char *buf, size_t bufsize, const char *fmt, va_list args)
{
// format, buffer and string arguments are assumed to be UTF-8 (except wide strings).
// note that since the format specifiers are entirely ascii, we can byte-copy safely and handle
@@ -1452,23 +1452,23 @@ int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args)
return int(actualsize);
}
#if ENABLED(ENABLE_UNIT_TESTS)
#include "3rdparty/catch/catch.hpp"
#include "common/formatting.h"
int utf8printf_wrapper(char *buf, size_t bufsize, const char *fmt, ...)
int utf8printf(char *str, size_t bufSize, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = utf8printf(buf, bufsize, fmt, args);
int ret = utf8printv(str, bufSize, fmt, args);
va_end(args);
return ret;
}
#if ENABLED(ENABLE_UNIT_TESTS)
#include "3rdparty/catch/catch.hpp"
#include "common/formatting.h"
TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
{
int fourtytwo = 42;
@@ -1477,7 +1477,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
SECTION("NULL input buffer")
{
int a = utf8printf_wrapper(NULL, 0, "%d %c", fourtytwo, x);
int a = utf8printf(NULL, 0, "%d %c", fourtytwo, x);
int b = snprintf(NULL, 0, "%d %c", fourtytwo, x);
CHECK(a == 4);
@@ -1490,7 +1490,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
char bufa[] = {0, 0, 0, 0, 0, 0};
char bufb[] = {0, 0, 0, 0, 0, 0};
int a = utf8printf_wrapper(bufa, sizeof(bufa), "%d foo", largenum);
int a = utf8printf(bufa, sizeof(bufa), "%d foo", largenum);
int b = snprintf(bufb, sizeof(bufb), "%d foo", largenum);
RDCCOMPILE_ASSERT(sizeof(bufa) == 6, "bufa is mis-sized for test");
@@ -1513,7 +1513,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
SECTION("contains NULL terminator")
{
memset(bufa, 'a', sizeof(bufa));
a = utf8printf_wrapper(bufa, sizeof(bufa), "%d foo", largenum);
a = utf8printf(bufa, sizeof(bufa), "%d foo", largenum);
INFO("bufa is '" << rdcstr(bufa) << "'");
CHECK(memcmp(bufa, ref, sizeof(ref)) == 0);
}
@@ -1527,7 +1527,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
memset(bufa, 'a', sizeof(bufa));
memset(bufb, 'b', sizeof(bufb));
int a = utf8printf_wrapper(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
int a = utf8printf(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
int b = snprintf(bufb, sizeof(bufb), "foobar %c %d", x, fourtytwo);
CHECK(a == sizeof(bufa) - 1);
@@ -1556,7 +1556,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
memset(bufa, 'a', sizeof(bufa));
memset(bufb, 'b', sizeof(bufb));
int a = utf8printf_wrapper(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
int a = utf8printf(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
int b = snprintf(bufb, sizeof(bufb), "foobar %c %d", x, fourtytwo);
CHECK(a == sizeof(bufa));
@@ -1585,7 +1585,7 @@ TEST_CASE("utf8printf buffer sizing", "[utf8printf]")
memset(bufa, 'a', sizeof(bufa));
memset(bufb, 'b', sizeof(bufb));
int a = utf8printf_wrapper(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
int a = utf8printf(bufa, sizeof(bufa), "foobar %c %d", x, fourtytwo);
int b = snprintf(bufb, sizeof(bufb), "foobar %c %d", x, fourtytwo);
CHECK(a == 11);