Home | History | Annotate | Download | only in referencerenderer
      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