1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) Module 3e5c31af7Sopenharmony_ci * ----------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief sglr-rsg adaptation. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "glsRandomShaderProgram.hpp" 25e5c31af7Sopenharmony_ci#include "rsgShader.hpp" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_cinamespace deqp 28e5c31af7Sopenharmony_ci{ 29e5c31af7Sopenharmony_cinamespace gls 30e5c31af7Sopenharmony_ci{ 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ciusing std::vector; 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_cistatic rr::GenericVecType mapToGenericVecType (const rsg::VariableType& varType) 35e5c31af7Sopenharmony_ci{ 36e5c31af7Sopenharmony_ci if (varType.isFloatOrVec()) 37e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_FLOAT; 38e5c31af7Sopenharmony_ci else if (varType.isIntOrVec()) 39e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_INT32; 40e5c31af7Sopenharmony_ci else 41e5c31af7Sopenharmony_ci { 42e5c31af7Sopenharmony_ci DE_ASSERT(false); 43e5c31af7Sopenharmony_ci return rr::GENERICVECTYPE_LAST; 44e5c31af7Sopenharmony_ci } 45e5c31af7Sopenharmony_ci} 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_cistatic glu::DataType mapToBasicType (const rsg::VariableType& varType) 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_ci if (varType.isFloatOrVec() || varType.isIntOrVec() || varType.isBoolOrVec()) 50e5c31af7Sopenharmony_ci { 51e5c31af7Sopenharmony_ci const glu::DataType scalarType = varType.isFloatOrVec() ? glu::TYPE_FLOAT : 52e5c31af7Sopenharmony_ci varType.isIntOrVec() ? glu::TYPE_INT : 53e5c31af7Sopenharmony_ci varType.isBoolOrVec() ? glu::TYPE_BOOL : glu::TYPE_LAST; 54e5c31af7Sopenharmony_ci const int numComps = varType.getNumElements(); 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numComps, 1, 4)); 57e5c31af7Sopenharmony_ci return glu::DataType(scalarType + numComps - 1); 58e5c31af7Sopenharmony_ci } 59e5c31af7Sopenharmony_ci else if (varType.getBaseType() == rsg::VariableType::TYPE_SAMPLER_2D) 60e5c31af7Sopenharmony_ci return glu::TYPE_SAMPLER_2D; 61e5c31af7Sopenharmony_ci else if (varType.getBaseType() == rsg::VariableType::TYPE_SAMPLER_CUBE) 62e5c31af7Sopenharmony_ci return glu::TYPE_SAMPLER_CUBE; 63e5c31af7Sopenharmony_ci else 64e5c31af7Sopenharmony_ci { 65e5c31af7Sopenharmony_ci DE_ASSERT(false); 66e5c31af7Sopenharmony_ci return glu::TYPE_LAST; 67e5c31af7Sopenharmony_ci } 68e5c31af7Sopenharmony_ci} 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_cistatic void generateProgramDeclaration (sglr::pdec::ShaderProgramDeclaration& decl, const rsg::Shader& vertexShader, const rsg::Shader& fragmentShader, int numUnifiedUniforms, const rsg::ShaderInput* const* unifiedUniforms) 71e5c31af7Sopenharmony_ci{ 72e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexSource(vertexShader.getSource()) 73e5c31af7Sopenharmony_ci << sglr::pdec::FragmentSource(fragmentShader.getSource()); 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci for (vector<rsg::ShaderInput*>::const_iterator vtxInIter = vertexShader.getInputs().begin(); vtxInIter != vertexShader.getInputs().end(); ++vtxInIter) 76e5c31af7Sopenharmony_ci { 77e5c31af7Sopenharmony_ci const rsg::ShaderInput* vertexInput = *vtxInIter; 78e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexAttribute(vertexInput->getVariable()->getName(), mapToGenericVecType(vertexInput->getVariable()->getType())); 79e5c31af7Sopenharmony_ci } 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci for (vector<rsg::ShaderInput*>::const_iterator fragInIter = fragmentShader.getInputs().begin(); fragInIter != fragmentShader.getInputs().end(); ++fragInIter) 82e5c31af7Sopenharmony_ci { 83e5c31af7Sopenharmony_ci const rsg::ShaderInput* fragInput = *fragInIter; 84e5c31af7Sopenharmony_ci decl << sglr::pdec::VertexToFragmentVarying(mapToGenericVecType(fragInput->getVariable()->getType())); 85e5c31af7Sopenharmony_ci } 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ci for (int uniformNdx = 0; uniformNdx < numUnifiedUniforms; uniformNdx++) 88e5c31af7Sopenharmony_ci { 89e5c31af7Sopenharmony_ci const rsg::ShaderInput* uniform = unifiedUniforms[uniformNdx]; 90e5c31af7Sopenharmony_ci decl << sglr::pdec::Uniform(uniform->getVariable()->getName(), mapToBasicType(uniform->getVariable()->getType())); 91e5c31af7Sopenharmony_ci } 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT); 94e5c31af7Sopenharmony_ci} 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_cistatic sglr::pdec::ShaderProgramDeclaration generateProgramDeclaration (const rsg::Shader& vertexShader, const rsg::Shader& fragmentShader, int numUnifiedUniforms, const rsg::ShaderInput* const* unifiedUniforms) 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_ci sglr::pdec::ShaderProgramDeclaration decl; 99e5c31af7Sopenharmony_ci generateProgramDeclaration(decl, vertexShader, fragmentShader, numUnifiedUniforms, unifiedUniforms); 100e5c31af7Sopenharmony_ci return decl; 101e5c31af7Sopenharmony_ci} 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_cistatic const rsg::Variable* findShaderOutputByName (const rsg::Shader& shader, const char* name) 104e5c31af7Sopenharmony_ci{ 105e5c31af7Sopenharmony_ci vector<const rsg::Variable*> outputs; 106e5c31af7Sopenharmony_ci shader.getOutputs(outputs); 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ci for (vector<const rsg::Variable*>::const_iterator iter = outputs.begin(); iter != outputs.end(); ++iter) 109e5c31af7Sopenharmony_ci { 110e5c31af7Sopenharmony_ci if (deStringEqual((*iter)->getName(), name)) 111e5c31af7Sopenharmony_ci return *iter; 112e5c31af7Sopenharmony_ci } 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ci return DE_NULL; 115e5c31af7Sopenharmony_ci} 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_cistatic const rsg::Variable* findShaderOutputByLocation (const rsg::Shader& shader, int location) 118e5c31af7Sopenharmony_ci{ 119e5c31af7Sopenharmony_ci vector<const rsg::Variable*> outputs; 120e5c31af7Sopenharmony_ci shader.getOutputs(outputs); 121e5c31af7Sopenharmony_ci 122e5c31af7Sopenharmony_ci for (vector<const rsg::Variable*>::const_iterator iter = outputs.begin(); iter != outputs.end(); iter++) 123e5c31af7Sopenharmony_ci { 124e5c31af7Sopenharmony_ci if ((*iter)->getLayoutLocation() == location) 125e5c31af7Sopenharmony_ci return *iter; 126e5c31af7Sopenharmony_ci } 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci return DE_NULL; 129e5c31af7Sopenharmony_ci} 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ciRandomShaderProgram::RandomShaderProgram (const rsg::Shader& vertexShader, const rsg::Shader& fragmentShader, int numUnifiedUniforms, const rsg::ShaderInput* const* unifiedUniforms) 132e5c31af7Sopenharmony_ci : sglr::ShaderProgram (generateProgramDeclaration(vertexShader, fragmentShader, numUnifiedUniforms, unifiedUniforms)) 133e5c31af7Sopenharmony_ci , m_vertexShader (vertexShader) 134e5c31af7Sopenharmony_ci , m_fragmentShader (fragmentShader) 135e5c31af7Sopenharmony_ci , m_numUnifiedUniforms (numUnifiedUniforms) 136e5c31af7Sopenharmony_ci , m_unifiedUniforms (unifiedUniforms) 137e5c31af7Sopenharmony_ci , m_positionVar (findShaderOutputByName(vertexShader, "gl_Position")) 138e5c31af7Sopenharmony_ci , m_fragColorVar (findShaderOutputByLocation(fragmentShader, 0)) 139e5c31af7Sopenharmony_ci , m_execCtx (m_sampler2DMap, m_samplerCubeMap) 140e5c31af7Sopenharmony_ci{ 141e5c31af7Sopenharmony_ci TCU_CHECK_INTERNAL(m_positionVar && m_positionVar->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT && m_positionVar->getType().getNumElements() == 4); 142e5c31af7Sopenharmony_ci TCU_CHECK_INTERNAL(m_fragColorVar && m_fragColorVar->getType().getBaseType() == rsg::VariableType::TYPE_FLOAT && m_fragColorVar->getType().getNumElements() == 4); 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci // Build list of vertex outputs. 145e5c31af7Sopenharmony_ci for (vector<rsg::ShaderInput*>::const_iterator fragInIter = fragmentShader.getInputs().begin(); fragInIter != fragmentShader.getInputs().end(); ++fragInIter) 146e5c31af7Sopenharmony_ci { 147e5c31af7Sopenharmony_ci const rsg::ShaderInput* fragInput = *fragInIter; 148e5c31af7Sopenharmony_ci const rsg::Variable* vertexOutput = findShaderOutputByName(vertexShader, fragInput->getVariable()->getName()); 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci TCU_CHECK_INTERNAL(vertexOutput); 151e5c31af7Sopenharmony_ci m_vertexOutputs.push_back(vertexOutput); 152e5c31af7Sopenharmony_ci } 153e5c31af7Sopenharmony_ci} 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_civoid RandomShaderProgram::refreshUniforms (void) const 156e5c31af7Sopenharmony_ci{ 157e5c31af7Sopenharmony_ci DE_ASSERT(m_numUnifiedUniforms == (int)m_uniforms.size()); 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_ci for (int uniformNdx = 0; uniformNdx < m_numUnifiedUniforms; uniformNdx++) 160e5c31af7Sopenharmony_ci { 161e5c31af7Sopenharmony_ci const rsg::Variable* uniformVar = m_unifiedUniforms[uniformNdx]->getVariable(); 162e5c31af7Sopenharmony_ci const rsg::VariableType& uniformType = uniformVar->getType(); 163e5c31af7Sopenharmony_ci const sglr::UniformSlot& uniformSlot = m_uniforms[uniformNdx]; 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci m_execCtx.getValue(uniformVar) = rsg::ConstValueAccess(uniformType, (const rsg::Scalar*)&uniformSlot.value).value(); 166e5c31af7Sopenharmony_ci } 167e5c31af7Sopenharmony_ci} 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_civoid RandomShaderProgram::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const 170e5c31af7Sopenharmony_ci{ 171e5c31af7Sopenharmony_ci // \todo [2013-12-13 pyry] Do only when necessary. 172e5c31af7Sopenharmony_ci refreshUniforms(); 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci int packetOffset = 0; 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci while (packetOffset < numPackets) 177e5c31af7Sopenharmony_ci { 178e5c31af7Sopenharmony_ci const int numToExecute = de::min(numPackets-packetOffset, (int)rsg::EXEC_VEC_WIDTH); 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci // Fetch attributes. 181e5c31af7Sopenharmony_ci for (int attribNdx = 0; attribNdx < (int)m_vertexShader.getInputs().size(); ++attribNdx) 182e5c31af7Sopenharmony_ci { 183e5c31af7Sopenharmony_ci const rsg::Variable* attribVar = m_vertexShader.getInputs()[attribNdx]->getVariable(); 184e5c31af7Sopenharmony_ci const rsg::VariableType& attribType = attribVar->getType(); 185e5c31af7Sopenharmony_ci const int numComponents = attribType.getNumElements(); 186e5c31af7Sopenharmony_ci rsg::ExecValueAccess access = m_execCtx.getValue(attribVar); 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci DE_ASSERT(attribType.isFloatOrVec() && de::inRange(numComponents, 1, 4)); 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numToExecute; ndx++) 191e5c31af7Sopenharmony_ci { 192e5c31af7Sopenharmony_ci const int packetNdx = ndx+packetOffset; 193e5c31af7Sopenharmony_ci const rr::VertexPacket* packet = packets[packetNdx]; 194e5c31af7Sopenharmony_ci const tcu::Vec4 attribValue = rr::readVertexAttribFloat(inputs[attribNdx], packet->instanceNdx, packet->vertexNdx); 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci access.component(0).asFloat(ndx) = attribValue[0]; 197e5c31af7Sopenharmony_ci if (numComponents >= 2) access.component(1).asFloat(ndx) = attribValue[1]; 198e5c31af7Sopenharmony_ci if (numComponents >= 3) access.component(2).asFloat(ndx) = attribValue[2]; 199e5c31af7Sopenharmony_ci if (numComponents >= 4) access.component(3).asFloat(ndx) = attribValue[3]; 200e5c31af7Sopenharmony_ci } 201e5c31af7Sopenharmony_ci } 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci m_vertexShader.execute(m_execCtx); 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci // Store position 206e5c31af7Sopenharmony_ci { 207e5c31af7Sopenharmony_ci const rsg::ExecConstValueAccess access = m_execCtx.getValue(m_positionVar); 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numToExecute; ndx++) 210e5c31af7Sopenharmony_ci { 211e5c31af7Sopenharmony_ci const int packetNdx = ndx+packetOffset; 212e5c31af7Sopenharmony_ci rr::VertexPacket* packet = packets[packetNdx]; 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_ci packet->position[0] = access.component(0).asFloat(ndx); 215e5c31af7Sopenharmony_ci packet->position[1] = access.component(1).asFloat(ndx); 216e5c31af7Sopenharmony_ci packet->position[2] = access.component(2).asFloat(ndx); 217e5c31af7Sopenharmony_ci packet->position[3] = access.component(3).asFloat(ndx); 218e5c31af7Sopenharmony_ci } 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci // Other varyings 222e5c31af7Sopenharmony_ci for (int varNdx = 0; varNdx < (int)m_vertexOutputs.size(); varNdx++) 223e5c31af7Sopenharmony_ci { 224e5c31af7Sopenharmony_ci const rsg::Variable* var = m_vertexOutputs[varNdx]; 225e5c31af7Sopenharmony_ci const rsg::VariableType& varType = var->getType(); 226e5c31af7Sopenharmony_ci const int numComponents = varType.getNumElements(); 227e5c31af7Sopenharmony_ci const rsg::ExecConstValueAccess access = m_execCtx.getValue(var); 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci DE_ASSERT(varType.isFloatOrVec() && de::inRange(numComponents, 1, 4)); 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numToExecute; ndx++) 232e5c31af7Sopenharmony_ci { 233e5c31af7Sopenharmony_ci const int packetNdx = ndx+packetOffset; 234e5c31af7Sopenharmony_ci rr::VertexPacket* const packet = packets[packetNdx]; 235e5c31af7Sopenharmony_ci float* const dst = packet->outputs[varNdx].getAccess<float>(); 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci dst[0] = access.component(0).asFloat(ndx); 238e5c31af7Sopenharmony_ci if (numComponents >= 2) dst[1] = access.component(1).asFloat(ndx); 239e5c31af7Sopenharmony_ci if (numComponents >= 3) dst[2] = access.component(2).asFloat(ndx); 240e5c31af7Sopenharmony_ci if (numComponents >= 4) dst[3] = access.component(3).asFloat(ndx); 241e5c31af7Sopenharmony_ci } 242e5c31af7Sopenharmony_ci } 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci packetOffset += numToExecute; 245e5c31af7Sopenharmony_ci } 246e5c31af7Sopenharmony_ci} 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_civoid RandomShaderProgram::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const 249e5c31af7Sopenharmony_ci{ 250e5c31af7Sopenharmony_ci const rsg::ExecConstValueAccess fragColorAccess = m_execCtx.getValue(m_fragColorVar); 251e5c31af7Sopenharmony_ci int packetOffset = 0; 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(rsg::EXEC_VEC_WIDTH % rr::NUM_FRAGMENTS_PER_PACKET == 0); 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_ci while (packetOffset < numPackets) 256e5c31af7Sopenharmony_ci { 257e5c31af7Sopenharmony_ci const int numPacketsToExecute = de::min(numPackets-packetOffset, (int)rsg::EXEC_VEC_WIDTH / (int)rr::NUM_FRAGMENTS_PER_PACKET); 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci // Interpolate varyings. 260e5c31af7Sopenharmony_ci for (int varNdx = 0; varNdx < (int)m_fragmentShader.getInputs().size(); ++varNdx) 261e5c31af7Sopenharmony_ci { 262e5c31af7Sopenharmony_ci const rsg::Variable* var = m_fragmentShader.getInputs()[varNdx]->getVariable(); 263e5c31af7Sopenharmony_ci const rsg::VariableType& varType = var->getType(); 264e5c31af7Sopenharmony_ci const int numComponents = varType.getNumElements(); 265e5c31af7Sopenharmony_ci rsg::ExecValueAccess access = m_execCtx.getValue(var); 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ci DE_ASSERT(varType.isFloatOrVec() && de::inRange(numComponents, 1, 4)); 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPacketsToExecute; packetNdx++) 270e5c31af7Sopenharmony_ci { 271e5c31af7Sopenharmony_ci const rr::FragmentPacket& packet = packets[packetOffset+packetNdx]; 272e5c31af7Sopenharmony_ci 273e5c31af7Sopenharmony_ci for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++) 274e5c31af7Sopenharmony_ci { 275e5c31af7Sopenharmony_ci const tcu::Vec4 varValue = rr::readVarying<float>(packet, context, varNdx, fragNdx); 276e5c31af7Sopenharmony_ci const int dstNdx = packetNdx*rr::NUM_FRAGMENTS_PER_PACKET + fragNdx; 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci access.component(0).asFloat(dstNdx) = varValue[0]; 279e5c31af7Sopenharmony_ci if (numComponents >= 2) access.component(1).asFloat(dstNdx) = varValue[1]; 280e5c31af7Sopenharmony_ci if (numComponents >= 3) access.component(2).asFloat(dstNdx) = varValue[2]; 281e5c31af7Sopenharmony_ci if (numComponents >= 4) access.component(3).asFloat(dstNdx) = varValue[3]; 282e5c31af7Sopenharmony_ci } 283e5c31af7Sopenharmony_ci } 284e5c31af7Sopenharmony_ci } 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ci m_fragmentShader.execute(m_execCtx); 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci // Store color 289e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPacketsToExecute; packetNdx++) 290e5c31af7Sopenharmony_ci { 291e5c31af7Sopenharmony_ci for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; fragNdx++) 292e5c31af7Sopenharmony_ci { 293e5c31af7Sopenharmony_ci const int srcNdx = packetNdx*rr::NUM_FRAGMENTS_PER_PACKET + fragNdx; 294e5c31af7Sopenharmony_ci const tcu::Vec4 color (fragColorAccess.component(0).asFloat(srcNdx), 295e5c31af7Sopenharmony_ci fragColorAccess.component(1).asFloat(srcNdx), 296e5c31af7Sopenharmony_ci fragColorAccess.component(2).asFloat(srcNdx), 297e5c31af7Sopenharmony_ci fragColorAccess.component(3).asFloat(srcNdx)); 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_ci rr::writeFragmentOutput(context, packetOffset+packetNdx, fragNdx, 0, color); 300e5c31af7Sopenharmony_ci } 301e5c31af7Sopenharmony_ci } 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci packetOffset += numPacketsToExecute; 304e5c31af7Sopenharmony_ci } 305e5c31af7Sopenharmony_ci} 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ci} // gls 308e5c31af7Sopenharmony_ci} // deqp 309