Home | History | Annotate | Download | only in pipeline
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2015 The Khronos Group Inc.
      6  * Copyright (c) 2015 Imagination Technologies Ltd.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  *
     20  *//*!
     21  * \file
     22  * \brief Reference renderer.
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktPipelineReferenceRenderer.hpp"
     26 #include "vktPipelineClearUtil.hpp"
     27 #include "rrShadingContext.hpp"
     28 #include "rrVertexAttrib.hpp"
     29 
     30 namespace vkt
     31 {
     32 namespace pipeline
     33 {
     34 
     35 using namespace vk;
     36 
     37 rr::BlendFunc mapVkBlendFactor (VkBlendFactor blend)
     38 {
     39 	switch (blend)
     40 	{
     41 		case VK_BLEND_FACTOR_ZERO:						return rr::BLENDFUNC_ZERO;
     42 		case VK_BLEND_FACTOR_ONE:						return rr::BLENDFUNC_ONE;
     43 		case VK_BLEND_FACTOR_SRC_COLOR:					return rr::BLENDFUNC_SRC_COLOR;
     44 		case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR:		return rr::BLENDFUNC_ONE_MINUS_SRC_COLOR;
     45 		case VK_BLEND_FACTOR_DST_COLOR:					return rr::BLENDFUNC_DST_COLOR;
     46 		case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR:		return rr::BLENDFUNC_ONE_MINUS_DST_COLOR;
     47 		case VK_BLEND_FACTOR_SRC_ALPHA:					return rr::BLENDFUNC_SRC_ALPHA;
     48 		case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:		return rr::BLENDFUNC_ONE_MINUS_SRC_ALPHA;
     49 		case VK_BLEND_FACTOR_DST_ALPHA:					return rr::BLENDFUNC_DST_ALPHA;
     50 		case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA:		return rr::BLENDFUNC_ONE_MINUS_DST_ALPHA;
     51 		case VK_BLEND_FACTOR_CONSTANT_COLOR:			return rr::BLENDFUNC_CONSTANT_COLOR;
     52 		case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:	return rr::BLENDFUNC_ONE_MINUS_CONSTANT_COLOR;
     53 		case VK_BLEND_FACTOR_CONSTANT_ALPHA:			return rr::BLENDFUNC_CONSTANT_ALPHA;
     54 		case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:	return rr::BLENDFUNC_ONE_MINUS_CONSTANT_ALPHA;
     55 		case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE:		return rr::BLENDFUNC_SRC_ALPHA_SATURATE;
     56 		case VK_BLEND_FACTOR_SRC1_COLOR:				return rr::BLENDFUNC_SRC1_COLOR;
     57 		case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR:		return rr::BLENDFUNC_ONE_MINUS_SRC1_COLOR;
     58 		case VK_BLEND_FACTOR_SRC1_ALPHA:				return rr::BLENDFUNC_SRC1_ALPHA;
     59 		case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA:		return rr::BLENDFUNC_ONE_MINUS_SRC1_ALPHA;
     60 		default:
     61 			DE_ASSERT(false);
     62 	}
     63 	return rr::BLENDFUNC_LAST;
     64 }
     65 
     66 rr::BlendEquation mapVkBlendOp (VkBlendOp blendOp)
     67 {
     68 	switch (blendOp)
     69 	{
     70 		case VK_BLEND_OP_ADD:					return rr::BLENDEQUATION_ADD;
     71 		case VK_BLEND_OP_SUBTRACT:				return rr::BLENDEQUATION_SUBTRACT;
     72 		case VK_BLEND_OP_REVERSE_SUBTRACT:		return rr::BLENDEQUATION_REVERSE_SUBTRACT;
     73 		case VK_BLEND_OP_MIN:					return rr::BLENDEQUATION_MIN;
     74 		case VK_BLEND_OP_MAX:					return rr::BLENDEQUATION_MAX;
     75 		default:
     76 			DE_ASSERT(false);
     77 	}
     78 	return rr::BLENDEQUATION_LAST;
     79 }
     80 
     81 tcu::BVec4 mapVkColorComponentFlags (VkColorComponentFlags flags)
     82 {
     83 	return tcu::BVec4((flags & VK_COLOR_COMPONENT_R_BIT) != 0,
     84 					  (flags & VK_COLOR_COMPONENT_G_BIT) != 0,
     85 					  (flags & VK_COLOR_COMPONENT_B_BIT) != 0,
     86 					  (flags & VK_COLOR_COMPONENT_A_BIT) != 0);
     87 }
     88 
     89 rr::TestFunc mapVkCompareOp (VkCompareOp compareFunc)
     90 {
     91 	switch (compareFunc)
     92 	{
     93 		case VK_COMPARE_OP_NEVER:				return rr::TESTFUNC_NEVER;
     94 		case VK_COMPARE_OP_LESS:				return rr::TESTFUNC_LESS;
     95 		case VK_COMPARE_OP_EQUAL:				return rr::TESTFUNC_EQUAL;
     96 		case VK_COMPARE_OP_LESS_OR_EQUAL:		return rr::TESTFUNC_LEQUAL;
     97 		case VK_COMPARE_OP_GREATER:				return rr::TESTFUNC_GREATER;
     98 		case VK_COMPARE_OP_NOT_EQUAL:			return rr::TESTFUNC_NOTEQUAL;
     99 		case VK_COMPARE_OP_GREATER_OR_EQUAL:	return rr::TESTFUNC_GEQUAL;
    100 		case VK_COMPARE_OP_ALWAYS:				return rr::TESTFUNC_ALWAYS;
    101 		default:
    102 			DE_ASSERT(false);
    103 	}
    104 	return rr::TESTFUNC_LAST;
    105 }
    106 
    107 rr::PrimitiveType mapVkPrimitiveTopology (VkPrimitiveTopology primitiveTopology)
    108 {
    109 	switch (primitiveTopology)
    110 	{
    111 		case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:						return rr::PRIMITIVETYPE_POINTS;
    112 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:						return rr::PRIMITIVETYPE_LINES;
    113 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:						return rr::PRIMITIVETYPE_LINE_STRIP;
    114 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:					return rr::PRIMITIVETYPE_TRIANGLES;
    115 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:					return rr::PRIMITIVETYPE_TRIANGLE_FAN;
    116 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:					return rr::PRIMITIVETYPE_TRIANGLE_STRIP;
    117 		case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:		return rr::PRIMITIVETYPE_LINES_ADJACENCY;
    118 		case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:		return rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY;
    119 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:	return rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY;
    120 		case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:	return rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY;
    121 		default:
    122 			DE_ASSERT(false);
    123 	}
    124 	return rr::PRIMITIVETYPE_LAST;
    125 }
    126 
    127 rr::StencilOp mapVkStencilOp (vk::VkStencilOp stencilOp)
    128 {
    129 	switch (stencilOp)
    130 	{
    131 		case VK_STENCIL_OP_KEEP:					return rr::STENCILOP_KEEP;
    132 		case VK_STENCIL_OP_ZERO:					return rr::STENCILOP_ZERO;
    133 		case VK_STENCIL_OP_REPLACE:					return rr::STENCILOP_REPLACE;
    134 		case VK_STENCIL_OP_INCREMENT_AND_CLAMP:		return rr::STENCILOP_INCR;
    135 		case VK_STENCIL_OP_DECREMENT_AND_CLAMP:		return rr::STENCILOP_DECR;
    136 		case VK_STENCIL_OP_INVERT:					return rr::STENCILOP_INVERT;
    137 		case VK_STENCIL_OP_INCREMENT_AND_WRAP:		return rr::STENCILOP_INCR_WRAP;
    138 		case VK_STENCIL_OP_DECREMENT_AND_WRAP:		return rr::STENCILOP_DECR_WRAP;
    139 		default:
    140 			DE_ASSERT(false);
    141 	}
    142 	return rr::STENCILOP_LAST;
    143 }
    144 
    145 tcu::Vec4 swizzle (const tcu::Vec4& color, const tcu::UVec4& swizzle)
    146 {
    147 	const float channelValues[] =
    148 	{
    149 		0.0f,
    150 		1.0f,
    151 		color.x(),
    152 		color.y(),
    153 		color.z(),
    154 		color.w()
    155 	};
    156 
    157 	return tcu::Vec4(channelValues[swizzle.x()],
    158 					 channelValues[swizzle.y()],
    159 					 channelValues[swizzle.z()],
    160 					 channelValues[swizzle.w()]);
    161 }
    162 
    163 ReferenceRenderer::ReferenceRenderer(int						surfaceWidth,
    164 									 int						surfaceHeight,
    165 									 int						numSamples,
    166 									 const tcu::TextureFormat&	colorFormat,
    167 									 const tcu::TextureFormat&	depthStencilFormat,
    168 									 const rr::Program* const	program)
    169 	: m_surfaceWidth		(surfaceWidth)
    170 	, m_surfaceHeight		(surfaceHeight)
    171 	, m_numSamples			(numSamples)
    172 	, m_colorFormat			(colorFormat)
    173 	, m_depthStencilFormat	(depthStencilFormat)
    174 	, m_program				(program)
    175 {
    176 	const tcu::TextureChannelClass	formatClass				= tcu::getTextureChannelClass(colorFormat.type);
    177 	const bool						hasDepthStencil			= (m_depthStencilFormat.order != tcu::TextureFormat::CHANNELORDER_LAST);
    178 	const bool						hasDepthBufferOnly		= (m_depthStencilFormat.order == tcu::TextureFormat::D);
    179 	const bool						hasStencilBufferOnly	= (m_depthStencilFormat.order == tcu::TextureFormat::S);
    180 	const int						actualSamples			= (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? 1: m_numSamples;
    181 
    182 	m_colorBuffer.setStorage(m_colorFormat, actualSamples, m_surfaceWidth, m_surfaceHeight);
    183 	m_resolveColorBuffer.setStorage(m_colorFormat, m_surfaceWidth, m_surfaceHeight);
    184 
    185 	if (formatClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
    186 	{
    187 		tcu::clear(m_colorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
    188 		tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorInt(m_colorFormat));
    189 	}
    190 	else if (formatClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
    191 	{
    192 		tcu::clear(m_colorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
    193 		tcu::clear(m_resolveColorBuffer.getAccess(), defaultClearColorUint(m_colorFormat));
    194 	}
    195 	else
    196 	{
    197 		tcu::Vec4 clearColor = defaultClearColor(m_colorFormat);
    198 
    199 		if (isSRGB(m_colorFormat))
    200 			clearColor = tcu::linearToSRGB(clearColor);
    201 
    202 		tcu::clear(m_colorBuffer.getAccess(), clearColor);
    203 		tcu::clear(m_resolveColorBuffer.getAccess(), clearColor);
    204 	}
    205 
    206 	if (hasDepthStencil)
    207 	{
    208 		if (hasDepthBufferOnly)
    209 		{
    210 			m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
    211 			tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
    212 
    213 			m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
    214 												  rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
    215 		}
    216 		else if (hasStencilBufferOnly)
    217 		{
    218 			m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
    219 			tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
    220 
    221 			m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
    222 												  rr::MultisamplePixelBufferAccess(),
    223 												  rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
    224 		}
    225 		else
    226 		{
    227 			m_depthStencilBuffer.setStorage(m_depthStencilFormat, actualSamples, surfaceWidth, surfaceHeight);
    228 
    229 			tcu::clearDepth(m_depthStencilBuffer.getAccess(), defaultClearDepth());
    230 			tcu::clearStencil(m_depthStencilBuffer.getAccess(), defaultClearStencil());
    231 
    232 			m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()),
    233 												  rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()),
    234 												  rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_depthStencilBuffer.getAccess()));
    235 		}
    236 	}
    237 	else
    238 	{
    239 		m_renderTarget = new rr::RenderTarget(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess()));
    240 	}
    241 }
    242 
    243 ReferenceRenderer::~ReferenceRenderer (void)
    244 {
    245 	delete m_renderTarget;
    246 }
    247 
    248 void ReferenceRenderer::colorClear(const tcu::Vec4& color)
    249 {
    250 	tcu::clear(m_colorBuffer.getAccess(), color);
    251 	tcu::clear(m_resolveColorBuffer.getAccess(), color);
    252 }
    253 
    254 void ReferenceRenderer::draw (const rr::RenderState&			renderState,
    255 							  const rr::PrimitiveType			primitive,
    256 							  const std::vector<Vertex4RGBA>&	vertexBuffer)
    257 {
    258 	const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
    259 
    260 	std::vector<tcu::Vec4> positions;
    261 	std::vector<tcu::Vec4> colors;
    262 
    263 	for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
    264 	{
    265 		const Vertex4RGBA& v = vertexBuffer[vertexNdx];
    266 		positions.push_back(v.position);
    267 		colors.push_back(v.color);
    268 	}
    269 
    270 	rr::VertexAttrib vertexAttribs[2];
    271 
    272 	// Position attribute
    273 	vertexAttribs[0].type		= rr::VERTEXATTRIBTYPE_FLOAT;
    274 	vertexAttribs[0].size		= 4;
    275 	vertexAttribs[0].pointer	= positions.data();
    276 	// UV attribute
    277 	vertexAttribs[1].type		= rr::VERTEXATTRIBTYPE_FLOAT;
    278 	vertexAttribs[1].size		= 4;
    279 	vertexAttribs[1].pointer	= colors.data();
    280 
    281 	rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
    282 
    283 	m_renderer.draw(drawQuadCommand);
    284 }
    285 
    286 void ReferenceRenderer::draw (const rr::RenderState&			renderState,
    287 							  const rr::PrimitiveType			primitive,
    288 							  const std::vector<Vertex4Tex4>&	vertexBuffer)
    289 {
    290 	const rr::PrimitiveList primitives(primitive, (int)vertexBuffer.size(), 0);
    291 
    292 	std::vector<tcu::Vec4> positions;
    293 	std::vector<tcu::Vec4> texCoords;
    294 
    295 	for (size_t vertexNdx = 0; vertexNdx < vertexBuffer.size(); vertexNdx++)
    296 	{
    297 		const Vertex4Tex4& v = vertexBuffer[vertexNdx];
    298 		positions.push_back(v.position);
    299 		texCoords.push_back(v.texCoord);
    300 	}
    301 
    302 	rr::VertexAttrib vertexAttribs[2];
    303 
    304 	// Position attribute
    305 	vertexAttribs[0].type		= rr::VERTEXATTRIBTYPE_FLOAT;
    306 	vertexAttribs[0].size		= 4;
    307 	vertexAttribs[0].pointer	= positions.data();
    308 	// UV attribute
    309 	vertexAttribs[1].type		= rr::VERTEXATTRIBTYPE_FLOAT;
    310 	vertexAttribs[1].size		= 4;
    311 	vertexAttribs[1].pointer	= texCoords.data();
    312 
    313 	rr::DrawCommand drawQuadCommand(renderState, *m_renderTarget, *m_program, 2, vertexAttribs, primitives);
    314 
    315 	m_renderer.draw(drawQuadCommand);
    316 }
    317 
    318 tcu::PixelBufferAccess ReferenceRenderer::getAccess (void)
    319 {
    320 	rr::MultisampleConstPixelBufferAccess multiSampleAccess = rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(m_colorBuffer.getAccess());
    321 	rr::resolveMultisampleColorBuffer(m_resolveColorBuffer.getAccess(), multiSampleAccess);
    322 
    323 	return m_resolveColorBuffer.getAccess();
    324 }
    325 
    326 const rr::ViewportState ReferenceRenderer::getViewportState (void) const
    327 {
    328 	return rr::ViewportState(rr::WindowRectangle(0, 0, m_surfaceWidth, m_surfaceHeight));
    329 }
    330 
    331 } // pipeline
    332 } // vkt
    333