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 
MultisamplePixelBufferAccess(const tcu::PixelBufferAccess & rawAccess)30 MultisamplePixelBufferAccess::MultisamplePixelBufferAccess (const tcu::PixelBufferAccess& rawAccess)
31 	: m_access(rawAccess)
32 {
33 }
34 
MultisamplePixelBufferAccess(void)35 MultisamplePixelBufferAccess::MultisamplePixelBufferAccess (void)
36 	: m_access(tcu::PixelBufferAccess())
37 {
38 }
39 
toSinglesampleAccess(void) const40 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 
fromSinglesampleAccess(const tcu::PixelBufferAccess & original)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 
fromMultisampleAccess(const tcu::PixelBufferAccess & multisampledAccess)60 MultisamplePixelBufferAccess MultisamplePixelBufferAccess::fromMultisampleAccess (const tcu::PixelBufferAccess& multisampledAccess)
61 {
62 	return MultisamplePixelBufferAccess(multisampledAccess);
63 }
64 
MultisampleConstPixelBufferAccess(void)65 MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (void)
66 	: m_access(tcu::ConstPixelBufferAccess())
67 {
68 }
69 
MultisampleConstPixelBufferAccess(const tcu::ConstPixelBufferAccess & rawAccess)70 MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (const tcu::ConstPixelBufferAccess& rawAccess)
71 	: m_access(rawAccess)
72 {
73 }
74 
MultisampleConstPixelBufferAccess(const rr::MultisamplePixelBufferAccess & msAccess)75 MultisampleConstPixelBufferAccess::MultisampleConstPixelBufferAccess (const rr::MultisamplePixelBufferAccess& msAccess)
76 	: m_access(msAccess.raw())
77 {
78 }
79 
toSinglesampleAccess(void) const80 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 
fromSinglesampleAccess(const tcu::ConstPixelBufferAccess & original)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 
fromMultisampleAccess(const tcu::ConstPixelBufferAccess & multisampledAccess)100 MultisampleConstPixelBufferAccess MultisampleConstPixelBufferAccess::fromMultisampleAccess (const tcu::ConstPixelBufferAccess& multisampledAccess)
101 {
102 	return MultisampleConstPixelBufferAccess(multisampledAccess);
103 }
104 
getSubregion(const MultisamplePixelBufferAccess & access,int x,int y,int width,int height)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 
getSubregion(const MultisampleConstPixelBufferAccess & access,int x,int y,int width,int height)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 
resolveMultisampleColorBuffer(const tcu::PixelBufferAccess & dst,const MultisampleConstPixelBufferAccess & src)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 
resolveMultisampleDepthBuffer(const tcu::PixelBufferAccess & dst,const MultisampleConstPixelBufferAccess & src)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 
resolveMultisampleStencilBuffer(const tcu::PixelBufferAccess & dst,const MultisampleConstPixelBufferAccess & src)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 
resolveMultisampleBuffer(const tcu::PixelBufferAccess & dst,const MultisampleConstPixelBufferAccess & src)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 
resolveMultisamplePixel(const MultisampleConstPixelBufferAccess & access,int x,int y)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 
clear(const MultisamplePixelBufferAccess & access,const tcu::Vec4 & color)224 void clear (const MultisamplePixelBufferAccess& access, const tcu::Vec4& color)
225 {
226 	tcu::clear(access.raw(), color);
227 }
228 
clear(const MultisamplePixelBufferAccess & access,const tcu::IVec4 & color)229 void clear (const MultisamplePixelBufferAccess& access, const tcu::IVec4& color)
230 {
231 	tcu::clear(access.raw(), color);
232 }
233 
clearDepth(const MultisamplePixelBufferAccess & access,float depth)234 void clearDepth (const MultisamplePixelBufferAccess& access, float depth)
235 {
236 	tcu::clearDepth(access.raw(), depth);
237 }
238 
clearStencil(const MultisamplePixelBufferAccess & access,int stencil)239 void clearStencil (const MultisamplePixelBufferAccess& access, int stencil)
240 {
241 	tcu::clearStencil(access.raw(), stencil);
242 }
243 
244 } // rr
245