shaderc: Added in/out hash. Fixed shader binary backward compatibility.

This commit is contained in:
Branimir Karadžić
2018-10-12 16:41:26 -07:00
parent 1ba107d156
commit 623fd3cf0b
10 changed files with 220 additions and 115 deletions

View File

@@ -1392,6 +1392,26 @@ namespace bgfx
return s_topologyName[bx::min(_topology, Topology::PointList)];
}
const char* getShaderTypeName(uint32_t _magic)
{
if (isShaderType(_magic, 'C') )
{
return "Compute";
}
else if (isShaderType(_magic, 'F') )
{
return "Fragment";
}
else if (isShaderType(_magic, 'V') )
{
return "Vertex";
}
BX_CHECK(false, "Invalid shader type!");
return NULL;
}
static TextureFormat::Enum s_emulatedFormats[] =
{
TextureFormat::BC1,

View File

@@ -132,15 +132,11 @@ namespace bgfx
#define BGFX_CHUNK_MAGIC_TEX BX_MAKEFOURCC('T', 'E', 'X', 0x0)
#define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', 0x3)
#define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', 0x5)
#define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', 0x5)
#define BGFX_CLEAR_COLOR_USE_PALETTE UINT16_C(0x8000)
#define BGFX_CLEAR_MASK (0 \
| BGFX_CLEAR_COLOR \
| BGFX_CLEAR_DEPTH \
| BGFX_CLEAR_STENCIL \
#define BGFX_CLEAR_MASK (0 \
| BGFX_CLEAR_COLOR \
| BGFX_CLEAR_DEPTH \
| BGFX_CLEAR_STENCIL \
| BGFX_CLEAR_COLOR_USE_PALETTE \
)
@@ -319,6 +315,25 @@ namespace bgfx
bool windowsVersionIs(Condition::Enum _op, uint32_t _version);
constexpr bool isShaderType(uint32_t _magic, char _type)
{
return uint32_t(_type) == (_magic & BX_MAKEFOURCC(0xff, 0, 0, 0) );
}
inline bool isShaderBin(uint32_t _magic)
{
return BX_MAKEFOURCC(0, 'S', 'H', 0) == (_magic & BX_MAKEFOURCC(0, 0xff, 0xff, 0) )
&& (isShaderType(_magic, 'C') || isShaderType(_magic, 'F') || isShaderType(_magic, 'V') )
;
}
inline bool isShaderVerLess(uint32_t _magic, uint8_t _version)
{
return (_magic & BX_MAKEFOURCC(0, 0, 0, 0xff) ) < BX_MAKEFOURCC(0, 0, 0, _version);
}
const char* getShaderTypeName(uint32_t _magic);
struct Clear
{
void set(uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
@@ -3526,11 +3541,9 @@ namespace bgfx
return BGFX_INVALID_HANDLE;
}
if (BGFX_CHUNK_MAGIC_CSH != magic
&& BGFX_CHUNK_MAGIC_FSH != magic
&& BGFX_CHUNK_MAGIC_VSH != magic)
if (!isShaderBin(magic) )
{
BX_WARN(false, "Invalid shader signature! %c%c%c%d."
BX_TRACE("Invalid shader signature! %c%c%c%d."
, ( (uint8_t*)&magic)[0]
, ( (uint8_t*)&magic)[1]
, ( (uint8_t*)&magic)[2]
@@ -3540,6 +3553,23 @@ namespace bgfx
return BGFX_INVALID_HANDLE;
}
if (isShaderType(magic, 'C')
&& 0 == (g_caps.supported & BGFX_CAPS_COMPUTE) )
{
BX_TRACE("Creating compute shader but compute is not supported!");
release(_mem);
return BGFX_INVALID_HANDLE;
}
if ( (isShaderType(magic, 'C') && isShaderVerLess(magic, 3) )
|| (isShaderType(magic, 'F') && isShaderVerLess(magic, 5) )
|| (isShaderType(magic, 'V') && isShaderVerLess(magic, 5) ) )
{
BX_TRACE("Unsupported shader binary version.");
release(_mem);
return BGFX_INVALID_HANDLE;
}
const uint32_t shaderHash = bx::hash<bx::HashMurmur2A>(_mem->data, _mem->size);
const uint16_t idx = m_shaderHashMap.find(shaderHash);
if (kInvalidHandle != idx)
@@ -3550,8 +3580,19 @@ namespace bgfx
return handle;
}
uint32_t iohash;
bx::read(&reader, iohash, &err);
uint32_t hashIn;
bx::read(&reader, hashIn, &err);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
hashOut = hashIn;
}
else
{
bx::read(&reader, hashOut, &err);
}
uint16_t count;
bx::read(&reader, count, &err);
@@ -3577,7 +3618,8 @@ namespace bgfx
ShaderRef& sr = m_shaderRef[handle.idx];
sr.m_refCount = 1;
sr.m_hash = iohash;
sr.m_hashIn = hashIn;
sr.m_hashOut = hashOut;
sr.m_num = 0;
sr.m_uniforms = NULL;
@@ -3745,7 +3787,7 @@ namespace bgfx
{
const ShaderRef& vsr = m_shaderRef[_vsh.idx];
const ShaderRef& fsr = m_shaderRef[_fsh.idx];
if (vsr.m_hash != fsr.m_hash)
if (vsr.m_hashOut != fsr.m_hashIn)
{
BX_TRACE("Vertex shader output doesn't match fragment shader input.");
return BGFX_INVALID_HANDLE;
@@ -4682,7 +4724,8 @@ namespace bgfx
{
UniformHandle* m_uniforms;
String m_name;
uint32_t m_hash;
uint32_t m_hashIn;
uint32_t m_hashOut;
int16_t m_refCount;
uint16_t m_num;
};

View File

@@ -3841,22 +3841,21 @@ namespace bgfx { namespace d3d11
uint32_t magic;
bx::read(&reader, magic);
switch (magic)
const bool fragment = isShaderType(magic, 'F');
uint32_t hashIn;
bx::read(&reader, hashIn);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
case BGFX_CHUNK_MAGIC_CSH:
case BGFX_CHUNK_MAGIC_FSH:
case BGFX_CHUNK_MAGIC_VSH:
break;
default:
BGFX_FATAL(false, Fatal::InvalidShader, "Unknown shader format %x.", magic);
break;
hashOut = hashIn;
}
else
{
bx::read(&reader, hashOut);
}
bool fragment = BGFX_CHUNK_MAGIC_FSH == magic;
uint32_t iohash;
bx::read(&reader, iohash);
uint16_t count;
bx::read(&reader, count);
@@ -3865,11 +3864,11 @@ namespace bgfx { namespace d3d11
m_numUniforms = count;
BX_TRACE("%s Shader consts %d"
, BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute"
, getShaderTypeName(magic)
, count
);
uint8_t fragmentBit = fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0;
const uint8_t fragmentBit = fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0;
if (0 < count)
{
@@ -3949,13 +3948,13 @@ namespace bgfx { namespace d3d11
const void* code = reader.getDataPtr();
bx::skip(&reader, shaderSize+1);
if (BGFX_CHUNK_MAGIC_FSH == magic)
if (isShaderType(magic, 'F') )
{
m_hasDepthOp = hasDepthOp(code, shaderSize);
DX_CHECK(s_renderD3D11->m_device->CreatePixelShader(code, shaderSize, NULL, &m_pixelShader) );
BGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create fragment shader.");
}
else if (BGFX_CHUNK_MAGIC_VSH == magic)
else if (isShaderType(magic, 'V') )
{
m_hash = bx::hash<bx::HashMurmur2A>(code, shaderSize);
m_code = copy(code, shaderSize);
@@ -3963,7 +3962,7 @@ namespace bgfx { namespace d3d11
DX_CHECK(s_renderD3D11->m_device->CreateVertexShader(code, shaderSize, NULL, &m_vertexShader) );
BGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create vertex shader.");
}
else
else if (isShaderType(magic, 'C') )
{
DX_CHECK(s_renderD3D11->m_device->CreateComputeShader(code, shaderSize, NULL, &m_computeShader) );
BGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create compute shader.");

View File

@@ -4338,22 +4338,21 @@ namespace bgfx { namespace d3d12
uint32_t magic;
bx::read(&reader, magic);
switch (magic)
const bool fragment = isShaderType(magic, 'F');
uint32_t hashIn;
bx::read(&reader, hashIn);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
case BGFX_CHUNK_MAGIC_CSH:
case BGFX_CHUNK_MAGIC_FSH:
case BGFX_CHUNK_MAGIC_VSH:
break;
default:
BGFX_FATAL(false, Fatal::InvalidShader, "Unknown shader format %x.", magic);
break;
hashOut = hashIn;
}
else
{
bx::read(&reader, hashOut);
}
bool fragment = BGFX_CHUNK_MAGIC_FSH == magic;
uint32_t iohash;
bx::read(&reader, iohash);
uint16_t count;
bx::read(&reader, count);
@@ -4362,7 +4361,7 @@ namespace bgfx { namespace d3d12
m_numUniforms = count;
BX_TRACE("%s Shader consts %d"
, BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute"
, getShaderTypeName(magic)
, count
);
@@ -4468,7 +4467,8 @@ namespace bgfx { namespace d3d12
bx::HashMurmur2A murmur;
murmur.begin();
murmur.add(iohash);
murmur.add(hashIn);
murmur.add(hashOut);
murmur.add(code, shaderSize);
murmur.add(numAttrs);
murmur.add(m_attrMask, numAttrs);

View File

@@ -2394,21 +2394,21 @@ namespace bgfx { namespace d3d9
uint32_t magic;
bx::read(&reader, magic);
switch (magic)
const bool fragment = isShaderType(magic, 'F');
uint32_t hashIn;
bx::read(&reader, hashIn);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
case BGFX_CHUNK_MAGIC_FSH:
case BGFX_CHUNK_MAGIC_VSH:
break;
default:
BGFX_FATAL(false, Fatal::InvalidShader, "Unknown shader format %x.", magic);
break;
hashOut = hashIn;
}
else
{
bx::read(&reader, hashOut);
}
bool fragment = BGFX_CHUNK_MAGIC_FSH == magic;
uint32_t iohash;
bx::read(&reader, iohash);
uint16_t count;
bx::read(&reader, count);

View File

@@ -5255,25 +5255,38 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
uint32_t magic;
bx::read(&reader, magic);
switch (magic)
if (isShaderType(magic, 'C') )
{
case BGFX_CHUNK_MAGIC_CSH: m_type = GL_COMPUTE_SHADER; break;
case BGFX_CHUNK_MAGIC_FSH: m_type = GL_FRAGMENT_SHADER; break;
case BGFX_CHUNK_MAGIC_VSH: m_type = GL_VERTEX_SHADER; break;
default:
BGFX_FATAL(false, Fatal::InvalidShader, "Unknown shader format %x.", magic);
break;
m_type = GL_COMPUTE_SHADER;
}
else if (isShaderType(magic, 'F') )
{
m_type = GL_FRAGMENT_SHADER;
}
else if (isShaderType(magic, 'V') )
{
m_type = GL_VERTEX_SHADER;
}
uint32_t iohash;
bx::read(&reader, iohash);
uint32_t hashIn;
bx::read(&reader, hashIn);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
hashOut = hashIn;
}
else
{
bx::read(&reader, hashOut);
}
uint16_t count;
bx::read(&reader, count);
BX_TRACE("%s Shader consts %d"
, BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute"
, getShaderTypeName(magic)
, count
);
@@ -5303,9 +5316,7 @@ BX_TRACE("%d, %d, %d, %s", _array, _srgb, _mipAutogen, getName(_format) );
bx::read(&reader, shaderSize);
m_id = glCreateShader(m_type);
BX_WARN(0 != m_id, "Failed to create %s shader."
, BGFX_CHUNK_MAGIC_FSH == magic ? "fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "vertex" : "compute"
);
BX_WARN(0 != m_id, "Failed to create shader.");
const char* code = (const char*)reader.getDataPtr();

View File

@@ -2352,26 +2352,25 @@ namespace bgfx { namespace mtl
uint32_t magic;
bx::read(&reader, magic);
switch (magic)
uint32_t hashIn;
bx::read(&reader, hashIn);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
case BGFX_CHUNK_MAGIC_CSH:
case BGFX_CHUNK_MAGIC_FSH:
case BGFX_CHUNK_MAGIC_VSH:
break;
default:
BGFX_FATAL(false, Fatal::InvalidShader, "Unknown shader format %x.", magic);
break;
hashOut = hashIn;
}
else
{
bx::read(&reader, hashOut);
}
uint32_t iohash;
bx::read(&reader, iohash);
uint16_t count;
bx::read(&reader, count);
BX_TRACE("%s Shader consts %d"
, BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute"
, getShaderTypeName(magic)
, count
);
@@ -2414,12 +2413,13 @@ namespace bgfx { namespace mtl
BGFX_FATAL(NULL != m_function
, bgfx::Fatal::InvalidShader
, "Failed to create %s shader."
, BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute"
, getShaderTypeName(magic)
);
bx::HashMurmur2A murmur;
murmur.begin();
murmur.add(iohash);
murmur.add(hashIn);
murmur.add(hashOut);
murmur.add(code, shaderSize);
// murmur.add(numAttrs);
// murmur.add(m_attrMask, numAttrs);

View File

@@ -3437,21 +3437,35 @@ VK_DESTROY
VkShaderStageFlagBits shaderStage;
BX_UNUSED(shaderStage);
switch (magic)
{
case BGFX_CHUNK_MAGIC_CSH: shaderStage = VK_SHADER_STAGE_COMPUTE_BIT; break;
case BGFX_CHUNK_MAGIC_FSH: shaderStage = VK_SHADER_STAGE_FRAGMENT_BIT; break;
case BGFX_CHUNK_MAGIC_VSH: shaderStage = VK_SHADER_STAGE_VERTEX_BIT; break;
default:
BGFX_FATAL(false, Fatal::InvalidShader, "Unknown shader format %x.", magic);
break;
if (isShaderType(magic, 'C') )
{
shaderStage = VK_SHADER_STAGE_COMPUTE_BIT;
}
else if (isShaderType(magic, 'F') )
{
shaderStage = VK_SHADER_STAGE_FRAGMENT_BIT;
}
else if (isShaderType(magic, 'V') )
{
shaderStage = VK_SHADER_STAGE_VERTEX_BIT;
}
bool fragment = BGFX_CHUNK_MAGIC_FSH == magic;
const bool fragment = isShaderType(magic, 'F');
uint32_t iohash;
bx::read(&reader, iohash);
uint32_t hashIn;
bx::read(&reader, hashIn);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
hashOut = hashIn;
}
else
{
bx::read(&reader, hashOut);
}
uint16_t count;
bx::read(&reader, count);
@@ -3460,7 +3474,7 @@ VK_DESTROY
m_numUniforms = count;
BX_TRACE("%s Shader consts %d"
, BGFX_CHUNK_MAGIC_FSH == magic ? "Fragment" : BGFX_CHUNK_MAGIC_VSH == magic ? "Vertex" : "Compute"
, getShaderTypeName(magic)
, count
);
@@ -3584,7 +3598,8 @@ VK_DESTROY
bx::HashMurmur2A murmur;
murmur.begin();
murmur.add(iohash);
murmur.add(hashIn);
murmur.add(hashOut);
murmur.add(m_code->data, m_code->size);
murmur.add(m_numAttrs);
murmur.add(m_attrMask, m_numAttrs);

View File

@@ -75,14 +75,23 @@ namespace bgfx
uint32_t magic;
bx::peek(_reader, magic);
if (BGFX_CHUNK_MAGIC_CSH == magic
|| BGFX_CHUNK_MAGIC_FSH == magic
|| BGFX_CHUNK_MAGIC_VSH == magic)
if (isShaderBin(magic) )
{
bx::read(_reader, magic);
uint32_t iohash;
bx::read(_reader, iohash, _err);
uint32_t hashIn;
bx::read(_reader, hashIn);
uint32_t hashOut;
if (isShaderVerLess(magic, 6) )
{
hashOut = hashIn;
}
else
{
bx::read(_reader, hashOut);
}
uint16_t count;
bx::read(_reader, count, _err);

View File

@@ -13,9 +13,10 @@ extern "C"
#include <fpp.h>
} // extern "C"
#define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', 0x3)
#define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', 0x5)
#define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', 0x5)
#define BGFX_SHADER_BIN_VERSION 6
#define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', BGFX_SHADER_BIN_VERSION)
#define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', BGFX_SHADER_BIN_VERSION)
#define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', BGFX_SHADER_BIN_VERSION)
#define BGFX_SHADERC_VERSION_MAJOR 1
#define BGFX_SHADERC_VERSION_MINOR 16
@@ -1206,15 +1207,18 @@ namespace bgfx
{
bx::write(_writer, BGFX_CHUNK_MAGIC_FSH);
bx::write(_writer, inputHash);
bx::write(_writer, uint32_t(0) );
}
else if ('v' == _options.shaderType)
{
bx::write(_writer, BGFX_CHUNK_MAGIC_VSH);
bx::write(_writer, uint32_t(0) );
bx::write(_writer, outputHash);
}
else
{
bx::write(_writer, BGFX_CHUNK_MAGIC_CSH);
bx::write(_writer, uint32_t(0) );
bx::write(_writer, outputHash);
}
@@ -1339,6 +1343,7 @@ namespace bgfx
std::string code;
bx::write(_writer, BGFX_CHUNK_MAGIC_CSH);
bx::write(_writer, uint32_t(0) );
bx::write(_writer, outputHash);
if (0 != glsl
@@ -1829,15 +1834,18 @@ namespace bgfx
{
bx::write(_writer, BGFX_CHUNK_MAGIC_FSH);
bx::write(_writer, inputHash);
bx::write(_writer, uint32_t(0) );
}
else if ('v' == _options.shaderType)
{
bx::write(_writer, BGFX_CHUNK_MAGIC_VSH);
bx::write(_writer, uint32_t(0) );
bx::write(_writer, outputHash);
}
else
{
bx::write(_writer, BGFX_CHUNK_MAGIC_CSH);
bx::write(_writer, uint32_t(0) );
bx::write(_writer, outputHash);
}