1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
|
/*
* Copyright (C) 2007-2009 Gabest
* http://www.gabest.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "GSVector.h"
#include "GSDevice.h"
#include "GSAlignedClass.h"
class GSDeviceDX : public GSDevice
{
public:
#pragma pack(push, 1)
__aligned(struct, 32) VSConstantBuffer
{
GSVector4 VertexScale;
GSVector4 VertexOffset;
GSVector4 TextureScale;
struct VSConstantBuffer()
{
VertexScale = GSVector4::zero();
VertexOffset = GSVector4::zero();
TextureScale = GSVector4::zero();
}
__forceinline bool Update(const VSConstantBuffer* cb)
{
GSVector4i* a = (GSVector4i*)this;
GSVector4i* b = (GSVector4i*)cb;
GSVector4i b0 = b[0];
GSVector4i b1 = b[1];
GSVector4i b2 = b[2];
if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2)).alltrue())
{
a[0] = b0;
a[1] = b1;
a[2] = b2;
return true;
}
return false;
}
};
struct VSSelector
{
union
{
struct
{
uint32 bppz:2;
uint32 tme:1;
uint32 fst:1;
uint32 logz:1;
uint32 rtcopy:1;
};
uint32 key;
};
operator uint32() {return key & 0xff;}
VSSelector() : key(0) {}
};
__aligned(struct, 32) PSConstantBuffer
{
GSVector4 FogColor_AREF;
GSVector4 HalfTexel;
GSVector4 WH;
GSVector4 MinMax;
GSVector4 MinF_TA;
GSVector4i MskFix;
GSVector4 TC_OffsetHack;
struct PSConstantBuffer()
{
FogColor_AREF = GSVector4::zero();
HalfTexel = GSVector4::zero();
WH = GSVector4::zero();
MinMax = GSVector4::zero();
MinF_TA = GSVector4::zero();
MskFix = GSVector4i::zero();
}
__forceinline bool Update(const PSConstantBuffer* cb)
{
GSVector4i* a = (GSVector4i*)this;
GSVector4i* b = (GSVector4i*)cb;
GSVector4i b0 = b[0];
GSVector4i b1 = b[1];
GSVector4i b2 = b[2];
GSVector4i b3 = b[3];
GSVector4i b4 = b[4];
GSVector4i b5 = b[5];
if(!((a[0] == b0) /*& (a[1] == b1)*/ & (a[2] == b2) & (a[3] == b3) & (a[4] == b4) & (a[5] == b5)).alltrue()) // if WH matches HalfTexel does too
{
a[0] = b0;
a[1] = b1;
a[2] = b2;
a[3] = b3;
a[4] = b4;
a[5] = b5;
return true;
}
return false;
}
};
struct GSSelector
{
union
{
struct
{
uint32 iip:1;
uint32 prim:2;
};
uint32 key;
};
operator uint32() {return key & 0x7;}
GSSelector() : key(0) {}
};
struct PSSelector
{
union
{
struct
{
uint32 fst:1;
uint32 wms:2;
uint32 wmt:2;
uint32 fmt:3;
uint32 aem:1;
uint32 tfx:3;
uint32 tcc:1;
uint32 atst:3;
uint32 fog:1;
uint32 clr1:1;
uint32 fba:1;
uint32 aout:1;
uint32 rt:1;
uint32 ltf:1;
uint32 colclip:2;
uint32 date:2;
uint32 spritehack:1;
uint32 tcoffsethack:1;
uint32 point_sampler:1;
uint32 shuffle:1;
uint32 read_ba:1;
};
uint32 key;
};
operator uint32() {return key & 0xfffffff;}
PSSelector() : key(0) {}
};
struct PSSamplerSelector
{
union
{
struct
{
uint32 tau:1;
uint32 tav:1;
uint32 ltf:1;
};
uint32 key;
};
operator uint32() {return key & 0x7;}
PSSamplerSelector() : key(0) {}
};
struct OMDepthStencilSelector
{
union
{
struct
{
uint32 ztst:2;
uint32 zwe:1;
uint32 date:1;
uint32 fba:1;
uint32 alpha_stencil:1;
};
uint32 key;
};
operator uint32() {return key & 0x3f;}
OMDepthStencilSelector() : key(0) {}
};
struct OMBlendSelector
{
union
{
struct
{
uint32 abe:1;
uint32 a:2;
uint32 b:2;
uint32 c:2;
uint32 d:2;
uint32 wr:1;
uint32 wg:1;
uint32 wb:1;
uint32 wa:1;
uint32 negative:1;
};
struct
{
uint32 _pad:1;
uint32 abcd:8;
uint32 wrgba:4;
};
uint32 key;
};
operator uint32() {return key & 0x3fff;}
OMBlendSelector() : key(0) {}
bool IsCLR1() const
{
return (key & 0x19f) == 0x93; // abe == 1 && a == 1 && b == 2 && d == 1
}
};
struct D3D9Blend {int bogus, op, src, dst;};
static const D3D9Blend m_blendMapD3D9[3*3*3*3];
#pragma pack(pop)
protected:
struct {D3D_FEATURE_LEVEL level; string model, vs, gs, ps, cs;} m_shader;
uint32 m_msaa;
DXGI_SAMPLE_DESC m_msaa_desc;
static HMODULE s_d3d_compiler_dll;
static decltype(&D3DCompile) s_pD3DCompile;
// Older version doesn't support D3D_COMPILE_STANDARD_FILE_INCLUDE, which
// could be useful for external shaders.
static bool s_old_d3d_compiler_dll;
GSTexture* FetchSurface(int type, int w, int h, bool msaa, int format);
public:
GSDeviceDX();
virtual ~GSDeviceDX();
bool SetFeatureLevel(D3D_FEATURE_LEVEL level, bool compat_mode);
void GetFeatureLevel(D3D_FEATURE_LEVEL& level) const {level = m_shader.level;}
virtual void SetupVS(VSSelector sel, const VSConstantBuffer* cb) = 0;
virtual void SetupGS(GSSelector sel) = 0;
virtual void SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel) = 0;
virtual void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix) = 0;
virtual void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm) = 0;
virtual bool HasStencil() = 0;
virtual bool HasDepth32() = 0;
static bool LoadD3DCompiler();
static void FreeD3DCompiler();
template<class T> void PrepareShaderMacro(vector<T>& dst, const T* src)
{
dst.clear();
while(src && src->Definition && src->Name)
{
dst.push_back(*src++);
}
T m;
m.Name = "SHADER_MODEL";
m.Definition = m_shader.model.c_str();
dst.push_back(m);
m.Name = NULL;
m.Definition = NULL;
dst.push_back(m);
}
};
|