Commit 8b695ee3 by Austin Kinross Committed by Jamie Madill

Reduce unnecessary built-in varying usage in D3D renderer

Change-Id: I0c404e77aa3f56ddc5b97a206b06c7907edfb1eb Reviewed-on: https://chromium-review.googlesource.com/259812Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent c8ef69d2
...@@ -598,8 +598,8 @@ struct DynamicHLSL::SemanticInfo ...@@ -598,8 +598,8 @@ struct DynamicHLSL::SemanticInfo
BuiltinInfo glPointSize; BuiltinInfo glPointSize;
}; };
DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool position, bool fragCoord,
bool pointSize, bool pixelShader) const bool pointCoord, bool pointSize, bool pixelShader) const
{ {
SemanticInfo info; SemanticInfo info;
bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4); bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4);
...@@ -620,7 +620,10 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool ...@@ -620,7 +620,10 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool
info.dxPosition.enableSystem("POSITION"); info.dxPosition.enableSystem("POSITION");
} }
info.glPosition.enable(varyingSemantic, reservedRegisterIndex++); if (position)
{
info.glPosition.enable(varyingSemantic, reservedRegisterIndex++);
}
if (fragCoord) if (fragCoord)
{ {
...@@ -654,10 +657,13 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const ...@@ -654,10 +657,13 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
{ {
std::string linkHLSL = "{\n"; std::string linkHLSL = "{\n";
ASSERT(info.dxPosition.enabled && info.glPosition.enabled); ASSERT(info.dxPosition.enabled);
linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n"; linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n";
linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n";
if (info.glPosition.enabled)
{
linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n";
}
if (info.glFragCoord.enabled) if (info.glFragCoord.enabled)
{ {
...@@ -669,13 +675,14 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const ...@@ -669,13 +675,14 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n"; linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n";
} }
linkHLSL += varyingHLSL;
if (info.glPointSize.enabled) if (info.glPointSize.enabled)
{ {
linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n"; linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n";
} }
// Do this after glPointSize, to potentially combine gl_PointCoord and gl_PointSize into the same register.
linkHLSL += varyingHLSL;
linkHLSL += "};\n"; linkHLSL += "};\n";
return linkHLSL; return linkHLSL;
...@@ -684,10 +691,11 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const ...@@ -684,10 +691,11 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
std::vector<LinkedVarying> *linkedVaryings) const std::vector<LinkedVarying> *linkedVaryings) const
{ {
ASSERT(info.glPosition.enabled); if (info.glPosition.enabled)
{
linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic, linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic,
info.glPosition.index, 1)); info.glPosition.index, 1));
}
if (info.glFragCoord.enabled) if (info.glFragCoord.enabled)
{ {
...@@ -763,6 +771,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -763,6 +771,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3); const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3);
const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1); const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1);
// gl_Position only needs to be outputted from the vertex shader if transform feedback is active.
// This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from the vertex shader in this case.
// This saves us 1 output vector.
bool outputPositionFromVS = !(shaderModel >= 4 && mRenderer->getShaderModelSuffix() != "");
int shaderVersion = vertexShader->getShaderVersion(); int shaderVersion = vertexShader->getShaderVersion();
if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors) if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
...@@ -778,9 +791,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -778,9 +791,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
// GeometryShader PointSprite emulation does not require this additional entry because the // GeometryShader PointSprite emulation does not require this additional entry because the
// GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the PS_INPUT of the // GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the PS_INPUT of the
// generated pixel shader. // generated pixel shader.
const SemanticInfo &vertexSemantics = getSemanticInfo(registers, usesFragCoord, // The Geometry Shader point sprite implementation needs gl_PointSize to be in VS_OUTPUT and GS_INPUT.
(useInstancedPointSpriteEmulation && usesPointCoord), // Instanced point sprites doesn't need gl_PointSize in VS_OUTPUT.
usesPointSize, false); const SemanticInfo &vertexSemantics = getSemanticInfo(registers, outputPositionFromVS,
usesFragCoord, (useInstancedPointSpriteEmulation && usesPointCoord),
(!useInstancedPointSpriteEmulation && usesPointSize), false);
storeUserLinkedVaryings(vertexShader, linkedVaryings); storeUserLinkedVaryings(vertexShader, linkedVaryings);
storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings); storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings);
...@@ -809,8 +824,12 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -809,8 +824,12 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
vertexHLSL += "\n" vertexHLSL += "\n"
" gl_main();\n" " gl_main();\n"
"\n" "\n"
" VS_OUTPUT output;\n" " VS_OUTPUT output;\n";
" output.gl_Position = gl_Position;\n";
if (outputPositionFromVS)
{
vertexHLSL += " output.gl_Position = gl_Position;\n";
}
// On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust. // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust.
if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
...@@ -828,7 +847,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -828,7 +847,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
" output.dx_Position.w = gl_Position.w;\n"; " output.dx_Position.w = gl_Position.w;\n";
} }
if (usesPointSize && shaderModel >= 3) // We don't need to output gl_PointSize if we use are emulating point sprites via instancing.
if (usesPointSize && shaderModel >= 3 && !useInstancedPointSpriteEmulation)
{ {
vertexHLSL += " output.gl_PointSize = gl_PointSize;\n"; vertexHLSL += " output.gl_PointSize = gl_PointSize;\n";
} }
...@@ -877,8 +897,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -877,8 +897,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
{ {
vertexHLSL += "\n" vertexHLSL += "\n"
" gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n" " gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n"
" output.dx_Position.xyz += float3(input.spriteVertexPos.x * gl_PointSize / (dx_ViewCoords.x*2), input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * output.dx_Position.w;\n" " output.dx_Position.xyz += float3(input.spriteVertexPos.x * gl_PointSize / (dx_ViewCoords.x*2), input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * output.dx_Position.w;\n";
" output.gl_PointSize = gl_PointSize;\n";
if (usesPointCoord) if (usesPointCoord)
{ {
...@@ -891,8 +910,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, ...@@ -891,8 +910,8 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
" return output;\n" " return output;\n"
"}\n"; "}\n";
const SemanticInfo &pixelSemantics = getSemanticInfo(registers, usesFragCoord, usesPointCoord, const SemanticInfo &pixelSemantics = getSemanticInfo(registers, outputPositionFromVS, usesFragCoord, usesPointCoord,
usesPointSize, true); (!useInstancedPointSpriteEmulation && usesPointSize), true);
pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n"; pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n";
...@@ -1111,9 +1130,9 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragm ...@@ -1111,9 +1130,9 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragm
std::string geomHLSL; std::string geomHLSL;
const SemanticInfo &inSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord, const SemanticInfo &inSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord,
false, true, false); false, true, false);
const SemanticInfo &outSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord, const SemanticInfo &outSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord,
fragmentShader->mUsesPointCoord, true, false); fragmentShader->mUsesPointCoord, true, false);
std::string varyingHLSL = generateVaryingHLSL(vertexShader); std::string varyingHLSL = generateVaryingHLSL(vertexShader);
......
...@@ -81,8 +81,8 @@ class DynamicHLSL ...@@ -81,8 +81,8 @@ class DynamicHLSL
struct SemanticInfo; struct SemanticInfo;
std::string getVaryingSemantic(bool pointSize) const; std::string getVaryingSemantic(bool pointSize) const;
SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize, SemanticInfo getSemanticInfo(int startRegisters, bool position, bool fragCoord, bool pointCoord,
bool pixelShader) const; bool pointSize, bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const; std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(const ShaderD3D *shader) const; std::string generateVaryingHLSL(const ShaderD3D *shader) const;
void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const; void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
......
...@@ -568,7 +568,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) ...@@ -568,7 +568,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX; case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX;
// No constants for D3D9 viewport size limits, use the maximum texture sizes // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum texture sizes
case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
...@@ -676,7 +676,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) ...@@ -676,7 +676,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
// Uniform blocks not supported in D3D9 feature levels // Uniform blocks not supported on D3D11 Feature Level 9
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 0; case D3D_FEATURE_LEVEL_9_1: return 0;
...@@ -685,10 +685,33 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) ...@@ -685,10 +685,33 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
} }
} }
static size_t GetReservedVertexOutputVectors() static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
{ {
// We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize // According to The OpenGL ES Shading Language specifications
return 4; // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21)
// built-in special variables (e.g. gl_FragCoord, or gl_PointCoord)
// which are statically used in the shader should be included in the variable packing algorithm.
// Therefore, we should not reserve output vectors for them.
switch (featureLevel)
{
// We must reserve one output vector for dx_Position.
// We also reserve one for gl_Position, which we unconditionally output on Feature Levels 10_0+,
// even if it's unused in the shader (e.g. for transform feedback). TODO: This could be improved.
case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return 2;
// Just reserve dx_Position on Feature Level 9, since we don't ever need to output gl_Position.
case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 1;
default: UNREACHABLE(); return 0;
}
return 1;
} }
static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
...@@ -698,15 +721,15 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) ...@@ -698,15 +721,15 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel) switch (featureLevel)
{ {
case D3D_FEATURE_LEVEL_11_1: case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
// Use D3D9 SM3 and SM2 limits // Use Shader Model 2.X limits
case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel);
default: UNREACHABLE(); return 0; default: UNREACHABLE(); return 0;
} }
...@@ -722,7 +745,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) ...@@ -722,7 +745,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
// Vertex textures not supported in D3D9 feature levels according to // Vertex textures not supported on D3D11 Feature Level 9 according to
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
// ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
...@@ -769,7 +792,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) ...@@ -769,7 +792,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
// Uniform blocks not supported in D3D9 feature levels // Uniform blocks not supported on D3D11 Feature Level 9
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 0; case D3D_FEATURE_LEVEL_9_1: return 0;
...@@ -783,15 +806,15 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) ...@@ -783,15 +806,15 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel) switch (featureLevel)
{ {
case D3D_FEATURE_LEVEL_11_1: case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_10_1: case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
// Use D3D9 SM3 and SM2 limits // Use Shader Model 2.X limits
case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_3: return 8 - GetReservedVertexOutputVectors(featureLevel);
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel);
default: UNREACHABLE(); return 0; default: UNREACHABLE(); return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment