#include "vkImageUtil.hpp"
#include "tcuCommandLine.hpp"
#include "tcuRGBA.hpp"
+#include "tcuStringTemplate.hpp"
namespace vkt
{
void GeometryShaderTestInstance::createPipeline (void)
{
- const DeviceInterface& vk = m_context.getDeviceInterface();
- const VkDevice device = m_context.getDevice();
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+ const VkBool32 useGeomPointSize = m_context.getDeviceFeatures().shaderTessellationAndGeometryPointSize && (m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
// Pipeline
Unique<VkShaderModule> vs(createShaderModule(vk, device, m_context.getBinaryCollection().get("vertex"), (VkShaderModuleCreateFlags)0));
- Unique<VkShaderModule> gs(createShaderModule(vk, device, m_context.getBinaryCollection().get("geometry"), (VkShaderModuleCreateFlags)0));
+ Unique<VkShaderModule> gs(createShaderModule(vk, device, m_context.getBinaryCollection().get(useGeomPointSize ? "geometry_point_size" : "geometry"), (VkShaderModuleCreateFlags)0));
Unique<VkShaderModule> fs(createShaderModule(vk, device, m_context.getBinaryCollection().get("fragment"), (VkShaderModuleCreateFlags)0));
const PipelineCreateInfo::ColorBlendState::Attachment attachmentState;
if(m_parametersGraphic.queryStatisticFlags & (VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT |
VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT))
{ // Geometry Shader
+ const bool isTopologyPointSize = m_parametersGraphic.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
std::ostringstream source;
source << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
<< "layout("<<inputTypeToGLString(m_parametersGraphic.primitiveTopology)<<") in;\n"
<< "void main (void)\n"
<< "{\n"
<< " out_color = in_color[0];\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n"
+ << (isTopologyPointSize ? "${pointSize}" : "" )
<< " gl_Position = gl_in[0].gl_Position;\n"
<< " EmitVertex();\n"
<< " EndPrimitive();\n"
<< "\n"
<< " out_color = in_color[0];\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n"
+ << (isTopologyPointSize ? "${pointSize}" : "")
<< " gl_Position = vec4(1.0, 1.0, 1.0, 1.0);\n"
<< " EmitVertex();\n"
<< " out_color = in_color[0];\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n"
+ << (isTopologyPointSize ? "${pointSize}" : "")
<< " gl_Position = vec4(-1.0, -1.0, 1.0, 1.0);\n"
<< " EmitVertex();\n"
<< " EndPrimitive();\n"
else
{
source << " out_color = in_color[0];\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n"
- << " gl_Position = vec4(1.0, 1.0, 1.0, 1.0);\n"
+ << (isTopologyPointSize ? "${pointSize}" : "")
+ << " gl_Position = vec4(1.0, 1.0, 1.0, 1.0);\n"
<< " EmitVertex();\n"
<< " out_color = in_color[0];\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n"
+ << (isTopologyPointSize ? "${pointSize}" : "")
<< " gl_Position = vec4(1.0, -1.0, 1.0, 1.0);\n"
<< " EmitVertex();\n"
<< " out_color = in_color[0];\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n"
+ << (isTopologyPointSize ? "${pointSize}" : "")
<< " gl_Position = vec4(-1.0, 1.0, 1.0, 1.0);\n"
<< " EmitVertex();\n"
<< " out_color = in_color[0];\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n"
+ << (isTopologyPointSize ? "${pointSize}" : "")
<< " gl_Position = vec4(-1.0, -1.0, 1.0, 1.0);\n"
<< " EmitVertex();\n"
<< " EndPrimitive();\n";
}
source << "}\n";
- sourceCollections.glslSources.add("geometry") << glu::GeometrySource(source.str());
+
+ if (isTopologyPointSize)
+ {
+ // Add geometry shader codes with and without gl_PointSize if the primitive topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST
+
+ tcu::StringTemplate sourceTemplate(source.str());
+
+ std::map<std::string, std::string> pointSize;
+ std::map<std::string, std::string> noPointSize;
+
+ pointSize["pointSize"] = " gl_PointSize = gl_in[0].gl_PointSize;\n";
+ noPointSize["pointSize"] = "";
+
+ sourceCollections.glslSources.add("geometry") << glu::GeometrySource(sourceTemplate.specialize(noPointSize));
+ sourceCollections.glslSources.add("geometry_point_size") << glu::GeometrySource(sourceTemplate.specialize(pointSize));
+ }
+ else
+ {
+ sourceCollections.glslSources.add("geometry") << glu::GeometrySource(source.str());
+ }
}
{ // Fragment Shader
return src.str();
}
-static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
+static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix, const bool pointSizeSupported)
{
DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
<< "void main (void)\n"
<< "{\n"
<< " gl_Position = gl_in[0].gl_Position;\n"
- << " gl_PointSize = gl_in[0].gl_PointSize;\n\n";
+ << (pointSizeSupported ? " gl_PointSize = gl_in[0].gl_PointSize;\n\n" : "");
// Fetch input variables
for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
if (useGeometryShader)
{
- geometryShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geom"), 0);
+ if (m_context.getDeviceFeatures().shaderTessellationAndGeometryPointSize)
+ geometryShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geom_point_size"), 0);
+ else
+ geometryShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geom"), 0);
}
}
programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec, "a_", "vtx_out_")) << shaderSpec.buildOptions;
- programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_")) << shaderSpec.buildOptions;
+ programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_", false)) << shaderSpec.buildOptions;
+ programCollection.glslSources.add("geom_point_size") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_", true)) << shaderSpec.buildOptions;
/* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "geom_out_", "o_")) << shaderSpec.buildOptions;