1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Random Shader Generator 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 Program Executor. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "rsgProgramExecutor.hpp" 25e5c31af7Sopenharmony_ci#include "rsgExecutionContext.hpp" 26e5c31af7Sopenharmony_ci#include "rsgVariableValue.hpp" 27e5c31af7Sopenharmony_ci#include "rsgUtils.hpp" 28e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 29e5c31af7Sopenharmony_ci#include "deMath.h" 30e5c31af7Sopenharmony_ci#include "deString.h" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include <set> 33e5c31af7Sopenharmony_ci#include <string> 34e5c31af7Sopenharmony_ci#include <map> 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ciusing std::set; 37e5c31af7Sopenharmony_ciusing std::string; 38e5c31af7Sopenharmony_ciusing std::vector; 39e5c31af7Sopenharmony_ciusing std::map; 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_cinamespace rsg 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ciclass VaryingStorage 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_cipublic: 47e5c31af7Sopenharmony_ci VaryingStorage (const VariableType& type, int numVertices); 48e5c31af7Sopenharmony_ci ~VaryingStorage (void) {} 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ci ValueAccess getValue (const VariableType& type, int vtxNdx); 51e5c31af7Sopenharmony_ci ConstValueAccess getValue (const VariableType& type, int vtxNdx) const; 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_ciprivate: 54e5c31af7Sopenharmony_ci std::vector<Scalar> m_value; 55e5c31af7Sopenharmony_ci}; 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_ciVaryingStorage::VaryingStorage (const VariableType& type, int numVertices) 58e5c31af7Sopenharmony_ci : m_value(type.getScalarSize()*numVertices) 59e5c31af7Sopenharmony_ci{ 60e5c31af7Sopenharmony_ci} 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ciValueAccess VaryingStorage::getValue (const VariableType& type, int vtxNdx) 63e5c31af7Sopenharmony_ci{ 64e5c31af7Sopenharmony_ci return ValueAccess(type, &m_value[type.getScalarSize()*vtxNdx]); 65e5c31af7Sopenharmony_ci} 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ciConstValueAccess VaryingStorage::getValue (const VariableType& type, int vtxNdx) const 68e5c31af7Sopenharmony_ci{ 69e5c31af7Sopenharmony_ci return ConstValueAccess(type, &m_value[type.getScalarSize()*vtxNdx]); 70e5c31af7Sopenharmony_ci} 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ciclass VaryingStore 73e5c31af7Sopenharmony_ci{ 74e5c31af7Sopenharmony_cipublic: 75e5c31af7Sopenharmony_ci VaryingStore (int numVertices); 76e5c31af7Sopenharmony_ci ~VaryingStore (void); 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci VaryingStorage* getStorage (const VariableType& type, const char* name); 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_ciprivate: 81e5c31af7Sopenharmony_ci int m_numVertices; 82e5c31af7Sopenharmony_ci std::map<std::string, VaryingStorage*> m_values; 83e5c31af7Sopenharmony_ci}; 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ciVaryingStore::VaryingStore (int numVertices) 86e5c31af7Sopenharmony_ci : m_numVertices(numVertices) 87e5c31af7Sopenharmony_ci{ 88e5c31af7Sopenharmony_ci} 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ciVaryingStore::~VaryingStore (void) 91e5c31af7Sopenharmony_ci{ 92e5c31af7Sopenharmony_ci for (map<string, VaryingStorage*>::iterator i = m_values.begin(); i != m_values.end(); i++) 93e5c31af7Sopenharmony_ci delete i->second; 94e5c31af7Sopenharmony_ci m_values.clear(); 95e5c31af7Sopenharmony_ci} 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ciVaryingStorage* VaryingStore::getStorage (const VariableType& type, const char* name) 98e5c31af7Sopenharmony_ci{ 99e5c31af7Sopenharmony_ci VaryingStorage* storage = m_values[name]; 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_ci if (!storage) 102e5c31af7Sopenharmony_ci { 103e5c31af7Sopenharmony_ci storage = new VaryingStorage(type, m_numVertices); 104e5c31af7Sopenharmony_ci m_values[name] = storage; 105e5c31af7Sopenharmony_ci } 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci return storage; 108e5c31af7Sopenharmony_ci} 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ciinline float interpolateVertexQuad (const tcu::Vec4& quad, float x, float y) 111e5c31af7Sopenharmony_ci{ 112e5c31af7Sopenharmony_ci float w00 = (1.0f-x)*(1.0f-y); 113e5c31af7Sopenharmony_ci float w01 = (1.0f-x)*y; 114e5c31af7Sopenharmony_ci float w10 = x*(1.0f-y); 115e5c31af7Sopenharmony_ci float w11 = x*y; 116e5c31af7Sopenharmony_ci return quad.x()*w00 + quad.y()*w10 + quad.z()*w01 + quad.w()*w11; 117e5c31af7Sopenharmony_ci} 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ciinline float interpolateVertex (float x0y0, float x1y1, float x, float y) 120e5c31af7Sopenharmony_ci{ 121e5c31af7Sopenharmony_ci return interpolateVertexQuad(tcu::Vec4(x0y0, (x0y0+x1y1)*0.5f, (x0y0+x1y1)*0.5f, x1y1), x, y); 122e5c31af7Sopenharmony_ci} 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ciinline float interpolateTri (float v0, float v1, float v2, float x, float y) 125e5c31af7Sopenharmony_ci{ 126e5c31af7Sopenharmony_ci return v0 + (v1-v0)*x + (v2-v0)*y; 127e5c31af7Sopenharmony_ci} 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ciinline float interpolateFragment (const tcu::Vec4& quad, float x, float y) 130e5c31af7Sopenharmony_ci{ 131e5c31af7Sopenharmony_ci if (x + y < 1.0f) 132e5c31af7Sopenharmony_ci return interpolateTri(quad.x(), quad.y(), quad.z(), x, y); 133e5c31af7Sopenharmony_ci else 134e5c31af7Sopenharmony_ci return interpolateTri(quad.w(), quad.z(), quad.y(), 1.0f-x, 1.0f-y); 135e5c31af7Sopenharmony_ci} 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_citemplate <int Stride> 138e5c31af7Sopenharmony_civoid interpolateVertexInput (StridedValueAccess<Stride> dst, int dstComp, const ConstValueRangeAccess valueRange, float x, float y) 139e5c31af7Sopenharmony_ci{ 140e5c31af7Sopenharmony_ci TCU_CHECK(valueRange.getType().getBaseType() == VariableType::TYPE_FLOAT); 141e5c31af7Sopenharmony_ci int numElements = valueRange.getType().getNumElements(); 142e5c31af7Sopenharmony_ci for (int elementNdx = 0; elementNdx < numElements; elementNdx++) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci float xd, yd; 145e5c31af7Sopenharmony_ci getVertexInterpolationCoords(xd, yd, x, y, elementNdx); 146e5c31af7Sopenharmony_ci dst.component(elementNdx).asFloat(dstComp) = interpolateVertex(valueRange.getMin().component(elementNdx).asFloat(), valueRange.getMax().component(elementNdx).asFloat(), xd, yd); 147e5c31af7Sopenharmony_ci } 148e5c31af7Sopenharmony_ci} 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_citemplate <int Stride> 151e5c31af7Sopenharmony_civoid interpolateFragmentInput (StridedValueAccess<Stride> dst, int dstComp, ConstValueAccess vtx0, ConstValueAccess vtx1, ConstValueAccess vtx2, ConstValueAccess vtx3, float x, float y) 152e5c31af7Sopenharmony_ci{ 153e5c31af7Sopenharmony_ci TCU_CHECK(dst.getType().getBaseType() == VariableType::TYPE_FLOAT); 154e5c31af7Sopenharmony_ci int numElements = dst.getType().getNumElements(); 155e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numElements; ndx++) 156e5c31af7Sopenharmony_ci dst.component(ndx).asFloat(dstComp) = interpolateFragment(tcu::Vec4(vtx0.component(ndx).asFloat(), vtx1.component(ndx).asFloat(), vtx2.component(ndx).asFloat(), vtx3.component(ndx).asFloat()), x, y); 157e5c31af7Sopenharmony_ci} 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_citemplate <int Stride> 160e5c31af7Sopenharmony_civoid copyVarying (ValueAccess dst, ConstStridedValueAccess<Stride> src, int compNdx) 161e5c31af7Sopenharmony_ci{ 162e5c31af7Sopenharmony_ci TCU_CHECK(dst.getType().getBaseType() == VariableType::TYPE_FLOAT); 163e5c31af7Sopenharmony_ci for (int elemNdx = 0; elemNdx < dst.getType().getNumElements(); elemNdx++) 164e5c31af7Sopenharmony_ci dst.component(elemNdx).asFloat() = src.component(elemNdx).asFloat(compNdx); 165e5c31af7Sopenharmony_ci} 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ciProgramExecutor::ProgramExecutor (const tcu::PixelBufferAccess& dst, int gridWidth, int gridHeight) 168e5c31af7Sopenharmony_ci : m_dst (dst) 169e5c31af7Sopenharmony_ci , m_gridWidth (gridWidth) 170e5c31af7Sopenharmony_ci , m_gridHeight (gridHeight) 171e5c31af7Sopenharmony_ci{ 172e5c31af7Sopenharmony_ci} 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ciProgramExecutor::~ProgramExecutor (void) 175e5c31af7Sopenharmony_ci{ 176e5c31af7Sopenharmony_ci} 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_civoid ProgramExecutor::setTexture (int samplerNdx, const tcu::Texture2D* texture, const tcu::Sampler& sampler) 179e5c31af7Sopenharmony_ci{ 180e5c31af7Sopenharmony_ci m_samplers2D[samplerNdx] = Sampler2D(texture, sampler); 181e5c31af7Sopenharmony_ci} 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_civoid ProgramExecutor::setTexture (int samplerNdx, const tcu::TextureCube* texture, const tcu::Sampler& sampler) 184e5c31af7Sopenharmony_ci{ 185e5c31af7Sopenharmony_ci m_samplersCube[samplerNdx] = SamplerCube(texture, sampler); 186e5c31af7Sopenharmony_ci} 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ciinline tcu::IVec4 computeVertexIndices (float cellWidth, float cellHeight, int gridVtxWidth, int gridVtxHeight, int x, int y) 189e5c31af7Sopenharmony_ci{ 190e5c31af7Sopenharmony_ci DE_UNREF(gridVtxHeight); 191e5c31af7Sopenharmony_ci int x0 = (int)deFloatFloor((float)x / cellWidth); 192e5c31af7Sopenharmony_ci int y0 = (int)deFloatFloor((float)y / cellHeight); 193e5c31af7Sopenharmony_ci return tcu::IVec4(y0*gridVtxWidth + x0, y0*gridVtxWidth + x0 + 1, (y0+1)*gridVtxWidth + x0, (y0+1)*gridVtxWidth + x0 + 1); 194e5c31af7Sopenharmony_ci} 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ciinline tcu::Vec2 computeGridCellWeights (float cellWidth, float cellHeight, int x, int y) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci float gx = ((float)x + 0.5f) / cellWidth; 199e5c31af7Sopenharmony_ci float gy = ((float)y + 0.5f) / cellHeight; 200e5c31af7Sopenharmony_ci return tcu::Vec2(deFloatFrac(gx), deFloatFrac(gy)); 201e5c31af7Sopenharmony_ci} 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ciinline tcu::RGBA toColor (tcu::Vec4 rgba) 204e5c31af7Sopenharmony_ci{ 205e5c31af7Sopenharmony_ci return tcu::RGBA(deClamp32(deRoundFloatToInt32(rgba.x()*255), 0, 255), 206e5c31af7Sopenharmony_ci deClamp32(deRoundFloatToInt32(rgba.y()*255), 0, 255), 207e5c31af7Sopenharmony_ci deClamp32(deRoundFloatToInt32(rgba.z()*255), 0, 255), 208e5c31af7Sopenharmony_ci deClamp32(deRoundFloatToInt32(rgba.w()*255), 0, 255)); 209e5c31af7Sopenharmony_ci} 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_civoid ProgramExecutor::execute (const Shader& vertexShader, const Shader& fragmentShader, const vector<VariableValue>& uniformValues) 212e5c31af7Sopenharmony_ci{ 213e5c31af7Sopenharmony_ci int gridVtxWidth = m_gridWidth+1; 214e5c31af7Sopenharmony_ci int gridVtxHeight = m_gridHeight+1; 215e5c31af7Sopenharmony_ci int numVertices = gridVtxWidth*gridVtxHeight; 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_ci VaryingStore varyingStore(numVertices); 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci // Execute vertex shader 220e5c31af7Sopenharmony_ci { 221e5c31af7Sopenharmony_ci ExecutionContext execCtx(m_samplers2D, m_samplersCube); 222e5c31af7Sopenharmony_ci int numPackets = numVertices + ((numVertices%EXEC_VEC_WIDTH) ? 1 : 0); 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_ci const vector<ShaderInput*>& inputs = vertexShader.getInputs(); 225e5c31af7Sopenharmony_ci vector<const Variable*> outputs; 226e5c31af7Sopenharmony_ci vertexShader.getOutputs(outputs); 227e5c31af7Sopenharmony_ci 228e5c31af7Sopenharmony_ci // Set uniform values 229e5c31af7Sopenharmony_ci for (vector<VariableValue>::const_iterator uniformIter = uniformValues.begin(); uniformIter != uniformValues.end(); uniformIter++) 230e5c31af7Sopenharmony_ci execCtx.getValue(uniformIter->getVariable()) = uniformIter->getValue().value(); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 233e5c31af7Sopenharmony_ci { 234e5c31af7Sopenharmony_ci int packetStart = packetNdx*EXEC_VEC_WIDTH; 235e5c31af7Sopenharmony_ci int packetEnd = deMin32((packetNdx+1)*EXEC_VEC_WIDTH, numVertices); 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci // Compute values for vertex shader inputs 238e5c31af7Sopenharmony_ci for (vector<ShaderInput*>::const_iterator i = inputs.begin(); i != inputs.end(); i++) 239e5c31af7Sopenharmony_ci { 240e5c31af7Sopenharmony_ci const ShaderInput* input = *i; 241e5c31af7Sopenharmony_ci ExecValueAccess access = execCtx.getValue(input->getVariable()); 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci for (int vtxNdx = packetStart; vtxNdx < packetEnd; vtxNdx++) 244e5c31af7Sopenharmony_ci { 245e5c31af7Sopenharmony_ci int y = (vtxNdx/gridVtxWidth); 246e5c31af7Sopenharmony_ci int x = vtxNdx - y*gridVtxWidth; 247e5c31af7Sopenharmony_ci float xf = (float)x / (float)(gridVtxWidth-1); 248e5c31af7Sopenharmony_ci float yf = (float)y / (float)(gridVtxHeight-1); 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci interpolateVertexInput(access, vtxNdx-packetStart, input->getValueRange(), xf, yf); 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci } 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ci // Execute vertex shader for packet 255e5c31af7Sopenharmony_ci vertexShader.execute(execCtx); 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci // Store output values 258e5c31af7Sopenharmony_ci for (vector<const Variable*>::const_iterator i = outputs.begin(); i != outputs.end(); i++) 259e5c31af7Sopenharmony_ci { 260e5c31af7Sopenharmony_ci const Variable* output = *i; 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ci if (deStringEqual(output->getName(), "gl_Position")) 263e5c31af7Sopenharmony_ci continue; // Do not store position 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_ci ExecConstValueAccess access = execCtx.getValue(output); 266e5c31af7Sopenharmony_ci VaryingStorage* dst = varyingStore.getStorage(output->getType(), output->getName()); 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci for (int vtxNdx = packetStart; vtxNdx < packetEnd; vtxNdx++) 269e5c31af7Sopenharmony_ci { 270e5c31af7Sopenharmony_ci ValueAccess varyingAccess = dst->getValue(output->getType(), vtxNdx); 271e5c31af7Sopenharmony_ci copyVarying(varyingAccess, access, vtxNdx-packetStart); 272e5c31af7Sopenharmony_ci } 273e5c31af7Sopenharmony_ci } 274e5c31af7Sopenharmony_ci } 275e5c31af7Sopenharmony_ci } 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_ci // Execute fragment shader 278e5c31af7Sopenharmony_ci { 279e5c31af7Sopenharmony_ci ExecutionContext execCtx(m_samplers2D, m_samplersCube); 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_ci // Assign uniform values 282e5c31af7Sopenharmony_ci for (vector<VariableValue>::const_iterator i = uniformValues.begin(); i != uniformValues.end(); i++) 283e5c31af7Sopenharmony_ci execCtx.getValue(i->getVariable()) = i->getValue().value(); 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ci const vector<ShaderInput*>& inputs = fragmentShader.getInputs(); 286e5c31af7Sopenharmony_ci const Variable* fragColorVar = DE_NULL; 287e5c31af7Sopenharmony_ci vector<const Variable*> outputs; 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci // Find fragment shader output assigned to location 0. This is fragment color. 290e5c31af7Sopenharmony_ci fragmentShader.getOutputs(outputs); 291e5c31af7Sopenharmony_ci for (vector<const Variable*>::const_iterator i = outputs.begin(); i != outputs.end(); i++) 292e5c31af7Sopenharmony_ci { 293e5c31af7Sopenharmony_ci if ((*i)->getLayoutLocation() == 0) 294e5c31af7Sopenharmony_ci { 295e5c31af7Sopenharmony_ci fragColorVar = *i; 296e5c31af7Sopenharmony_ci break; 297e5c31af7Sopenharmony_ci } 298e5c31af7Sopenharmony_ci } 299e5c31af7Sopenharmony_ci TCU_CHECK(fragColorVar); 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci int width = m_dst.getWidth(); 302e5c31af7Sopenharmony_ci int height = m_dst.getHeight(); 303e5c31af7Sopenharmony_ci int numPackets = (width*height)/EXEC_VEC_WIDTH + (((width*height)%EXEC_VEC_WIDTH) ? 1 : 0); 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ci float cellWidth = (float)width / (float)m_gridWidth; 306e5c31af7Sopenharmony_ci float cellHeight = (float)height / (float)m_gridHeight; 307e5c31af7Sopenharmony_ci 308e5c31af7Sopenharmony_ci for (int packetNdx = 0; packetNdx < numPackets; packetNdx++) 309e5c31af7Sopenharmony_ci { 310e5c31af7Sopenharmony_ci int packetStart = packetNdx*EXEC_VEC_WIDTH; 311e5c31af7Sopenharmony_ci int packetEnd = deMin32((packetNdx+1)*EXEC_VEC_WIDTH, width*height); 312e5c31af7Sopenharmony_ci 313e5c31af7Sopenharmony_ci // Interpolate varyings 314e5c31af7Sopenharmony_ci for (vector<ShaderInput*>::const_iterator i = inputs.begin(); i != inputs.end(); i++) 315e5c31af7Sopenharmony_ci { 316e5c31af7Sopenharmony_ci const ShaderInput* input = *i; 317e5c31af7Sopenharmony_ci ExecValueAccess access = execCtx.getValue(input->getVariable()); 318e5c31af7Sopenharmony_ci const VariableType& type = input->getVariable()->getType(); 319e5c31af7Sopenharmony_ci const VaryingStorage* src = varyingStore.getStorage(type, input->getVariable()->getName()); 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci // \todo [2011-03-08 pyry] Part of this could be pre-computed... 322e5c31af7Sopenharmony_ci for (int fragNdx = packetStart; fragNdx < packetEnd; fragNdx++) 323e5c31af7Sopenharmony_ci { 324e5c31af7Sopenharmony_ci int y = fragNdx/width; 325e5c31af7Sopenharmony_ci int x = fragNdx - y*width; 326e5c31af7Sopenharmony_ci tcu::IVec4 vtxIndices = computeVertexIndices(cellWidth, cellHeight, gridVtxWidth, gridVtxHeight, x, y); 327e5c31af7Sopenharmony_ci tcu::Vec2 weights = computeGridCellWeights(cellWidth, cellHeight, x, y); 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci interpolateFragmentInput(access, fragNdx-packetStart, 330e5c31af7Sopenharmony_ci src->getValue(type, vtxIndices.x()), 331e5c31af7Sopenharmony_ci src->getValue(type, vtxIndices.y()), 332e5c31af7Sopenharmony_ci src->getValue(type, vtxIndices.z()), 333e5c31af7Sopenharmony_ci src->getValue(type, vtxIndices.w()), 334e5c31af7Sopenharmony_ci weights.x(), weights.y()); 335e5c31af7Sopenharmony_ci } 336e5c31af7Sopenharmony_ci } 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ci // Execute fragment shader 339e5c31af7Sopenharmony_ci fragmentShader.execute(execCtx); 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci // Write resulting color 342e5c31af7Sopenharmony_ci ExecConstValueAccess colorValue = execCtx.getValue(fragColorVar); 343e5c31af7Sopenharmony_ci for (int fragNdx = packetStart; fragNdx < packetEnd; fragNdx++) 344e5c31af7Sopenharmony_ci { 345e5c31af7Sopenharmony_ci int y = fragNdx/width; 346e5c31af7Sopenharmony_ci int x = fragNdx - y*width; 347e5c31af7Sopenharmony_ci int cNdx = fragNdx-packetStart; 348e5c31af7Sopenharmony_ci tcu::Vec4 c = tcu::Vec4(colorValue.component(0).asFloat(cNdx), 349e5c31af7Sopenharmony_ci colorValue.component(1).asFloat(cNdx), 350e5c31af7Sopenharmony_ci colorValue.component(2).asFloat(cNdx), 351e5c31af7Sopenharmony_ci colorValue.component(3).asFloat(cNdx)); 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci // \todo [2012-11-13 pyry] Reverse order. 354e5c31af7Sopenharmony_ci m_dst.setPixel(c, x, m_dst.getHeight()-y-1); 355e5c31af7Sopenharmony_ci } 356e5c31af7Sopenharmony_ci } 357e5c31af7Sopenharmony_ci } 358e5c31af7Sopenharmony_ci} 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci} // rsg 361