mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 17:19:28 +01:00
thin3d: Add sampler state selection.
This commit is contained in:
1 parent
0d68a172a9
commit
05fee24ccf
7 files changed
+192
-26
No files matched your search
+101
-11
@@ -42,6 +42,23 @@ static const unsigned short blendFactorToGL[] = {
|
||||
GL_CONSTANT_COLOR,
|
||||
};
|
||||
|
||||
static const unsigned short texWrapToGL[] = {
|
||||
GL_REPEAT,
|
||||
GL_CLAMP_TO_EDGE,
|
||||
};
|
||||
|
||||
static const unsigned short texFilterToGL[] = {
|
||||
GL_NEAREST,
|
||||
GL_LINEAR,
|
||||
};
|
||||
|
||||
static const unsigned short texMipFilterToGL[2][2] = {
|
||||
// Min nearest:
|
||||
{ GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR },
|
||||
// Min linear:
|
||||
{ GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR },
|
||||
};
|
||||
|
||||
#ifndef USING_GLES2
|
||||
static const unsigned short logicOpToGL[] = {
|
||||
GL_CLEAR,
|
||||
@@ -114,6 +131,32 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class Thin3DGLSamplerState : public Thin3DSamplerState {
|
||||
public:
|
||||
GLint wrapS;
|
||||
GLint wrapT;
|
||||
GLint magFilt;
|
||||
GLint minFilt;
|
||||
GLint mipMinFilt;
|
||||
|
||||
void Apply(bool hasMips, bool canWrap) {
|
||||
if (canWrap) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilt);
|
||||
if (hasMips) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipMinFilt);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilt);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Thin3DGLDepthStencilState : public Thin3DDepthStencilState {
|
||||
public:
|
||||
bool depthTestEnabled;
|
||||
@@ -307,6 +350,7 @@ public:
|
||||
|
||||
Thin3DDepthStencilState *CreateDepthStencilState(bool depthTestEnabled, bool depthWriteEnabled, T3DComparison depthCompare) override;
|
||||
Thin3DBlendState *CreateBlendState(const T3DBlendStateDesc &desc) override;
|
||||
Thin3DSamplerState *CreateSamplerState(const T3DSamplerStateDesc &desc) override;
|
||||
Thin3DBuffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
|
||||
Thin3DShaderSet *CreateShaderSet(Thin3DShader *vshader, Thin3DShader *fshader) override;
|
||||
Thin3DVertexFormat *CreateVertexFormat(const std::vector<Thin3DVertexComponent> &components, int stride, Thin3DShader *vshader) override;
|
||||
@@ -319,6 +363,28 @@ public:
|
||||
s->Apply();
|
||||
}
|
||||
|
||||
void SetSamplerStates(int start, int count, Thin3DSamplerState **states) override {
|
||||
if (samplerStates_.size() < (size_t)(start + count)) {
|
||||
samplerStates_.resize(start + count);
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int index = i + start;
|
||||
Thin3DGLSamplerState *s = static_cast<Thin3DGLSamplerState *>(states[index]);
|
||||
|
||||
if (samplerStates_[index]) {
|
||||
samplerStates_[index]->Release();
|
||||
}
|
||||
samplerStates_[index] = s;
|
||||
samplerStates_[index]->AddRef();
|
||||
|
||||
// TODO: Ideally, get these from the texture and apply on the right stage?
|
||||
if (index == 0) {
|
||||
s->Apply(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Bound state objects
|
||||
void SetDepthStencilState(Thin3DDepthStencilState *state) override {
|
||||
Thin3DGLDepthStencilState *s = static_cast<Thin3DGLDepthStencilState *>(state);
|
||||
@@ -391,6 +457,8 @@ public:
|
||||
default: return "?";
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Thin3DGLSamplerState *> samplerStates_;
|
||||
};
|
||||
|
||||
Thin3DGLContext::Thin3DGLContext() {
|
||||
@@ -398,6 +466,12 @@ Thin3DGLContext::Thin3DGLContext() {
|
||||
}
|
||||
|
||||
Thin3DGLContext::~Thin3DGLContext() {
|
||||
for (Thin3DGLSamplerState *s : samplerStates_) {
|
||||
if (s) {
|
||||
s->Release();
|
||||
}
|
||||
}
|
||||
samplerStates_.clear();
|
||||
}
|
||||
|
||||
Thin3DVertexFormat *Thin3DGLContext::CreateVertexFormat(const std::vector<Thin3DVertexComponent> &components, int stride, Thin3DShader *vshader) {
|
||||
@@ -428,6 +502,7 @@ class Thin3DGLTexture : public Thin3DTexture, GfxResourceHolder {
|
||||
public:
|
||||
Thin3DGLTexture() : tex_(0), target_(0) {
|
||||
generatedMips_ = false;
|
||||
canWrap_ = true;
|
||||
width_ = 0;
|
||||
height_ = 0;
|
||||
depth_ = 0;
|
||||
@@ -436,6 +511,7 @@ public:
|
||||
}
|
||||
Thin3DGLTexture(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) : tex_(0), target_(TypeToTarget(type)), format_(format), mipLevels_(mipLevels) {
|
||||
generatedMips_ = false;
|
||||
canWrap_ = true;
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
depth_ = depth;
|
||||
@@ -449,6 +525,7 @@ public:
|
||||
|
||||
bool Create(T3DTextureType type, T3DImageFormat format, int width, int height, int depth, int mipLevels) override {
|
||||
generatedMips_ = false;
|
||||
canWrap_ = true;
|
||||
format_ = format;
|
||||
target_ = TypeToTarget(type);
|
||||
mipLevels_ = mipLevels;
|
||||
@@ -468,6 +545,13 @@ public:
|
||||
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override;
|
||||
void AutoGenMipmaps() override;
|
||||
|
||||
bool HasMips() {
|
||||
return mipLevels_ > 1 || generatedMips_;
|
||||
}
|
||||
bool CanWrap() {
|
||||
return canWrap_;
|
||||
}
|
||||
|
||||
void Bind() {
|
||||
glBindTexture(target_, tex_);
|
||||
}
|
||||
@@ -494,6 +578,7 @@ private:
|
||||
T3DImageFormat format_;
|
||||
int mipLevels_;
|
||||
bool generatedMips_;
|
||||
bool canWrap_;
|
||||
};
|
||||
|
||||
Thin3DTexture *Thin3DGLContext::CreateTexture() {
|
||||
@@ -508,6 +593,7 @@ void Thin3DGLTexture::AutoGenMipmaps() {
|
||||
if (!generatedMips_) {
|
||||
Bind();
|
||||
glGenerateMipmap(target_);
|
||||
// TODO: Really, this should follow the sampler state.
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
generatedMips_ = true;
|
||||
}
|
||||
@@ -553,17 +639,7 @@ bool isPowerOf2(int n) {
|
||||
}
|
||||
|
||||
void Thin3DGLTexture::Finalize(int zim_flags) {
|
||||
GLenum wrap = GL_REPEAT;
|
||||
if ((zim_flags & ZIM_CLAMP) || !isPowerOf2(width_) || !isPowerOf2(height_))
|
||||
wrap = GL_CLAMP_TO_EDGE;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
if ((zim_flags & (ZIM_HAS_MIPS | ZIM_GEN_MIPS))) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
canWrap_ = (zim_flags & ZIM_CLAMP) || !isPowerOf2(width_) || !isPowerOf2(height_);
|
||||
}
|
||||
|
||||
|
||||
@@ -618,6 +694,16 @@ Thin3DBlendState *Thin3DGLContext::CreateBlendState(const T3DBlendStateDesc &des
|
||||
return bs;
|
||||
}
|
||||
|
||||
Thin3DSamplerState *Thin3DGLContext::CreateSamplerState(const T3DSamplerStateDesc &desc) {
|
||||
Thin3DGLSamplerState *samps = new Thin3DGLSamplerState();
|
||||
samps->wrapS = texWrapToGL[desc.wrapS];
|
||||
samps->wrapT = texWrapToGL[desc.wrapT];
|
||||
samps->magFilt = texFilterToGL[desc.magFilt];
|
||||
samps->minFilt = texFilterToGL[desc.minFilt];
|
||||
samps->mipMinFilt = texMipFilterToGL[desc.minFilt][desc.mipFilt];
|
||||
return samps;
|
||||
}
|
||||
|
||||
Thin3DBuffer *Thin3DGLContext::CreateBuffer(size_t size, uint32_t usageFlags) {
|
||||
return new Thin3DGLBuffer(size, usageFlags);
|
||||
}
|
||||
@@ -645,6 +731,10 @@ void Thin3DGLContext::SetTextures(int start, int count, Thin3DTexture **textures
|
||||
Thin3DGLTexture *glTex = static_cast<Thin3DGLTexture *>(textures[i]);
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glTex->Bind();
|
||||
|
||||
if (samplerStates_.size() > i && samplerStates_[i]) {
|
||||
samplerStates_[i]->Apply(glTex->HasMips(), glTex->CanWrap());
|
||||
}
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user