1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program Reference Renderer 3 * ----------------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Multisampled pixel buffer access 22 *//*--------------------------------------------------------------------*/ 23 24 #include "rrMultisamplePixelBufferAccess.hpp" 25 #include "tcuTextureUtil.hpp" 26 27 namespace rr 28 { 29 30 MultisamplePixelBufferAccess::MultisamplePixelBufferAccess (const tcu::PixelBufferAccess& rawAccess) 31 : m_access(rawAccess) 32 { 33 } 34 35 MultisamplePixelBufferAccess::MultisamplePixelBufferAccess (void) 36 : m_access(tcu::PixelBufferAccess()) 37 { 38 } 39 40 const tcu::PixelBufferAccess MultisamplePixelBufferAccess::toSinglesampleAccess (void) const 41 { 42 DE_ASSERT(getNumSamples() == 1); 43 44 return tcu::PixelBufferAccess(m_access.getFormat(), 45 tcu::IVec3(m_access.getHeight(), m_access.getDepth(), 1), 46 tcu::IVec3(m_access.getRowPitch(), m_access.getSlicePitch(), m_access.getSlicePitch() * m_access.getDepth()), 47 m_access.getDataPtr()); 48 } 49 50 MultisamplePixelBufferAccess MultisamplePixelBufferAccess::fromSinglesampleAccess (const tcu::PixelBufferAccess& original) 51 { 52 return MultisamplePixelBufferAccess( 53 tcu::PixelBufferAccess( 54 original.getFormat(), 55 tcu::IVec3(1, original.getWidth(), original.getHeight()), 56 tcu::IVec3(original.getPixelPitch(), original.getPixelPitch(), original.getRowPitch()), 57 original.getDataPtr())); 58 } 59 60 MultisamplePixelBufferAccess MultisamplePixelBufferAccess::fromMultisampleAccess (const tcu::PixelBufferAccess& multisampledAccess) 61 { 62 return MultisamplePixelBufferAccess(multisampledAccess); 63 } 64 65 MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (void) 66 : m_access(tcu::ConstPixelBufferAccess()) 67 { 68 } 69 70 MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (const tcu::ConstPixelBufferAccess& rawAccess) 71 : m_access(rawAccess) 72 { 73 } 74 75 MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (const rr::MultisamplePixelBufferAccess& msAccess) 76 : m_access(msAccess.raw()) 77 { 78 } 79 80 const tcu::ConstPixelBufferAccess MultisampleConstPixelBufferAccess::toSinglesampleAccess (void) const 81 { 82 DE_ASSERT(getNumSamples() == 1); 83 84 return tcu::ConstPixelBufferAccess(m_access.getFormat(), 85 tcu::IVec3(m_access.getHeight(), m_access.getDepth(), 1), 86 tcu::IVec3(m_access.getRowPitch(), m_access.getSlicePitch(), m_access.getSlicePitch() * m_access.getDepth()), 87 m_access.getDataPtr()); 88 } 89 90 MultisampleConstPixelBufferAccess MultisampleConstPixelBufferAccess::fromSinglesampleAccess (const tcu::ConstPixelBufferAccess& original) 91 { 92 return MultisampleConstPixelBufferAccess( 93 tcu::ConstPixelBufferAccess( 94 original.getFormat(), 95 tcu::IVec3(1, original.getWidth(), original.getHeight()), 96 tcu::IVec3(original.getPixelPitch(), original.getPixelPitch(), original.getRowPitch()), 97 original.getDataPtr())); 98 } 99 100 MultisampleConstPixelBufferAccess MultisampleConstPixelBufferAccess::fromMultisampleAccess (const tcu::ConstPixelBufferAccess& multisampledAccess) 101 { 102 return MultisampleConstPixelBufferAccess(multisampledAccess); 103 } 104 105 MultisamplePixelBufferAccess getSubregion (const MultisamplePixelBufferAccess& access, int x, int y, int width, int height) 106 { 107 return MultisamplePixelBufferAccess::fromMultisampleAccess(tcu::getSubregion(access.raw(), 0, x, y, access.getNumSamples(), width, height)); 108 } 109 110 MultisampleConstPixelBufferAccess getSubregion (const MultisampleConstPixelBufferAccess& access, int x, int y, int width, int height) 111 { 112 return MultisampleConstPixelBufferAccess::fromMultisampleAccess(tcu::getSubregion(access.raw(), 0, x, y, access.getNumSamples(), width, height)); 113 } 114 115 void resolveMultisampleColorBuffer (const tcu::PixelBufferAccess& dst, const MultisampleConstPixelBufferAccess& src) 116 { 117 DE_ASSERT(dst.getWidth() == src.raw().getHeight()); 118 DE_ASSERT(dst.getHeight() == src.raw().getDepth()); 119 120 if (src.getNumSamples() == 1) 121 { 122 // fast-path for non-multisampled cases 123 tcu::copy(dst, src.toSinglesampleAccess()); 124 } 125 else 126 { 127 const float numSamplesInv = 1.0f / (float)src.getNumSamples(); 128 129 for (int y = 0; y < dst.getHeight(); y++) 130 for (int x = 0; x < dst.getWidth(); x++) 131 { 132 tcu::Vec4 sum; 133 for (int s = 0; s < src.raw().getWidth(); s++) 134 sum += src.raw().getPixel(s, x, y); 135 136 dst.setPixel(sum*numSamplesInv, x, y); 137 } 138 } 139 } 140 141 void resolveMultisampleDepthBuffer (const tcu::PixelBufferAccess& dst, const MultisampleConstPixelBufferAccess& src) 142 { 143 DE_ASSERT(dst.getWidth() == src.raw().getHeight()); 144 DE_ASSERT(dst.getHeight() == src.raw().getDepth()); 145 146 const tcu::ConstPixelBufferAccess effectiveSrc = tcu::getEffectiveDepthStencilAccess(src.raw(), tcu::Sampler::MODE_DEPTH); 147 const tcu::PixelBufferAccess effectiveDst = tcu::getEffectiveDepthStencilAccess(dst, tcu::Sampler::MODE_DEPTH); 148 149 if (src.getNumSamples() == 1) 150 { 151 // fast-path for non-multisampled cases 152 tcu::copy(effectiveDst, MultisampleConstPixelBufferAccess::fromMultisampleAccess(effectiveSrc).toSinglesampleAccess()); 153 } 154 else 155 { 156 const float numSamplesInv = 1.0f / (float)src.getNumSamples(); 157 158 for (int y = 0; y < dst.getHeight(); y++) 159 for (int x = 0; x < dst.getWidth(); x++) 160 { 161 float sum = 0.0f; 162 for (int s = 0; s < src.getNumSamples(); s++) 163 sum += effectiveSrc.getPixDepth(s, x, y); 164 165 effectiveDst.setPixDepth(sum*numSamplesInv, x, y); 166 } 167 } 168 } 169 170 void resolveMultisampleStencilBuffer (const tcu::PixelBufferAccess& dst, const MultisampleConstPixelBufferAccess& src) 171 { 172 DE_ASSERT(dst.getWidth() == src.raw().getHeight()); 173 DE_ASSERT(dst.getHeight() == src.raw().getDepth()); 174 175 const tcu::ConstPixelBufferAccess effectiveSrc = tcu::getEffectiveDepthStencilAccess(src.raw(), tcu::Sampler::MODE_STENCIL); 176 const tcu::PixelBufferAccess effectiveDst = tcu::getEffectiveDepthStencilAccess(dst, tcu::Sampler::MODE_STENCIL); 177 178 if (src.getNumSamples() == 1) 179 { 180 // fast-path for non-multisampled cases 181 tcu::copy(effectiveDst, MultisampleConstPixelBufferAccess::fromMultisampleAccess(effectiveSrc).toSinglesampleAccess()); 182 } 183 else 184 { 185 // Resolve by selecting one 186 for (int y = 0; y < dst.getHeight(); y++) 187 for (int x = 0; x < dst.getWidth(); x++) 188 effectiveDst.setPixStencil(effectiveSrc.getPixStencil(0, x, y), x, y); 189 } 190 } 191 192 void resolveMultisampleBuffer (const tcu::PixelBufferAccess& dst, const MultisampleConstPixelBufferAccess& src) 193 { 194 switch (src.raw().getFormat().order) 195 { 196 case tcu::TextureFormat::D: 197 resolveMultisampleDepthBuffer(dst, src); 198 return; 199 200 case tcu::TextureFormat::S: 201 resolveMultisampleStencilBuffer(dst, src); 202 return; 203 204 case tcu::TextureFormat::DS: 205 resolveMultisampleDepthBuffer(dst, src); 206 resolveMultisampleStencilBuffer(dst, src); 207 return; 208 209 default: 210 resolveMultisampleColorBuffer(dst, src); 211 return; 212 } 213 } 214 215 tcu::Vec4 resolveMultisamplePixel (const MultisampleConstPixelBufferAccess& access, int x, int y) 216 { 217 tcu::Vec4 sum; 218 for (int s = 0; s < access.getNumSamples(); s++) 219 sum += access.raw().getPixel(s, x, y); 220 221 return sum / (float)access.getNumSamples(); 222 } 223 224 void clear (const MultisamplePixelBufferAccess& access, const tcu::Vec4& color) 225 { 226 tcu::clear(access.raw(), color); 227 } 228 229 void clear (const MultisamplePixelBufferAccess& access, const tcu::IVec4& color) 230 { 231 tcu::clear(access.raw(), color); 232 } 233 234 void clearDepth (const MultisamplePixelBufferAccess& access, float depth) 235 { 236 tcu::clearDepth(access.raw(), depth); 237 } 238 239 void clearStencil (const MultisamplePixelBufferAccess& access, int stencil) 240 { 241 tcu::clearStencil(access.raw(), stencil); 242 } 243 244 } // rr 245