mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Implement 3D textures for D3D9 as well
This commit is contained in:
parent
0262fbc70a
commit
f87b4cf232
@ -208,6 +208,9 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
if (enableFog) {
|
||||
WRITE(p, "float3 u_fogcolor : register(c%i);\n", CONST_PS_FOGCOLOR);
|
||||
}
|
||||
if (texture3D) {
|
||||
WRITE(p, "float u_mipBias : register(c%i);\n", CONST_PS_MIPBIAS);
|
||||
}
|
||||
} else {
|
||||
WRITE(p, "SamplerState samp : register(s0);\n");
|
||||
if (texture3D) {
|
||||
@ -565,10 +568,18 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
|
||||
}
|
||||
}
|
||||
} else if (compat.shaderLanguage == HLSL_D3D9) {
|
||||
if (doTextureProjection) {
|
||||
WRITE(p, " vec4 t = tex2Dproj(tex, vec4(v_texcoord.x, v_texcoord.y, 0, v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : "");
|
||||
if (texture3D) {
|
||||
if (doTextureProjection) {
|
||||
WRITE(p, " vec4 t = tex3Dproj(tex, vec4(v_texcoord.x, v_texcoord.y, u_mipBias, v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : "");
|
||||
} else {
|
||||
WRITE(p, " vec4 t = tex3D(tex, vec3(%s.x, %s.y, u_mipBias))%s;\n", texcoord, texcoord, bgraTexture ? ".bgra" : "");
|
||||
}
|
||||
} else {
|
||||
WRITE(p, " vec4 t = tex2D(tex, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : "");
|
||||
if (doTextureProjection) {
|
||||
WRITE(p, " vec4 t = tex2Dproj(tex, vec3(v_texcoord.x, v_texcoord.y, v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : "");
|
||||
} else {
|
||||
WRITE(p, " vec4 t = tex2D(tex, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : "");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Note that here we're relying on the filter to be linear. We would have to otherwise to do two samples and manually filter in Z.
|
||||
|
@ -34,8 +34,9 @@ struct FShaderID;
|
||||
#define CONST_PS_FBOTEXSIZE 7
|
||||
#define CONST_PS_TEXCLAMP 8
|
||||
#define CONST_PS_TEXCLAMPOFF 9
|
||||
#define CONST_PS_MIPBIAS 10
|
||||
|
||||
// For stencil upload
|
||||
#define CONST_PS_STENCILVALUE 10
|
||||
#define CONST_PS_STENCILVALUE 11
|
||||
|
||||
bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLanguageDesc &compat, Draw::Bugs bugs, uint64_t *uniformMask, std::string *errorString);
|
||||
|
@ -314,6 +314,11 @@ void ShaderManagerDX9::PSUpdateUniforms(u64 dirtyUniforms) {
|
||||
};
|
||||
PSSetFloatArray(CONST_PS_TEXCLAMP, texclamp, 4);
|
||||
PSSetFloatArray(CONST_PS_TEXCLAMPOFF, texclampoff, 2);
|
||||
|
||||
float mipBias = (float)gstate.getTexLevelOffset16() * (1.0 / 16.0f);
|
||||
mipBias = (mipBias + 0.5f) / (float)(gstate.getTextureMaxLevel() + 1);
|
||||
|
||||
PSSetFloatArray(CONST_PS_MIPBIAS, &mipBias, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ void TextureCacheDX9::SetFramebufferManager(FramebufferManagerDX9 *fbManager) {
|
||||
}
|
||||
|
||||
void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
|
||||
LPDIRECT3DTEXTURE9 &texture = DxTex(entry);
|
||||
LPDIRECT3DBASETEXTURE9 &texture = DxTex(entry);
|
||||
if (texture) {
|
||||
texture->Release();
|
||||
texture = nullptr;
|
||||
@ -205,7 +205,7 @@ void TextureCacheDX9::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase
|
||||
}
|
||||
|
||||
void TextureCacheDX9::BindTexture(TexCacheEntry *entry) {
|
||||
LPDIRECT3DTEXTURE9 texture = DxTex(entry);
|
||||
LPDIRECT3DBASETEXTURE9 texture = DxTex(entry);
|
||||
if (texture != lastBoundTexture) {
|
||||
device_->SetTexture(0, texture);
|
||||
lastBoundTexture = texture;
|
||||
@ -425,10 +425,20 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
|
||||
// We don't yet have mip generation, so clamp the number of levels to the ones we can load directly.
|
||||
int levels = std::min(plan.levelsToCreate, plan.levelsToLoad);
|
||||
|
||||
LPDIRECT3DTEXTURE9 &texture = DxTex(entry);
|
||||
LPDIRECT3DBASETEXTURE9 &texture = DxTex(entry);
|
||||
D3DPOOL pool = D3DPOOL_DEFAULT;
|
||||
int usage = D3DUSAGE_DYNAMIC;
|
||||
HRESULT hr = device_->CreateTexture(tw, th, levels, usage, dstFmt, pool, &texture, NULL);
|
||||
|
||||
HRESULT hr;
|
||||
if (plan.depth == 1) {
|
||||
LPDIRECT3DTEXTURE9 tex;
|
||||
hr = device_->CreateTexture(tw, th, levels, usage, dstFmt, pool, &tex, nullptr);
|
||||
texture = tex;
|
||||
} else {
|
||||
LPDIRECT3DVOLUMETEXTURE9 tex;
|
||||
hr = device_->CreateVolumeTexture(tw, th, plan.depth, 1, usage, dstFmt, pool, &tex, nullptr);
|
||||
texture = tex;
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
INFO_LOG(G3D, "Failed to create D3D texture: %dx%d", tw, th);
|
||||
@ -443,24 +453,45 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) {
|
||||
|
||||
Draw::DataFormat texFmt = FromD3D9Format(dstFmt);
|
||||
|
||||
// Mipmapping is only enabled when texture scaling is disabled.
|
||||
for (int i = 0; i < levels; i++) {
|
||||
int dstLevel = i;
|
||||
HRESULT result;
|
||||
uint32_t lockFlag = dstLevel == 0 ? D3DLOCK_DISCARD : 0; // Can only discard the top level
|
||||
D3DLOCKED_RECT rect{};
|
||||
result = texture->LockRect(dstLevel, &rect, NULL, lockFlag);
|
||||
if (plan.depth == 1) {
|
||||
// Regular loop.
|
||||
for (int i = 0; i < levels; i++) {
|
||||
int dstLevel = i;
|
||||
HRESULT result;
|
||||
uint32_t lockFlag = dstLevel == 0 ? D3DLOCK_DISCARD : 0; // Can only discard the top level
|
||||
D3DLOCKED_RECT rect{};
|
||||
|
||||
result = ((LPDIRECT3DTEXTURE9)texture)->LockRect(dstLevel, &rect, NULL, lockFlag);
|
||||
if (FAILED(result)) {
|
||||
ERROR_LOG(G3D, "Failed to lock D3D 2D texture at level %d: %dx%d", i, plan.w, plan.h);
|
||||
return;
|
||||
}
|
||||
uint8_t *data = (uint8_t *)rect.pBits;
|
||||
int stride = rect.Pitch;
|
||||
LoadTextureLevel(*entry, data, stride, *plan.replaced, (i == 0) ? plan.baseLevelSrc : i, plan.scaleFactor, texFmt, false);
|
||||
((LPDIRECT3DTEXTURE9)texture)->UnlockRect(dstLevel);
|
||||
}
|
||||
} else {
|
||||
// 3D loop.
|
||||
D3DLOCKED_BOX box;
|
||||
HRESULT result = ((LPDIRECT3DVOLUMETEXTURE9)texture)->LockBox(0, &box, nullptr, D3DLOCK_DISCARD);
|
||||
if (FAILED(result)) {
|
||||
ERROR_LOG(G3D, "Failed to lock D3D texture at level %d: %dx%d", i, plan.w, plan.h);
|
||||
ERROR_LOG(G3D, "Failed to lock D3D 2D texture: %dx%dx%d", plan.w, plan.h, plan.depth);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *data = (uint8_t *)rect.pBits;
|
||||
int stride = rect.Pitch;
|
||||
uint8_t *data = (uint8_t *)box.pBits;
|
||||
int stride = box.RowPitch;
|
||||
for (int i = 0; i < plan.depth; i++) {
|
||||
LoadTextureLevel(*entry, data, stride, *plan.replaced, (i == 0) ? plan.baseLevelSrc : i, plan.scaleFactor, texFmt, false);
|
||||
data += box.SlicePitch;
|
||||
}
|
||||
((LPDIRECT3DVOLUMETEXTURE9)texture)->UnlockBox(0);
|
||||
}
|
||||
|
||||
LoadTextureLevel(*entry, data, stride, *plan.replaced, (i == 0) ? plan.baseLevelSrc : i, plan.scaleFactor, texFmt, false);
|
||||
|
||||
texture->UnlockRect(dstLevel);
|
||||
// Signal that we support depth textures so use it as one.
|
||||
if (plan.depth > 1) {
|
||||
entry->status |= TexCacheEntry::STATUS_3D;
|
||||
}
|
||||
|
||||
if (plan.replaced->Valid()) {
|
||||
|
@ -68,8 +68,8 @@ private:
|
||||
void ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) override;
|
||||
void BuildTexture(TexCacheEntry *const entry) override;
|
||||
|
||||
LPDIRECT3DTEXTURE9 &DxTex(TexCacheEntry *entry) {
|
||||
return *(LPDIRECT3DTEXTURE9 *)&entry->texturePtr;
|
||||
LPDIRECT3DBASETEXTURE9 &DxTex(TexCacheEntry *entry) {
|
||||
return *(LPDIRECT3DBASETEXTURE9 *)&entry->texturePtr;
|
||||
}
|
||||
|
||||
LPDIRECT3DDEVICE9 device_;
|
||||
@ -77,7 +77,7 @@ private:
|
||||
|
||||
LPDIRECT3DVERTEXDECLARATION9 pFramebufferVertexDecl;
|
||||
|
||||
LPDIRECT3DTEXTURE9 lastBoundTexture;
|
||||
LPDIRECT3DBASETEXTURE9 lastBoundTexture;
|
||||
float maxAnisotropyLevel;
|
||||
|
||||
FramebufferManagerDX9 *framebufferManagerDX9_;
|
||||
|
Loading…
Reference in New Issue
Block a user