mirror of
https://github.com/AxioDL/boo.git
synced 2025-12-08 21:17:50 +00:00
Work on MSAA support
This commit is contained in:
@@ -36,11 +36,11 @@ class GLDataFactoryImpl : public GLDataFactory, public GraphicsDataFactoryHead
|
||||
friend struct GLCommandQueue;
|
||||
friend class GLDataFactory::Context;
|
||||
IGraphicsContext* m_parent;
|
||||
uint32_t m_drawSamples;
|
||||
GLContext* m_glCtx;
|
||||
std::unordered_map<uint64_t, std::unique_ptr<GLShareableShader>> m_sharedShaders;
|
||||
public:
|
||||
GLDataFactoryImpl(IGraphicsContext* parent, uint32_t drawSamples)
|
||||
: m_parent(parent), m_drawSamples(drawSamples) {}
|
||||
GLDataFactoryImpl(IGraphicsContext* parent, GLContext* glCtx)
|
||||
: m_parent(parent), m_glCtx(glCtx) {}
|
||||
|
||||
Platform platform() const { return Platform::OpenGL; }
|
||||
const SystemChar* platformName() const { return _S("OpenGL"); }
|
||||
@@ -187,7 +187,7 @@ class GLTextureS : public GraphicsDataNode<ITextureS>
|
||||
friend class GLDataFactory;
|
||||
GLuint m_tex;
|
||||
GLTextureS(const ObjToken<BaseGraphicsData>& parent, size_t width, size_t height, size_t mips,
|
||||
TextureFormat fmt, TextureClampMode clampMode, const void* data, size_t sz)
|
||||
TextureFormat fmt, TextureClampMode clampMode, GLint aniso, const void* data, size_t sz)
|
||||
: GraphicsDataNode<ITextureS>(parent)
|
||||
{
|
||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
||||
@@ -196,12 +196,15 @@ class GLTextureS : public GraphicsDataNode<ITextureS>
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
if (mips > 1)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mips-1);
|
||||
}
|
||||
else
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
if (GLEW_EXT_texture_filter_anisotropic)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
|
||||
|
||||
SetClampMode(GL_TEXTURE_2D, clampMode);
|
||||
|
||||
GLenum intFormat, format;
|
||||
@@ -274,7 +277,7 @@ class GLTextureSA : public GraphicsDataNode<ITextureSA>
|
||||
friend class GLDataFactory;
|
||||
GLuint m_tex;
|
||||
GLTextureSA(const ObjToken<BaseGraphicsData>& parent, size_t width, size_t height, size_t layers, size_t mips,
|
||||
TextureFormat fmt, TextureClampMode clampMode, const void* data, size_t sz)
|
||||
TextureFormat fmt, TextureClampMode clampMode, GLint aniso, const void* data, size_t sz)
|
||||
: GraphicsDataNode<ITextureSA>(parent)
|
||||
{
|
||||
const uint8_t* dataIt = static_cast<const uint8_t*>(data);
|
||||
@@ -289,6 +292,9 @@ class GLTextureSA : public GraphicsDataNode<ITextureSA>
|
||||
else
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
if (GLEW_EXT_texture_filter_anisotropic)
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
|
||||
|
||||
SetClampMode(GL_TEXTURE_2D_ARRAY, clampMode);
|
||||
|
||||
GLenum intFormat, format;
|
||||
@@ -433,13 +439,13 @@ class GLTextureR : public GraphicsDataNode<ITextureR>
|
||||
struct GLCommandQueue* m_q;
|
||||
GLuint m_texs[2] = {};
|
||||
GLuint m_bindTexs[2][MAX_BIND_TEXS] = {};
|
||||
GLuint m_bindFBOs[2][MAX_BIND_TEXS] = {};
|
||||
GLuint m_fbo = 0;
|
||||
size_t m_width = 0;
|
||||
size_t m_height = 0;
|
||||
size_t m_samples = 0;
|
||||
size_t m_colorBindCount;
|
||||
size_t m_depthBindCount;
|
||||
GLenum m_target;
|
||||
GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue* q, size_t width, size_t height, size_t samples,
|
||||
TextureClampMode clampMode, size_t colorBindCount, size_t depthBindCount);
|
||||
public:
|
||||
@@ -447,6 +453,8 @@ public:
|
||||
{
|
||||
glDeleteTextures(2, m_texs);
|
||||
glDeleteTextures(MAX_BIND_TEXS * 2, m_bindTexs[0]);
|
||||
if (m_samples > 1)
|
||||
glDeleteFramebuffers(MAX_BIND_TEXS * 2, m_bindFBOs[0]);
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
}
|
||||
|
||||
@@ -467,7 +475,7 @@ public:
|
||||
void bind(size_t idx, int bindIdx, bool depth) const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + idx);
|
||||
glBindTexture(m_target, m_bindTexs[depth][bindIdx]);
|
||||
glBindTexture(GL_TEXTURE_2D, m_bindTexs[depth][bindIdx]);
|
||||
}
|
||||
|
||||
void resize(size_t width, size_t height)
|
||||
@@ -518,7 +526,9 @@ ObjToken<ITextureS>
|
||||
GLDataFactory::Context::newStaticTexture(size_t width, size_t height, size_t mips, TextureFormat fmt,
|
||||
TextureClampMode clampMode, const void* data, size_t sz)
|
||||
{
|
||||
return {new GLTextureS(m_data, width, height, mips, fmt, clampMode, data, sz)};
|
||||
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
||||
return {new GLTextureS(m_data, width, height, mips, fmt, clampMode,
|
||||
factory.m_glCtx->m_anisotropy, data, sz)};
|
||||
}
|
||||
|
||||
ObjToken<ITextureSA>
|
||||
@@ -526,7 +536,9 @@ GLDataFactory::Context::newStaticArrayTexture(size_t width, size_t height, size_
|
||||
TextureFormat fmt, TextureClampMode clampMode,
|
||||
const void *data, size_t sz)
|
||||
{
|
||||
return {new GLTextureSA(m_data, width, height, layers, mips, fmt, clampMode, data, sz)};
|
||||
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
||||
return {new GLTextureSA(m_data, width, height, layers, mips, fmt, clampMode,
|
||||
factory.m_glCtx->m_anisotropy, data, sz)};
|
||||
}
|
||||
|
||||
class GLShaderPipeline : public GraphicsDataNode<IShaderPipeline>
|
||||
@@ -1028,6 +1040,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
Platform platform() const { return IGraphicsDataFactory::Platform::OpenGL; }
|
||||
const SystemChar* platformName() const { return _S("OpenGL"); }
|
||||
IGraphicsContext* m_parent = nullptr;
|
||||
GLContext* m_glCtx = nullptr;
|
||||
|
||||
std::mutex m_mt;
|
||||
std::condition_variable m_cv;
|
||||
@@ -1167,8 +1180,31 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
{
|
||||
glGenFramebuffers(1, &tex->m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->m_texs[0], 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex->m_texs[1], 0);
|
||||
GLenum target = tex->m_samples > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, tex->m_texs[0], 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, target, tex->m_texs[1], 0);
|
||||
|
||||
if (tex->m_samples > 1)
|
||||
{
|
||||
if (tex->m_colorBindCount)
|
||||
{
|
||||
glGenFramebuffers(tex->m_colorBindCount, tex->m_bindFBOs[0]);
|
||||
for (int i=0 ; i<tex->m_colorBindCount ; ++i)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[0][i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->m_bindTexs[0][i], 0);
|
||||
}
|
||||
}
|
||||
if (tex->m_depthBindCount)
|
||||
{
|
||||
glGenFramebuffers(tex->m_depthBindCount, tex->m_bindFBOs[1]);
|
||||
for (int i=0 ; i<tex->m_depthBindCount ; ++i)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[1][i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex->m_bindTexs[1][i], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderingWorker(GLCommandQueue* self)
|
||||
@@ -1188,6 +1224,17 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
Log.report(logvisor::Info, "OpenGL Version: %s", version);
|
||||
self->m_parent->postInit();
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
if (GLEW_EXT_texture_filter_anisotropic)
|
||||
{
|
||||
GLint maxAniso;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
|
||||
self->m_glCtx->m_anisotropy = std::min(uint32_t(maxAniso), self->m_glCtx->m_anisotropy);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso);
|
||||
}
|
||||
GLint maxSamples;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
self->m_glCtx->m_sampleCount =
|
||||
flp2(std::min(uint32_t(maxSamples), std::max(uint32_t(1), self->m_glCtx->m_sampleCount)) - 1);
|
||||
}
|
||||
self->m_initcv.notify_one();
|
||||
while (self->m_running)
|
||||
@@ -1229,6 +1276,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
std::vector<Command>& cmds = self->m_cmdBufs[self->m_drawBuf];
|
||||
GLenum currentPrim = GL_TRIANGLES;
|
||||
const GLShaderDataBinding* curBinding = nullptr;
|
||||
GLuint curFBO = 0;
|
||||
for (const Command& cmd : cmds)
|
||||
{
|
||||
switch (cmd.m_op)
|
||||
@@ -1244,10 +1292,8 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
case Command::Op::SetRenderTarget:
|
||||
{
|
||||
const GLTextureR* tex = cmd.target.cast<GLTextureR>();
|
||||
if (!tex)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_fbo);
|
||||
curFBO = (!tex) ? 0 : tex->m_fbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, curFBO);
|
||||
break;
|
||||
}
|
||||
case Command::Op::SetViewport:
|
||||
@@ -1291,23 +1337,49 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
break;
|
||||
case Command::Op::ResolveBindTexture:
|
||||
{
|
||||
const SWindowRect& rect = cmd.viewport.rect;
|
||||
const GLTextureR* tex = cmd.resolveTex.cast<GLTextureR>();
|
||||
GLenum target = (tex->m_samples > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, tex->m_fbo);
|
||||
glActiveTexture(GL_TEXTURE9);
|
||||
if (cmd.resolveColor && tex->m_bindTexs[0][cmd.bindIdx])
|
||||
if (tex->m_samples <= 1)
|
||||
{
|
||||
glBindTexture(target, tex->m_bindTexs[0][cmd.bindIdx]);
|
||||
glCopyTexSubImage2D(target, 0, cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||
cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||
cmd.viewport.rect.size[0], cmd.viewport.rect.size[1]);
|
||||
glActiveTexture(GL_TEXTURE9);
|
||||
if (cmd.resolveColor && tex->m_bindTexs[0][cmd.bindIdx])
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_bindTexs[0][cmd.bindIdx]);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
rect.location[0], rect.location[1],
|
||||
rect.location[0], rect.location[1],
|
||||
rect.size[0], rect.size[1]);
|
||||
}
|
||||
if (cmd.resolveDepth && tex->m_bindTexs[1][cmd.bindIdx])
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, tex->m_bindTexs[1][cmd.bindIdx]);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
rect.location[0], rect.location[1],
|
||||
rect.location[0], rect.location[1],
|
||||
rect.size[0], rect.size[1]);
|
||||
}
|
||||
}
|
||||
if (cmd.resolveDepth && tex->m_bindTexs[1][cmd.bindIdx])
|
||||
else
|
||||
{
|
||||
glBindTexture(target, tex->m_bindTexs[1][cmd.bindIdx]);
|
||||
glCopyTexSubImage2D(target, 0, cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||
cmd.viewport.rect.location[0], cmd.viewport.rect.location[1],
|
||||
cmd.viewport.rect.size[0], cmd.viewport.rect.size[1]);
|
||||
if (cmd.resolveColor && tex->m_bindTexs[0][cmd.bindIdx])
|
||||
{
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_bindFBOs[0][cmd.bindIdx]);
|
||||
glBlitFramebuffer(rect.location[0], rect.location[1],
|
||||
rect.location[0] + rect.size[0], rect.location[1] + rect.size[1],
|
||||
rect.location[0], rect.location[1],
|
||||
rect.location[0] + rect.size[0], rect.location[1] + rect.size[1],
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
if (cmd.resolveDepth && tex->m_bindTexs[1][cmd.bindIdx])
|
||||
{
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tex->m_bindFBOs[1][cmd.bindIdx]);
|
||||
glBlitFramebuffer(rect.location[0], rect.location[1],
|
||||
rect.location[0] + rect.size[0], rect.location[1] + rect.size[1],
|
||||
rect.location[0], rect.location[1],
|
||||
rect.location[0] + rect.size[0], rect.location[1] + rect.size[1],
|
||||
GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
if (cmd.clearDepth)
|
||||
{
|
||||
@@ -1315,6 +1387,7 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, curFBO);
|
||||
break;
|
||||
}
|
||||
case Command::Op::Present:
|
||||
@@ -1338,8 +1411,9 @@ struct GLCommandQueue : IGraphicsCommandQueue
|
||||
}
|
||||
}
|
||||
|
||||
GLCommandQueue(IGraphicsContext* parent)
|
||||
GLCommandQueue(IGraphicsContext* parent, GLContext* glCtx)
|
||||
: m_parent(parent),
|
||||
m_glCtx(glCtx),
|
||||
m_initlk(m_initmt),
|
||||
m_thr(RenderingWorker, this)
|
||||
{
|
||||
@@ -1585,7 +1659,6 @@ GLTextureR::GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue*
|
||||
|
||||
if (samples > 1)
|
||||
{
|
||||
m_target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[0]);
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA, width, height, GL_FALSE);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texs[1]);
|
||||
@@ -1593,7 +1666,6 @@ GLTextureR::GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue*
|
||||
}
|
||||
else
|
||||
{
|
||||
m_target = GL_TEXTURE_2D;
|
||||
glBindTexture(GL_TEXTURE_2D, m_texs[0]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texs[1]);
|
||||
@@ -1626,7 +1698,7 @@ GLDataFactory::Context::newRenderTexture(size_t width, size_t height, TextureCla
|
||||
{
|
||||
GLDataFactoryImpl& factory = static_cast<GLDataFactoryImpl&>(m_parent);
|
||||
GLCommandQueue* q = static_cast<GLCommandQueue*>(factory.m_parent->getCommandQueue());
|
||||
ObjToken<ITextureR> retval(new GLTextureR(m_data, q, width, height, factory.m_drawSamples, clampMode,
|
||||
ObjToken<ITextureR> retval(new GLTextureR(m_data, q, width, height, factory.m_glCtx->m_sampleCount, clampMode,
|
||||
colorBindingCount, depthBindingCount));
|
||||
q->resizeRenderTexture(retval, width, height);
|
||||
return retval;
|
||||
@@ -1653,14 +1725,14 @@ ObjToken<IVertexFormat> GLDataFactory::Context::newVertexFormat
|
||||
return {new GLVertexFormat(m_data, q, elementCount, elements, baseVert, baseInst)};
|
||||
}
|
||||
|
||||
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent)
|
||||
IGraphicsCommandQueue* _NewGLCommandQueue(IGraphicsContext* parent, GLContext* glCtx)
|
||||
{
|
||||
return new struct GLCommandQueue(parent);
|
||||
return new struct GLCommandQueue(parent, glCtx);
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* _NewGLDataFactory(IGraphicsContext* parent, uint32_t drawSamples)
|
||||
IGraphicsDataFactory* _NewGLDataFactory(IGraphicsContext* parent, GLContext* glCtx)
|
||||
{
|
||||
return new class GLDataFactoryImpl(parent, drawSamples);
|
||||
return new class GLDataFactoryImpl(parent, glCtx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,15 +37,14 @@ class MetalDataFactoryImpl : public MetalDataFactory, public GraphicsDataFactory
|
||||
IGraphicsContext* m_parent;
|
||||
std::unordered_map<uint64_t, std::unique_ptr<MetalShareableShader>> m_sharedShaders;
|
||||
struct MetalContext* m_ctx;
|
||||
uint32_t m_sampleCount;
|
||||
|
||||
public:
|
||||
std::unordered_map<uint64_t, uint64_t> m_sourceToBinary;
|
||||
char m_libfile[MAXPATHLEN];
|
||||
bool m_hasCompiler = false;
|
||||
|
||||
MetalDataFactoryImpl(IGraphicsContext* parent, MetalContext* ctx, uint32_t sampleCount)
|
||||
: m_parent(parent), m_ctx(ctx), m_sampleCount(sampleCount)
|
||||
MetalDataFactoryImpl(IGraphicsContext* parent, MetalContext* ctx)
|
||||
: m_parent(parent), m_ctx(ctx)
|
||||
{
|
||||
snprintf(m_libfile, MAXPATHLEN, "%sboo_metal_shader.metallib", getenv("TMPDIR"));
|
||||
for (auto& arg : APP->getArgs())
|
||||
@@ -524,14 +523,28 @@ class MetalTextureR : public GraphicsDataNode<ITextureR>
|
||||
{
|
||||
desc.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
for (int i=0 ; i<m_colorBindCount ; ++i)
|
||||
{
|
||||
m_colorBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||
m_blitColor[i] = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
m_blitColor[i].colorAttachments[0].texture = m_colorTex;
|
||||
m_blitColor[i].colorAttachments[0].loadAction = MTLLoadActionLoad;
|
||||
m_blitColor[i].colorAttachments[0].storeAction = MTLStoreActionMultisampleResolve;
|
||||
m_blitColor[i].colorAttachments[0].resolveTexture = m_colorBindTex[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_depthBindCount)
|
||||
{
|
||||
desc.pixelFormat = MTLPixelFormatDepth32Float;
|
||||
for (int i=0 ; i<m_depthBindCount ; ++i)
|
||||
{
|
||||
m_depthBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
|
||||
m_blitDepth[i] = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
m_blitDepth[i].depthAttachment.texture = m_colorTex;
|
||||
m_blitDepth[i].depthAttachment.loadAction = MTLLoadActionLoad;
|
||||
m_blitDepth[i].depthAttachment.storeAction = MTLStoreActionMultisampleResolve;
|
||||
m_blitDepth[i].depthAttachment.resolveTexture = m_depthBindTex[i];
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@@ -609,6 +622,8 @@ public:
|
||||
MTLRenderPassDescriptor* m_clearDepthPassDesc;
|
||||
MTLRenderPassDescriptor* m_clearColorPassDesc;
|
||||
MTLRenderPassDescriptor* m_clearBothPassDesc;
|
||||
MTLRenderPassDescriptor* m_blitColor[MAX_BIND_TEXS] = {};
|
||||
MTLRenderPassDescriptor* m_blitDepth[MAX_BIND_TEXS] = {};
|
||||
~MetalTextureR() = default;
|
||||
|
||||
void resize(MetalContext* ctx, size_t width, size_t height)
|
||||
@@ -1004,6 +1019,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||
IGraphicsContext* m_parent;
|
||||
id<MTLCommandBuffer> m_cmdBuf;
|
||||
id<MTLRenderCommandEncoder> m_enc;
|
||||
id<MTLSamplerState> m_samplers[3];
|
||||
bool m_running = true;
|
||||
|
||||
int m_fillBuf = 0;
|
||||
@@ -1015,6 +1031,27 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||
@autoreleasepool
|
||||
{
|
||||
m_cmdBuf = [ctx->m_q commandBuffer];
|
||||
|
||||
MTLSamplerDescriptor* sampDesc = [MTLSamplerDescriptor new];
|
||||
sampDesc.rAddressMode = MTLSamplerAddressModeRepeat;
|
||||
sampDesc.sAddressMode = MTLSamplerAddressModeRepeat;
|
||||
sampDesc.tAddressMode = MTLSamplerAddressModeRepeat;
|
||||
sampDesc.minFilter = MTLSamplerMinMagFilterLinear;
|
||||
sampDesc.magFilter = MTLSamplerMinMagFilterLinear;
|
||||
sampDesc.mipFilter = MTLSamplerMipFilterLinear;
|
||||
sampDesc.maxAnisotropy = ctx->m_anisotropy;
|
||||
sampDesc.borderColor = MTLSamplerBorderColorOpaqueWhite;
|
||||
m_samplers[0] = [ctx->m_dev newSamplerStateWithDescriptor:sampDesc];
|
||||
|
||||
sampDesc.rAddressMode = MTLSamplerAddressModeClampToBorderColor;
|
||||
sampDesc.sAddressMode = MTLSamplerAddressModeClampToBorderColor;
|
||||
sampDesc.tAddressMode = MTLSamplerAddressModeClampToBorderColor;
|
||||
m_samplers[1] = [ctx->m_dev newSamplerStateWithDescriptor:sampDesc];
|
||||
|
||||
sampDesc.rAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||
sampDesc.sAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||
sampDesc.tAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||
m_samplers[2] = [ctx->m_dev newSamplerStateWithDescriptor:sampDesc];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,6 +1077,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||
cbind->bind(m_enc, m_fillBuf);
|
||||
m_boundData = cbind;
|
||||
m_currentPrimitive = cbind->m_pipeline.cast<MetalShaderPipeline>()->m_drawPrim;
|
||||
[m_enc setFragmentSamplerStates:m_samplers withRange:NSMakeRange(0, 3)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1175,39 +1213,11 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||
@autoreleasepool
|
||||
{
|
||||
[m_enc endEncoding];
|
||||
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, tex->m_width, tex->m_height));
|
||||
NSUInteger y = tlOrigin ? intersectRect.location[1] : int(tex->m_height) -
|
||||
intersectRect.location[1] - intersectRect.size[1];
|
||||
MTLOrigin origin = {NSUInteger(intersectRect.location[0]), y, 0};
|
||||
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
|
||||
|
||||
if (color && tex->m_colorBindTex[bindIdx])
|
||||
{
|
||||
[blitEnc copyFromTexture:tex->m_colorTex
|
||||
sourceSlice:0
|
||||
sourceLevel:0
|
||||
sourceOrigin:origin
|
||||
sourceSize:MTLSizeMake(intersectRect.size[0], intersectRect.size[1], 1)
|
||||
toTexture:tex->m_colorBindTex[bindIdx]
|
||||
destinationSlice:0
|
||||
destinationLevel:0
|
||||
destinationOrigin:origin];
|
||||
}
|
||||
|
||||
[[m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_blitColor[bindIdx]] endEncoding];
|
||||
if (depth && tex->m_depthBindTex[bindIdx])
|
||||
{
|
||||
[blitEnc copyFromTexture:tex->m_depthTex
|
||||
sourceSlice:0
|
||||
sourceLevel:0
|
||||
sourceOrigin:origin
|
||||
sourceSize:MTLSizeMake(intersectRect.size[0], intersectRect.size[1], 1)
|
||||
toTexture:tex->m_depthBindTex[bindIdx]
|
||||
destinationSlice:0
|
||||
destinationLevel:0
|
||||
destinationOrigin:origin];
|
||||
}
|
||||
[[m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_blitDepth[bindIdx]] endEncoding];
|
||||
|
||||
[blitEnc endEncoding];
|
||||
m_enc = [m_cmdBuf renderCommandEncoderWithDescriptor:clearDepth ? tex->m_clearDepthPassDesc : tex->m_passDesc];
|
||||
[m_enc setFrontFacingWinding:MTLWindingCounterClockwise];
|
||||
|
||||
@@ -1225,6 +1235,7 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||
}
|
||||
|
||||
bool m_inProgress = false;
|
||||
std::unordered_map<uintptr_t, MTLRenderPassDescriptor*> m_resolvePasses;
|
||||
void execute()
|
||||
{
|
||||
if (!m_running)
|
||||
@@ -1297,20 +1308,21 @@ struct MetalCommandQueue : IGraphicsCommandQueue
|
||||
{
|
||||
MetalTextureR* src = m_needsDisplay.cast<MetalTextureR>();
|
||||
id<MTLTexture> dest = drawable.texture;
|
||||
uintptr_t key = uintptr_t(src->m_colorTex) ^ uintptr_t(dest);
|
||||
auto passSearch = m_resolvePasses.find(key);
|
||||
if (passSearch == m_resolvePasses.end())
|
||||
{
|
||||
MTLRenderPassDescriptor* desc = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
desc.colorAttachments[0].texture = src->m_colorTex;
|
||||
desc.colorAttachments[0].loadAction = MTLLoadActionLoad;
|
||||
desc.colorAttachments[0].storeAction = MTLStoreActionMultisampleResolve;
|
||||
desc.colorAttachments[0].resolveTexture = dest;
|
||||
passSearch = m_resolvePasses.insert(std::make_pair(key, desc)).first;
|
||||
}
|
||||
if (src->m_colorTex.width == dest.width &&
|
||||
src->m_colorTex.height == dest.height)
|
||||
{
|
||||
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
|
||||
[blitEnc copyFromTexture:src->m_colorTex
|
||||
sourceSlice:0
|
||||
sourceLevel:0
|
||||
sourceOrigin:MTLOriginMake(0, 0, 0)
|
||||
sourceSize:MTLSizeMake(dest.width, dest.height, 1)
|
||||
toTexture:dest
|
||||
destinationSlice:0
|
||||
destinationLevel:0
|
||||
destinationOrigin:MTLOriginMake(0, 0, 0)];
|
||||
[blitEnc endEncoding];
|
||||
[[m_cmdBuf renderCommandEncoderWithDescriptor:passSearch->second] endEncoding];
|
||||
[m_cmdBuf presentDrawable:drawable];
|
||||
}
|
||||
}
|
||||
@@ -1392,7 +1404,7 @@ MetalDataFactory::Context::newRenderTexture(size_t width, size_t height, Texture
|
||||
@autoreleasepool
|
||||
{
|
||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||
return {new MetalTextureR(m_data, factory.m_ctx, width, height, factory.m_sampleCount,
|
||||
return {new MetalTextureR(m_data, factory.m_ctx, width, height, factory.m_ctx->m_sampleCount,
|
||||
colorBindCount, depthBindCount)};
|
||||
}
|
||||
}
|
||||
@@ -1411,7 +1423,7 @@ ObjToken<IShaderPipeline>
|
||||
MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char* fragSource,
|
||||
std::vector<uint8_t>* vertBlobOut,
|
||||
std::vector<uint8_t>* fragBlobOut,
|
||||
const ObjToken<IVertexFormat>& vtxFmt, unsigned targetSamples,
|
||||
const ObjToken<IVertexFormat>& vtxFmt,
|
||||
BlendFactor srcFac, BlendFactor dstFac, Primitive prim,
|
||||
ZTest depthTest, bool depthWrite, bool colorWrite,
|
||||
bool alphaWrite, CullMode culling)
|
||||
@@ -1420,7 +1432,7 @@ MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char*
|
||||
{
|
||||
MetalDataFactoryImpl& factory = static_cast<MetalDataFactoryImpl&>(m_parent);
|
||||
MTLCompileOptions* compOpts = [MTLCompileOptions new];
|
||||
compOpts.languageVersion = MTLLanguageVersion1_2;
|
||||
compOpts.languageVersion = MTLLanguageVersion1_1;
|
||||
NSError* err = nullptr;
|
||||
|
||||
XXH64_state_t hashState;
|
||||
@@ -1541,7 +1553,7 @@ MetalDataFactory::Context::newShaderPipeline(const char* vertSource, const char*
|
||||
}
|
||||
|
||||
return {new MetalShaderPipeline(m_data, factory.m_ctx, std::move(vertShader), std::move(fragShader),
|
||||
vtxFmt, targetSamples, srcFac, dstFac, prim, depthTest, depthWrite,
|
||||
vtxFmt, factory.m_ctx->m_sampleCount, srcFac, dstFac, prim, depthTest, depthWrite,
|
||||
colorWrite, alphaWrite, culling)};
|
||||
}
|
||||
}
|
||||
@@ -1588,9 +1600,9 @@ IGraphicsCommandQueue* _NewMetalCommandQueue(MetalContext* ctx, IWindow* parentW
|
||||
return new struct MetalCommandQueue(ctx, parentWindow, parent);
|
||||
}
|
||||
|
||||
IGraphicsDataFactory* _NewMetalDataFactory(IGraphicsContext* parent, MetalContext* ctx, uint32_t sampleCount)
|
||||
IGraphicsDataFactory* _NewMetalDataFactory(IGraphicsContext* parent, MetalContext* ctx)
|
||||
{
|
||||
return new class MetalDataFactoryImpl(parent, ctx, sampleCount);
|
||||
return new class MetalDataFactoryImpl(parent, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user