mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-26 01:50:14 +00:00
Implemented validation for the texture module
This commit is contained in:
parent
30f0d1dbf4
commit
1c6965f106
@ -309,17 +309,24 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
|
|||||||
codec->configTiling(true, 8); // change 8 for 32 in case the mage is tiled
|
codec->configTiling(true, 8); // change 8 for 32 in case the mage is tiled
|
||||||
// on blocks of 32x32
|
// on blocks of 32x32
|
||||||
codec->configRGBATransform(!native_format[(unsigned int)params.pixel_format]);
|
codec->configRGBATransform(!native_format[(unsigned int)params.pixel_format]);
|
||||||
codec->decode();
|
codec->validate();
|
||||||
std::unique_ptr<u8[]> decoded_texture = codec->transferInternalBuffer();
|
if (!codec->invalid()) {
|
||||||
u32 bytes = codec->getInternalBytesPerPixel();
|
codec->decode();
|
||||||
if (bytes == 3)
|
std::unique_ptr<u8[]> decoded_texture = codec->transferInternalBuffer();
|
||||||
bytes = 1;
|
u32 bytes = codec->getInternalBytesPerPixel();
|
||||||
else if (bytes != 2)
|
if (bytes == 3)
|
||||||
bytes = 4;
|
bytes = 1;
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, bytes);
|
else if (bytes != 2)
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0,
|
bytes = 4;
|
||||||
tuple.format, tuple.type, decoded_texture.get());
|
glPixelStorei(GL_UNPACK_ALIGNMENT, bytes);
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height,
|
||||||
|
0, tuple.format, tuple.type, decoded_texture.get());
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(Render_OpenGL,
|
||||||
|
"Invalid texture sent to renderer; width: %d height %d type: %d",
|
||||||
|
params.width, params.height, (unsigned int)params.pixel_format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface
|
// If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface
|
||||||
if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) {
|
if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) {
|
||||||
@ -662,7 +669,13 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
|
|||||||
codec->configRGBATransform(!native_format[(u32)surface->pixel_format]);
|
codec->configRGBATransform(!native_format[(u32)surface->pixel_format]);
|
||||||
codec->configPreConvertedRGBA(!native_format[(u32)surface->pixel_format]);
|
codec->configPreConvertedRGBA(!native_format[(u32)surface->pixel_format]);
|
||||||
codec->setExternalBuffer(dst_buffer);
|
codec->setExternalBuffer(dst_buffer);
|
||||||
codec->encode();
|
codec->validate();
|
||||||
|
if (!codec->invalid())
|
||||||
|
codec->encode();
|
||||||
|
else
|
||||||
|
LOG_WARNING(Render_OpenGL,
|
||||||
|
"Invalid texture sent to renderer; width: %d height %d type: %d",
|
||||||
|
surface->width, surface->height, (unsigned int)surface->pixel_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->dirty = false;
|
surface->dirty = false;
|
||||||
|
@ -13,13 +13,13 @@ void Codec::decode() {
|
|||||||
this->init(true);
|
this->init(true);
|
||||||
if (this->morton)
|
if (this->morton)
|
||||||
this->decode_morton_pass();
|
this->decode_morton_pass();
|
||||||
};
|
}
|
||||||
|
|
||||||
void Codec::encode() {
|
void Codec::encode() {
|
||||||
this->init(false);
|
this->init(false);
|
||||||
if (this->morton)
|
if (this->morton)
|
||||||
this->encode_morton_pass();
|
this->encode_morton_pass();
|
||||||
};
|
}
|
||||||
|
|
||||||
void Codec::configTiling(bool active, u32 tiling) {
|
void Codec::configTiling(bool active, u32 tiling) {
|
||||||
this->morton = true;
|
this->morton = true;
|
||||||
@ -66,14 +66,39 @@ void Codec::init(bool decode) {
|
|||||||
if (!this->raw_RGBA)
|
if (!this->raw_RGBA)
|
||||||
this->expected_nibbles_size = this->start_nibbles_size;
|
this->expected_nibbles_size = this->start_nibbles_size;
|
||||||
}
|
}
|
||||||
if (!this->external_result_buffer) {
|
this->validate();
|
||||||
|
if (!this->external_result_buffer || !this->invalid()) {
|
||||||
size_t buff_size = this->width * this->height * this->expected_nibbles_size / 2;
|
size_t buff_size = this->width * this->height * this->expected_nibbles_size / 2;
|
||||||
this->internal_buffer = std::make_unique<u8[]>(buff_size);
|
this->internal_buffer = std::make_unique<u8[]>(buff_size);
|
||||||
this->passing_buffer = this->internal_buffer.get();
|
this->passing_buffer = this->internal_buffer.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Codec::decode_morton_pass() {
|
void Codec::validate() {
|
||||||
|
if (this->width < 8) {
|
||||||
|
this->invalid_state = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->height < 8) {
|
||||||
|
this->invalid_state = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->target_buffer == nullptr) {
|
||||||
|
this->invalid_state = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->external_result_buffer && this->passing_buffer == nullptr) {
|
||||||
|
this->invalid_state = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->morton && this->morton_pass_tiling != 8 && this->morton_pass_tiling != 32) {
|
||||||
|
this->invalid_state = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->invalid_state = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Codec::decode_morton_pass() {
|
||||||
if (this->morton_pass_tiling == 8)
|
if (this->morton_pass_tiling == 8)
|
||||||
Decoders::Morton_8x8(this->target_buffer, this->passing_buffer, this->width, this->height,
|
Decoders::Morton_8x8(this->target_buffer, this->passing_buffer, this->width, this->height,
|
||||||
this->start_nibbles_size * 4);
|
this->start_nibbles_size * 4);
|
||||||
@ -82,7 +107,7 @@ void Codec::decode_morton_pass() {
|
|||||||
this->start_nibbles_size * 4);
|
this->start_nibbles_size * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Codec::encode_morton_pass() {
|
inline void Codec::encode_morton_pass() {
|
||||||
if (this->morton_pass_tiling == 8)
|
if (this->morton_pass_tiling == 8)
|
||||||
Encoders::Morton_8x8(this->target_buffer, this->passing_buffer, this->width, this->height,
|
Encoders::Morton_8x8(this->target_buffer, this->passing_buffer, this->width, this->height,
|
||||||
this->start_nibbles_size * 4);
|
this->start_nibbles_size * 4);
|
||||||
|
@ -43,6 +43,7 @@ public:
|
|||||||
void setExternalBuffer(u8* external);
|
void setExternalBuffer(u8* external);
|
||||||
std::unique_ptr<u8[]> transferInternalBuffer();
|
std::unique_ptr<u8[]> transferInternalBuffer();
|
||||||
|
|
||||||
|
virtual void validate();
|
||||||
bool invalid();
|
bool invalid();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -74,8 +75,8 @@ protected:
|
|||||||
|
|
||||||
typedef Codec super;
|
typedef Codec super;
|
||||||
|
|
||||||
void decode_morton_pass();
|
inline void decode_morton_pass();
|
||||||
void encode_morton_pass();
|
inline void encode_morton_pass();
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace CodecFactory {
|
namespace CodecFactory {
|
||||||
|
Loading…
Reference in New Issue
Block a user