Permalink
Browse files

Merge pull request #10427 from unknownbrackets/gl-pack-len

Use GL_PACK_ROW_LENGTH where possible
  • Loading branch information...
hrydgard committed Dec 21, 2017
2 parents fe45a05 + 8e2682d commit 4d1c8ae9796a08529d219e4b803932a209a02013
Showing with 32 additions and 52 deletions.
  1. +28 −19 GPU/GLES/FramebufferManagerGLES.cpp
  2. +2 −2 ext/native/thin3d/thin3d_gl.cpp
  3. +2 −31 ext/native/thin3d/thin3d_vulkan.cpp
@@ -937,14 +937,19 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
h = possibleH;
}
// Pixel size always 4 here because we always request RGBA8888
u32 bufSize = vfb->fb_stride * h * 4;
u32 fb_address = 0x04000000 | vfb->fb_address;
bool convert = vfb->format != GE_FORMAT_8888;
const int dstBpp = vfb->format == GE_FORMAT_8888 ? 4 : 2;
const int packWidth = std::min(vfb->fb_stride, std::min(x + w, (int)vfb->width));
// Pixel size always 4 here because we always request RGBA8888
u32 bufSize = packWidth * h * 4;
u32 fb_address = 0x04000000 | vfb->fb_address;
if (gl_extensions.IsGLES && !gl_extensions.GLES3 && packWidth != vfb->fb_stride && h != 1) {
// Need to use a temp buffer, since GLES2 doesn't support GL_PACK_ROW_LENGTH.
convert = true;
}
int dstByteOffset = y * vfb->fb_stride * dstBpp;
u8 *dst = Memory::GetPointer(fb_address + dstByteOffset);
@@ -963,10 +968,11 @@ void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x
if (packed) {
DEBUG_LOG(FRAMEBUF, "Reading framebuffer to mem, bufSize = %u, fb_address = %08x", bufSize, fb_address);
int packW = h == 1 ? packWidth : vfb->fb_stride; // TODO: What's this about?
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, y, packW, h, Draw::DataFormat::R8G8B8A8_UNORM, packed, packW);
// Avoid reading the part between width and stride, if possible.
int packStride = convert || h == 1 ? packWidth : vfb->fb_stride;
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, y, packWidth, h, Draw::DataFormat::R8G8B8A8_UNORM, packed, packStride);
if (convert) {
ConvertFromRGBA8888(dst, packed, vfb->fb_stride, vfb->fb_stride, packWidth, h, vfb->format);
ConvertFromRGBA8888(dst, packed, vfb->fb_stride, packStride, packWidth, h, vfb->format);
}
}
@@ -1004,22 +1010,25 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int
DEBUG_LOG(FRAMEBUF, "Reading depthbuffer to mem at %08x for vfb=%08x", z_address, vfb->fb_address);
int packW = h == 1 ? packWidth : vfb->z_stride;
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, y, packW, h, Draw::DataFormat::D32F, convBuf_, packW);
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, y, packWidth, h, Draw::DataFormat::D32F, convBuf_, vfb->z_stride);
int dstByteOffset = y * vfb->fb_stride * sizeof(u16);
int dstByteOffset = y * vfb->z_stride * sizeof(u16);
u16 *depth = (u16 *)Memory::GetPointer(z_address + dstByteOffset);
GLfloat *packed = (GLfloat *)convBuf_;
int totalPixels = h == 1 ? packWidth : vfb->z_stride * h;
for (int i = 0; i < totalPixels; ++i) {
float scaled = FromScaledDepth(packed[i]);
if (scaled <= 0.0f) {
depth[i] = 0;
} else if (scaled >= 65535.0f) {
depth[i] = 65535;
} else {
depth[i] = (int)scaled;
for (int yp = 0; yp < h; ++yp) {
int row_offset = vfb->z_stride * yp;
for (int xp = 0; xp < packWidth; ++xp) {
const int i = row_offset + xp;
float scaled = FromScaledDepth(packed[i]);
if (scaled <= 0.0f) {
depth[i] = 0;
} else if (scaled >= 65535.0f) {
depth[i] = 65535;
} else {
depth[i] = (int)scaled;
}
}
}
CHECK_GL_ERROR_IF_DEBUG();
@@ -1114,4 +1123,4 @@ bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
buffer.Allocate(w, h, GPU_DBG_FORMAT_888_RGB, true);
draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData(), w);
return true;
}
}
@@ -903,8 +903,8 @@ bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBit
}
// Apply the correct alignment.
glPixelStorei(GL_PACK_ALIGNMENT, alignment);
if (!gl_extensions.IsGLES || (gl_extensions.GLES3 && caps_.vendor != GPUVendor::VENDOR_NVIDIA)) {
// Some drivers seem to require we specify this. See #8254.
if (!gl_extensions.IsGLES || gl_extensions.GLES3) {
// Even if not required, some drivers seem to require we specify this. See #8254.
glPixelStorei(GL_PACK_ROW_LENGTH, pixelStride);
}
@@ -237,17 +237,6 @@ bool VKShaderModule::Compile(VulkanContext *vulkan, ShaderLanguage language, con
return ok_;
}
inline VkFormat ConvertVertexDataTypeToVk(DataFormat type) {
switch (type) {
case DataFormat::R32G32_FLOAT: return VK_FORMAT_R32G32_SFLOAT;
case DataFormat::R32G32B32_FLOAT: return VK_FORMAT_R32G32B32_SFLOAT;
case DataFormat::R32G32B32A32_FLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT;
case DataFormat::R8G8B8A8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM;
default: return VK_FORMAT_UNDEFINED;
}
}
class VKInputLayout : public InputLayout {
public:
std::vector<VkVertexInputBindingDescription> bindings;
@@ -604,7 +593,7 @@ VkFormat DataFormatToVulkan(DataFormat format) {
}
}
inline VkSamplerAddressMode AddressModeToVulkan(Draw::TextureAddressMode mode) {
static inline VkSamplerAddressMode AddressModeToVulkan(Draw::TextureAddressMode mode) {
switch (mode) {
case TextureAddressMode::CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case TextureAddressMode::CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
@@ -1023,7 +1012,7 @@ void VKTexture::SetImageData(VkCommandBuffer cmd, int x, int y, int z, int width
vkTex_->Unlock(cmd);
}
inline void CopySide(VkStencilOpState &dest, const StencilSide &src) {
static inline void CopySide(VkStencilOpState &dest, const StencilSide &src) {
dest.compareMask = src.compareMask;
dest.reference = src.reference;
dest.writeMask = src.writeMask;
@@ -1122,24 +1111,6 @@ int VKPipeline::GetUniformLoc(const char *name) {
return loc;
}
inline VkPrimitiveTopology PrimToVK(Primitive prim) {
switch (prim) {
case Primitive::POINT_LIST: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case Primitive::LINE_LIST: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case Primitive::LINE_LIST_ADJ: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
case Primitive::LINE_STRIP: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
case Primitive::LINE_STRIP_ADJ: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
case Primitive::TRIANGLE_LIST: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
case Primitive::TRIANGLE_LIST_ADJ: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
case Primitive::TRIANGLE_STRIP: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
case Primitive::TRIANGLE_STRIP_ADJ: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
case Primitive::TRIANGLE_FAN: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
case Primitive::PATCH_LIST: return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
default:
return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
}
}
void VKContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) {
curPipeline_->SetDynamicUniformData(ub, size);
}

0 comments on commit 4d1c8ae

Please sign in to comment.