Commit 9d815378 by Jamie Madill Committed by Commit Bot

D3D: Refactor driver uniform application.

This is a preparation for more dirty bits. It moves the driver constant buffer application into the state manager, redesigns how the dirtiness is tracked (no more memcmp) and also removes a couple of virtual calls. BUG=angleproject:1390 BUG=angleproject:2052 Change-Id: I41a75c280600ad8ba1f23c721d436214a116422a Reviewed-on: https://chromium-review.googlesource.com/659223 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 33bb7c42
...@@ -1765,22 +1765,6 @@ void ProgramD3D::initializeUniformStorage() ...@@ -1765,22 +1765,6 @@ void ProgramD3D::initializeUniformStorage()
} }
} }
gl::Error ProgramD3D::applyUniforms()
{
ASSERT(!mDirtySamplerMapping);
ANGLE_TRY(mRenderer->applyUniforms(*this, mD3DUniforms));
mUniformsDirty = false;
return gl::NoError();
}
gl::Error ProgramD3D::applyComputeUniforms()
{
ASSERT(!mDirtySamplerMapping);
ANGLE_TRY(mRenderer->applyComputeUniforms(*this, mD3DUniforms));
mUniformsDirty = false;
return gl::NoError();
}
gl::Error ProgramD3D::applyUniformBuffers(const gl::ContextState &data) gl::Error ProgramD3D::applyUniformBuffers(const gl::ContextState &data)
{ {
if (mState.getUniformBlocks().empty()) if (mState.getUniformBlocks().empty())
......
...@@ -208,8 +208,6 @@ class ProgramD3D : public ProgramImpl ...@@ -208,8 +208,6 @@ class ProgramD3D : public ProgramImpl
const GLfloat *coeffs) override; const GLfloat *coeffs) override;
void initializeUniformStorage(); void initializeUniformStorage();
gl::Error applyUniforms();
gl::Error applyComputeUniforms();
gl::Error applyUniformBuffers(const gl::ContextState &data); gl::Error applyUniformBuffers(const gl::ContextState &data);
void dirtyAllUniforms(); void dirtyAllUniforms();
...@@ -290,6 +288,8 @@ class ProgramD3D : public ProgramImpl ...@@ -290,6 +288,8 @@ class ProgramD3D : public ProgramImpl
bool hasPixelExecutableForCachedOutputLayout(); bool hasPixelExecutableForCachedOutputLayout();
bool areUniformsDirty() const { return mUniformsDirty; } bool areUniformsDirty() const { return mUniformsDirty; }
const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
void markUniformsClean() { mUniformsDirty = false; }
private: private:
// These forward-declared tasks are used for multi-thread shader compiles. // These forward-declared tasks are used for multi-thread shader compiles.
......
...@@ -154,9 +154,6 @@ class RendererD3D : public BufferFactoryD3D ...@@ -154,9 +154,6 @@ class RendererD3D : public BufferFactoryD3D
const std::vector<GLint> &vertexUniformBuffers, const std::vector<GLint> &vertexUniformBuffers,
const std::vector<GLint> &fragmentUniformBuffers) = 0; const std::vector<GLint> &fragmentUniformBuffers) = 0;
virtual gl::Error applyUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray) = 0;
virtual unsigned int getReservedVertexUniformBuffers() const = 0; virtual unsigned int getReservedVertexUniformBuffers() const = 0;
virtual unsigned int getReservedFragmentUniformBuffers() const = 0; virtual unsigned int getReservedFragmentUniformBuffers() const = 0;
...@@ -319,9 +316,6 @@ class RendererD3D : public BufferFactoryD3D ...@@ -319,9 +316,6 @@ class RendererD3D : public BufferFactoryD3D
angle::WorkerThreadPool *getWorkerThreadPool(); angle::WorkerThreadPool *getWorkerThreadPool();
virtual gl::Error applyComputeUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray) = 0;
bool isRobustResourceInitEnabled() const; bool isRobustResourceInitEnabled() const;
size_t getBoundFramebufferTextures(const gl::ContextState &data, size_t getBoundFramebufferTextures(const gl::ContextState &data,
......
...@@ -2119,171 +2119,6 @@ gl::Error Renderer11::drawTriangleFan(const gl::ContextState &data, ...@@ -2119,171 +2119,6 @@ gl::Error Renderer11::drawTriangleFan(const gl::ContextState &data,
return gl::NoError(); return gl::NoError();
} }
// TODO(jmadill): Move to StateManager11.
gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray)
{
UniformStorage11 *vertexUniformStorage =
GetAs<UniformStorage11>(&programD3D.getVertexUniformStorage());
UniformStorage11 *fragmentUniformStorage =
GetAs<UniformStorage11>(&programD3D.getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
ASSERT(fragmentUniformStorage);
const d3d11::Buffer *vertexConstantBuffer = nullptr;
ANGLE_TRY(vertexUniformStorage->getConstantBuffer(this, &vertexConstantBuffer));
const d3d11::Buffer *pixelConstantBuffer = nullptr;
ANGLE_TRY(fragmentUniformStorage->getConstantBuffer(this, &pixelConstantBuffer));
bool uniformsDirty = programD3D.areUniformsDirty();
if (vertexUniformStorage->size() > 0 && uniformsDirty)
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
mDeviceContext->Map(vertexConstantBuffer->get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
ASSERT(SUCCEEDED(result));
memcpy(map.pData, vertexUniformStorage->getDataPointer(0, 0), vertexUniformStorage->size());
mDeviceContext->Unmap(vertexConstantBuffer->get(), 0);
}
if (fragmentUniformStorage->size() > 0 && uniformsDirty)
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
mDeviceContext->Map(pixelConstantBuffer->get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
ASSERT(SUCCEEDED(result));
memcpy(map.pData, fragmentUniformStorage->getDataPointer(0, 0),
fragmentUniformStorage->size());
mDeviceContext->Unmap(pixelConstantBuffer->get(), 0);
}
ID3D11Buffer *appliedVertexConstants = vertexConstantBuffer->get();
if (mCurrentVertexConstantBuffer != reinterpret_cast<uintptr_t>(appliedVertexConstants))
{
mDeviceContext->VSSetConstantBuffers(
d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &appliedVertexConstants);
mCurrentVertexConstantBuffer = reinterpret_cast<uintptr_t>(appliedVertexConstants);
}
ID3D11Buffer *appliedPixelConstants = pixelConstantBuffer->get();
if (mCurrentPixelConstantBuffer != reinterpret_cast<uintptr_t>(appliedPixelConstants))
{
mDeviceContext->PSSetConstantBuffers(
d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &appliedPixelConstants);
mCurrentPixelConstantBuffer = reinterpret_cast<uintptr_t>(appliedPixelConstants);
}
return gl::NoError();
}
gl::Error Renderer11::applyDriverUniforms(const ProgramD3D &programD3D, GLenum drawMode)
{
auto *samplerMetadataVS = mStateManager.getVertexSamplerMetadata();
auto *samplerMetadataPS = mStateManager.getPixelSamplerMetadata();
if (!mDriverConstantBufferVS.valid())
{
D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc(
&constantBufferDescription,
sizeof(dx_VertexConstants11) + samplerMetadataVS->sizeBytes());
ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferVS));
ID3D11Buffer *driverVSConstants = mDriverConstantBufferVS.get();
mDeviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
&driverVSConstants);
}
if (!mDriverConstantBufferPS.valid())
{
D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc(&constantBufferDescription,
sizeof(dx_PixelConstants11) + samplerMetadataPS->sizeBytes());
ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferPS));
ID3D11Buffer *driverVSConstants = mDriverConstantBufferPS.get();
mDeviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
&driverVSConstants);
}
// Sampler metadata and driver constants need to coexist in the same constant buffer to conserve
// constant buffer slots. We update both in the constant buffer if needed.
const dx_VertexConstants11 &vertexConstants = mStateManager.getVertexConstants();
size_t samplerMetadataReferencedBytesVS = sizeof(SamplerMetadata11::dx_SamplerMetadata) *
programD3D.getUsedSamplerRange(gl::SAMPLER_VERTEX);
applyDriverConstantsIfNeeded(&mAppliedVertexConstants, vertexConstants, samplerMetadataVS,
samplerMetadataReferencedBytesVS, mDriverConstantBufferVS);
const dx_PixelConstants11 &pixelConstants = mStateManager.getPixelConstants();
size_t samplerMetadataReferencedBytesPS = sizeof(SamplerMetadata11::dx_SamplerMetadata) *
programD3D.getUsedSamplerRange(gl::SAMPLER_PIXEL);
applyDriverConstantsIfNeeded(&mAppliedPixelConstants, pixelConstants, samplerMetadataPS,
samplerMetadataReferencedBytesPS, mDriverConstantBufferPS);
// GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
if (programD3D.usesGeometryShader(drawMode))
{
// needed for the point sprite geometry shader
ID3D11Buffer *appliedGeometryConstants = mDriverConstantBufferPS.get();
if (mCurrentGeometryConstantBuffer != reinterpret_cast<uintptr_t>(appliedGeometryConstants))
{
ASSERT(mDriverConstantBufferPS.valid());
mDeviceContext->GSSetConstantBuffers(0, 1, &appliedGeometryConstants);
mCurrentGeometryConstantBuffer = reinterpret_cast<uintptr_t>(appliedGeometryConstants);
}
}
return gl::NoError();
}
template <class TShaderConstants>
void Renderer11::applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants,
const TShaderConstants &constants,
SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer)
{
ASSERT(driverConstantBuffer.valid());
if (memcmp(appliedConstants, &constants, sizeof(TShaderConstants)) != 0 ||
samplerMetadata->isDirty())
{
memcpy(appliedConstants, &constants, sizeof(TShaderConstants));
D3D11_MAPPED_SUBRESOURCE mapping = {0};
HRESULT result = mDeviceContext->Map(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD,
0, &mapping);
ASSERT(SUCCEEDED(result));
memcpy(mapping.pData, appliedConstants, sizeof(TShaderConstants));
// Previous buffer contents were discarded, so we need to refresh also the area of the
// buffer that isn't used by this program.
memcpy(&reinterpret_cast<uint8_t *>(mapping.pData)[sizeof(TShaderConstants)],
samplerMetadata->getData(), samplerMetadata->sizeBytes());
mDeviceContext->Unmap(driverConstantBuffer.get(), 0);
samplerMetadata->markClean();
}
}
template void Renderer11::applyDriverConstantsIfNeeded<dx_VertexConstants11>(
dx_VertexConstants11 *appliedConstants,
const dx_VertexConstants11 &constants,
SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer);
template void Renderer11::applyDriverConstantsIfNeeded<dx_PixelConstants11>(
dx_PixelConstants11 *appliedConstants,
const dx_PixelConstants11 &constants,
SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer);
template void Renderer11::applyDriverConstantsIfNeeded<dx_ComputeConstants11>(
dx_ComputeConstants11 *appliedConstants,
const dx_ComputeConstants11 &constants,
SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer);
void Renderer11::markAllStateDirty(const gl::Context *context) void Renderer11::markAllStateDirty(const gl::Context *context)
{ {
TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty"); TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty");
...@@ -2292,9 +2127,6 @@ void Renderer11::markAllStateDirty(const gl::Context *context) ...@@ -2292,9 +2127,6 @@ void Renderer11::markAllStateDirty(const gl::Context *context)
mAppliedTFObject = angle::DirtyPointer; mAppliedTFObject = angle::DirtyPointer;
memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants11));
memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants11));
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++) for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++)
{ {
mCurrentConstantBufferVS[i] = static_cast<unsigned int>(-1); mCurrentConstantBufferVS[i] = static_cast<unsigned int>(-1);
...@@ -2305,10 +2137,6 @@ void Renderer11::markAllStateDirty(const gl::Context *context) ...@@ -2305,10 +2137,6 @@ void Renderer11::markAllStateDirty(const gl::Context *context)
mCurrentConstantBufferPSSize[i] = 0; mCurrentConstantBufferPSSize[i] = 0;
} }
mCurrentVertexConstantBuffer = angle::DirtyPointer;
mCurrentPixelConstantBuffer = angle::DirtyPointer;
mCurrentGeometryConstantBuffer = angle::DirtyPointer;
mCurrentComputeConstantBuffer = angle::DirtyPointer;
} }
void Renderer11::releaseDeviceResources() void Renderer11::releaseDeviceResources()
...@@ -2323,9 +2151,6 @@ void Renderer11::releaseDeviceResources() ...@@ -2323,9 +2151,6 @@ void Renderer11::releaseDeviceResources()
SafeDelete(mTrim); SafeDelete(mTrim);
SafeDelete(mPixelTransfer); SafeDelete(mPixelTransfer);
mDriverConstantBufferVS.reset();
mDriverConstantBufferPS.reset();
mDriverConstantBufferCS.reset();
mSyncQuery.reset(); mSyncQuery.reset();
mCachedResolveTexture.reset(); mCachedResolveTexture.reset();
...@@ -4249,8 +4074,9 @@ gl::Error Renderer11::applyComputeShader(const gl::Context *context) ...@@ -4249,8 +4074,9 @@ gl::Error Renderer11::applyComputeShader(const gl::Context *context)
ASSERT(computeExe != nullptr); ASSERT(computeExe != nullptr);
mStateManager.setComputeShader(&GetAs<ShaderExecutable11>(computeExe)->getComputeShader()); mStateManager.setComputeShader(&GetAs<ShaderExecutable11>(computeExe)->getComputeShader());
ANGLE_TRY(mStateManager.applyComputeUniforms(programD3D));
return programD3D->applyComputeUniforms(); return gl::NoError();
} }
gl::Error Renderer11::dispatchCompute(const gl::Context *context, gl::Error Renderer11::dispatchCompute(const gl::Context *context,
...@@ -4267,59 +4093,6 @@ gl::Error Renderer11::dispatchCompute(const gl::Context *context, ...@@ -4267,59 +4093,6 @@ gl::Error Renderer11::dispatchCompute(const gl::Context *context,
return gl::NoError(); return gl::NoError();
} }
gl::Error Renderer11::applyComputeUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray)
{
UniformStorage11 *computeUniformStorage =
GetAs<UniformStorage11>(&programD3D.getComputeUniformStorage());
ASSERT(computeUniformStorage);
const d3d11::Buffer *computeConstantBufferObj = nullptr;
ANGLE_TRY(computeUniformStorage->getConstantBuffer(this, &computeConstantBufferObj));
ID3D11Buffer *computeConstantBuffer = computeConstantBufferObj->get();
if (computeUniformStorage->size() > 0)
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
mDeviceContext->Map(computeConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
ASSERT(SUCCEEDED(result));
memcpy(map.pData, computeUniformStorage->getDataPointer(0, 0),
computeUniformStorage->size());
mDeviceContext->Unmap(computeConstantBuffer, 0);
}
if (mCurrentComputeConstantBuffer != reinterpret_cast<uintptr_t>(computeConstantBuffer))
{
mDeviceContext->CSSetConstantBuffers(
d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &computeConstantBuffer);
mCurrentComputeConstantBuffer = reinterpret_cast<uintptr_t>(computeConstantBuffer);
}
auto *samplerMetadataCS = mStateManager.getComputeSamplerMetadata();
if (!mDriverConstantBufferCS.valid())
{
D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc(
&constantBufferDescription,
sizeof(dx_ComputeConstants11) + samplerMetadataCS->sizeBytes());
ANGLE_TRY(allocateResource(constantBufferDescription, &mDriverConstantBufferCS));
ID3D11Buffer *buffer = mDriverConstantBufferCS.get();
mDeviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
&buffer);
}
const dx_ComputeConstants11 &computeConstants = mStateManager.getComputeConstants();
size_t samplerMetadataReferencedBytesCS = sizeof(SamplerMetadata11::dx_SamplerMetadata) *
programD3D.getUsedSamplerRange(gl::SAMPLER_COMPUTE);
applyDriverConstantsIfNeeded(&mAppliedComputeConstants, computeConstants, samplerMetadataCS,
samplerMetadataReferencedBytesCS, mDriverConstantBufferCS);
return gl::NoError();
}
gl::ErrorOrResult<TextureHelper11> Renderer11::createStagingTexture( gl::ErrorOrResult<TextureHelper11> Renderer11::createStagingTexture(
ResourceType textureType, ResourceType textureType,
const d3d11::Format &formatSet, const d3d11::Format &formatSet,
......
...@@ -151,11 +151,6 @@ class Renderer11 : public RendererD3D ...@@ -151,11 +151,6 @@ class Renderer11 : public RendererD3D
const std::vector<GLint> &fragmentUniformBuffers) override; const std::vector<GLint> &fragmentUniformBuffers) override;
bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize); bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
gl::Error applyUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray) override;
gl::Error applyDriverUniforms(const ProgramD3D &programD3D, GLenum drawMode);
gl::Error applyTransformFeedbackBuffers(const gl::ContextState &data); gl::Error applyTransformFeedbackBuffers(const gl::ContextState &data);
// lost device // lost device
...@@ -419,8 +414,6 @@ class Renderer11 : public RendererD3D ...@@ -419,8 +414,6 @@ class Renderer11 : public RendererD3D
GLuint numGroupsX, GLuint numGroupsX,
GLuint numGroupsY, GLuint numGroupsY,
GLuint numGroupsZ); GLuint numGroupsZ);
gl::Error applyComputeUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray) override;
gl::Error applyComputeShader(const gl::Context *context); gl::Error applyComputeShader(const gl::Context *context);
gl::ErrorOrResult<TextureHelper11> createStagingTexture(ResourceType textureType, gl::ErrorOrResult<TextureHelper11> createStagingTexture(ResourceType textureType,
...@@ -518,13 +511,6 @@ class Renderer11 : public RendererD3D ...@@ -518,13 +511,6 @@ class Renderer11 : public RendererD3D
void updateHistograms(); void updateHistograms();
template <class TShaderConstants>
void applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants,
const TShaderConstants &constants,
SamplerMetadata11 *samplerMetadata,
size_t samplerMetadataReferencedBytes,
const d3d11::Buffer &driverConstantBuffer);
gl::Error copyImageInternal(const gl::Context *context, gl::Error copyImageInternal(const gl::Context *context,
const gl::Framebuffer *framebuffer, const gl::Framebuffer *framebuffer,
const gl::Rectangle &sourceRect, const gl::Rectangle &sourceRect,
...@@ -561,26 +547,13 @@ class Renderer11 : public RendererD3D ...@@ -561,26 +547,13 @@ class Renderer11 : public RendererD3D
// Currently applied transform feedback buffers // Currently applied transform feedback buffers
uintptr_t mAppliedTFObject; uintptr_t mAppliedTFObject;
dx_VertexConstants11 mAppliedVertexConstants;
d3d11::Buffer mDriverConstantBufferVS;
uintptr_t mCurrentVertexConstantBuffer;
unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
GLsizeiptr mCurrentConstantBufferVSSize[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; GLsizeiptr mCurrentConstantBufferVSSize[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
dx_PixelConstants11 mAppliedPixelConstants;
d3d11::Buffer mDriverConstantBufferPS;
uintptr_t mCurrentPixelConstantBuffer;
unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
GLintptr mCurrentConstantBufferPSOffset[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; GLintptr mCurrentConstantBufferPSOffset[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
GLsizeiptr mCurrentConstantBufferPSSize[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; GLsizeiptr mCurrentConstantBufferPSSize[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
dx_ComputeConstants11 mAppliedComputeConstants;
d3d11::Buffer mDriverConstantBufferCS;
uintptr_t mCurrentComputeConstantBuffer;
uintptr_t mCurrentGeometryConstantBuffer;
StreamingIndexBufferInterface *mLineLoopIB; StreamingIndexBufferInterface *mLineLoopIB;
StreamingIndexBufferInterface *mTriangleFanIB; StreamingIndexBufferInterface *mTriangleFanIB;
......
...@@ -208,30 +208,61 @@ void StateManager11::SRVCache::clear() ...@@ -208,30 +208,61 @@ void StateManager11::SRVCache::clear()
mHighestUsedSRV = 0; mHighestUsedSRV = 0;
} }
// SamplerMetadataD3D11 implementation // ShaderConstants11 implementation
SamplerMetadata11::SamplerMetadata11() : mDirty(true) ShaderConstants11::ShaderConstants11()
: mVertexDirty(true),
mPixelDirty(true),
mComputeDirty(true),
mSamplerMetadataVSDirty(true),
mSamplerMetadataPSDirty(true),
mSamplerMetadataCSDirty(true)
{ {
} }
SamplerMetadata11::~SamplerMetadata11() void ShaderConstants11::init(const gl::Caps &caps)
{ {
mSamplerMetadataVS.resize(caps.maxVertexTextureImageUnits);
mSamplerMetadataPS.resize(caps.maxTextureImageUnits);
mSamplerMetadataCS.resize(caps.maxComputeTextureImageUnits);
} }
void SamplerMetadata11::initData(unsigned int samplerCount) size_t ShaderConstants11::getRequiredBufferSize(gl::SamplerType samplerType) const
{ {
mSamplerMetadata.resize(samplerCount); switch (samplerType)
{
case gl::SAMPLER_VERTEX:
return sizeof(Vertex) + mSamplerMetadataVS.size() * sizeof(SamplerMetadata);
case gl::SAMPLER_PIXEL:
return sizeof(Pixel) + mSamplerMetadataPS.size() * sizeof(SamplerMetadata);
case gl::SAMPLER_COMPUTE:
return sizeof(Compute) + mSamplerMetadataCS.size() * sizeof(SamplerMetadata);
default:
UNREACHABLE();
return 0;
}
}
void ShaderConstants11::markDirty()
{
mVertexDirty = true;
mPixelDirty = true;
mComputeDirty = true;
mSamplerMetadataVSDirty = true;
mSamplerMetadataPSDirty = true;
mSamplerMetadataCSDirty = true;
} }
void SamplerMetadata11::update(unsigned int samplerIndex, const gl::Texture &texture) bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data, const gl::Texture &texture)
{ {
bool dirty = false;
unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel(); unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel();
GLenum sizedFormat = GLenum sizedFormat =
texture.getFormat(texture.getTarget(), baseLevel).info->sizedInternalFormat; texture.getFormat(texture.getTarget(), baseLevel).info->sizedInternalFormat;
if (mSamplerMetadata[samplerIndex].baseLevel != static_cast<int>(baseLevel)) if (data->baseLevel != static_cast<int>(baseLevel))
{ {
mSamplerMetadata[samplerIndex].baseLevel = static_cast<int>(baseLevel); data->baseLevel = static_cast<int>(baseLevel);
mDirty = true; dirty = true;
} }
// Some metadata is needed only for integer textures. We avoid updating the constant buffer // Some metadata is needed only for integer textures. We avoid updating the constant buffer
...@@ -283,10 +314,10 @@ void SamplerMetadata11::update(unsigned int samplerIndex, const gl::Texture &tex ...@@ -283,10 +314,10 @@ void SamplerMetadata11::update(unsigned int samplerIndex, const gl::Texture &tex
} }
if (needIntegerTextureMetadata) if (needIntegerTextureMetadata)
{ {
if (mSamplerMetadata[samplerIndex].internalFormatBits != internalFormatBits) if (data->internalFormatBits != internalFormatBits)
{ {
mSamplerMetadata[samplerIndex].internalFormatBits = internalFormatBits; data->internalFormatBits = internalFormatBits;
mDirty = true; dirty = true;
} }
// Pack the wrap values into one integer so we can fit all the metadata in one 4-integer // Pack the wrap values into one integer so we can fit all the metadata in one 4-integer
// vector. // vector.
...@@ -294,22 +325,187 @@ void SamplerMetadata11::update(unsigned int samplerIndex, const gl::Texture &tex ...@@ -294,22 +325,187 @@ void SamplerMetadata11::update(unsigned int samplerIndex, const gl::Texture &tex
GLenum wrapT = texture.getWrapT(); GLenum wrapT = texture.getWrapT();
GLenum wrapR = texture.getWrapR(); GLenum wrapR = texture.getWrapR();
int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4); int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4);
if (mSamplerMetadata[samplerIndex].wrapModes != wrapModes) if (data->wrapModes != wrapModes)
{ {
mSamplerMetadata[samplerIndex].wrapModes = wrapModes; data->wrapModes = wrapModes;
mDirty = true; dirty = true;
} }
} }
return dirty;
} }
const SamplerMetadata11::dx_SamplerMetadata *SamplerMetadata11::getData() const void ShaderConstants11::setComputeWorkGroups(GLuint numGroupsX,
GLuint numGroupsY,
GLuint numGroupsZ)
{ {
return mSamplerMetadata.data(); mCompute.numWorkGroups[0] = numGroupsX;
mCompute.numWorkGroups[1] = numGroupsY;
mCompute.numWorkGroups[2] = numGroupsZ;
mComputeDirty = true;
} }
size_t SamplerMetadata11::sizeBytes() const void ShaderConstants11::setMultiviewWriteToViewportIndex(GLfloat index)
{ {
return sizeof(dx_SamplerMetadata) * mSamplerMetadata.size(); mVertex.multiviewWriteToViewportIndex = index;
mVertexDirty = true;
mPixel.multiviewWriteToViewportIndex = index;
mPixelDirty = true;
}
void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport,
const D3D11_VIEWPORT &dxViewport,
bool is9_3,
bool presentPathFast)
{
mVertexDirty = true;
mPixelDirty = true;
// On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
// using viewAdjust (like the D3D9 renderer).
if (is9_3)
{
mVertex.viewAdjust[0] = static_cast<float>((glViewport.width - dxViewport.Width) +
2 * (glViewport.x - dxViewport.TopLeftX)) /
dxViewport.Width;
mVertex.viewAdjust[1] = static_cast<float>((glViewport.height - dxViewport.Height) +
2 * (glViewport.y - dxViewport.TopLeftY)) /
dxViewport.Height;
mVertex.viewAdjust[2] = static_cast<float>(glViewport.width) / dxViewport.Width;
mVertex.viewAdjust[3] = static_cast<float>(glViewport.height) / dxViewport.Height;
}
mPixel.viewCoords[0] = glViewport.width * 0.5f;
mPixel.viewCoords[1] = glViewport.height * 0.5f;
mPixel.viewCoords[2] = glViewport.x + (glViewport.width * 0.5f);
mPixel.viewCoords[3] = glViewport.y + (glViewport.height * 0.5f);
// Instanced pointsprite emulation requires ViewCoords to be defined in the
// the vertex shader.
mVertex.viewCoords[0] = mPixel.viewCoords[0];
mVertex.viewCoords[1] = mPixel.viewCoords[1];
mVertex.viewCoords[2] = mPixel.viewCoords[2];
mVertex.viewCoords[3] = mPixel.viewCoords[3];
const float zNear = dxViewport.MinDepth;
const float zFar = dxViewport.MaxDepth;
mPixel.depthFront[0] = (zFar - zNear) * 0.5f;
mPixel.depthFront[1] = (zNear + zFar) * 0.5f;
mVertex.depthRange[0] = zNear;
mVertex.depthRange[1] = zFar;
mVertex.depthRange[2] = zFar - zNear;
mPixel.depthRange[0] = zNear;
mPixel.depthRange[1] = zFar;
mPixel.depthRange[2] = zFar - zNear;
mPixel.viewScale[0] = 1.0f;
mPixel.viewScale[1] = presentPathFast ? 1.0f : -1.0f;
// Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw
// framebuffer's layout is changed.
mVertex.viewScale[0] = mPixel.viewScale[0];
mVertex.viewScale[1] = mPixel.viewScale[1];
}
void ShaderConstants11::onSamplerChange(gl::SamplerType samplerType,
unsigned int samplerIndex,
const gl::Texture &texture)
{
switch (samplerType)
{
case gl::SAMPLER_VERTEX:
if (updateSamplerMetadata(&mSamplerMetadataVS[samplerIndex], texture))
{
mSamplerMetadataVSDirty = true;
}
break;
case gl::SAMPLER_PIXEL:
if (updateSamplerMetadata(&mSamplerMetadataPS[samplerIndex], texture))
{
mSamplerMetadataPSDirty = true;
}
break;
case gl::SAMPLER_COMPUTE:
if (updateSamplerMetadata(&mSamplerMetadataCS[samplerIndex], texture))
{
mSamplerMetadataCSDirty = true;
}
break;
default:
UNREACHABLE();
break;
}
}
gl::Error ShaderConstants11::updateBuffer(ID3D11DeviceContext *deviceContext,
gl::SamplerType samplerType,
const ProgramD3D &programD3D,
const d3d11::Buffer &driverConstantBuffer)
{
bool dirty = false;
size_t dataSize = 0;
const uint8_t *data = nullptr;
const uint8_t *samplerData = nullptr;
switch (samplerType)
{
case gl::SAMPLER_VERTEX:
dirty = mVertexDirty || mSamplerMetadataVSDirty;
dataSize = sizeof(Vertex);
data = reinterpret_cast<const uint8_t *>(&mVertex);
samplerData = reinterpret_cast<const uint8_t *>(mSamplerMetadataVS.data());
mVertexDirty = false;
mSamplerMetadataVSDirty = false;
break;
case gl::SAMPLER_PIXEL:
dirty = mPixelDirty || mSamplerMetadataPSDirty;
dataSize = sizeof(Pixel);
data = reinterpret_cast<const uint8_t *>(&mPixel);
samplerData = reinterpret_cast<const uint8_t *>(mSamplerMetadataPS.data());
mPixelDirty = false;
mSamplerMetadataPSDirty = false;
break;
case gl::SAMPLER_COMPUTE:
dirty = mComputeDirty || mSamplerMetadataCSDirty;
dataSize = sizeof(Compute);
data = reinterpret_cast<const uint8_t *>(&mCompute);
samplerData = reinterpret_cast<const uint8_t *>(mSamplerMetadataCS.data());
mComputeDirty = false;
mSamplerMetadataCSDirty = false;
break;
default:
UNREACHABLE();
break;
}
ASSERT(driverConstantBuffer.valid());
if (!dirty)
{
return gl::NoError();
}
// Previous buffer contents are discarded, so we need to refresh the whole buffer.
D3D11_MAPPED_SUBRESOURCE mapping = {0};
HRESULT result =
deviceContext->Map(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping);
if (FAILED(result))
{
return gl::OutOfMemory() << "Internal error mapping constant buffer: " << gl::FmtHR(result);
}
size_t samplerDataBytes = sizeof(SamplerMetadata) * programD3D.getUsedSamplerRange(samplerType);
memcpy(mapping.pData, data, dataSize);
memcpy(reinterpret_cast<uint8_t *>(mapping.pData) + dataSize, samplerData, samplerDataBytes);
deviceContext->Unmap(driverConstantBuffer.get(), 0);
return gl::NoError();
} }
static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
...@@ -442,9 +638,7 @@ gl::Error StateManager11::updateStateForCompute(const gl::Context *context, ...@@ -442,9 +638,7 @@ gl::Error StateManager11::updateStateForCompute(const gl::Context *context,
GLuint numGroupsY, GLuint numGroupsY,
GLuint numGroupsZ) GLuint numGroupsZ)
{ {
mComputeConstants.numWorkGroups[0] = numGroupsX; mShaderConstants.setComputeWorkGroups(numGroupsX, numGroupsY, numGroupsZ);
mComputeConstants.numWorkGroups[1] = numGroupsY;
mComputeConstants.numWorkGroups[2] = numGroupsZ;
// TODO(jmadill): Use dirty bits. // TODO(jmadill): Use dirty bits.
const auto &glState = context->getGLState(); const auto &glState = context->getGLState();
...@@ -762,15 +956,13 @@ void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *con ...@@ -762,15 +956,13 @@ void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *con
switch (drawFramebuffer->getMultiviewLayout()) switch (drawFramebuffer->getMultiviewLayout())
{ {
case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE: case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE:
mVertexConstants.multiviewWriteToViewportIndex = 1.0f; mShaderConstants.setMultiviewWriteToViewportIndex(1.0f);
mPixelConstants.multiviewWriteToViewportIndex = 1.0f;
break; break;
case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE: case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE:
// Because the base view index is applied as an offset to the 2D texture array when the // Because the base view index is applied as an offset to the 2D texture array when the
// RTV is created, we just have to pass a boolean to select which code path is to be // RTV is created, we just have to pass a boolean to select which code path is to be
// used. // used.
mVertexConstants.multiviewWriteToViewportIndex = 0.0f; mShaderConstants.setMultiviewWriteToViewportIndex(0.0f);
mPixelConstants.multiviewWriteToViewportIndex = 0.0f;
break; break;
default: default:
// There is no need to update the value in the constant buffer if the active framebuffer // There is no need to update the value in the constant buffer if the active framebuffer
...@@ -958,7 +1150,9 @@ void StateManager11::syncViewport(const gl::Context *context) ...@@ -958,7 +1150,9 @@ void StateManager11::syncViewport(const gl::Context *context)
int dxMinViewportBoundsX = -dxMaxViewportBoundsX; int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
int dxMinViewportBoundsY = -dxMaxViewportBoundsY; int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) bool is9_3 = mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3;
if (is9_3)
{ {
// Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget. // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width); dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width);
...@@ -1032,51 +1226,13 @@ void StateManager11::syncViewport(const gl::Context *context) ...@@ -1032,51 +1226,13 @@ void StateManager11::syncViewport(const gl::Context *context)
mCurNear = actualZNear; mCurNear = actualZNear;
mCurFar = actualZFar; mCurFar = actualZFar;
// On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders const D3D11_VIEWPORT adjustViewport = {static_cast<FLOAT>(dxViewportTopLeftX),
// using viewAdjust (like the D3D9 renderer). static_cast<FLOAT>(dxViewportTopLeftY),
if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) static_cast<FLOAT>(dxViewportWidth),
{ static_cast<FLOAT>(dxViewportHeight),
const auto &dxViewport = dxViewports[0]; actualZNear,
mVertexConstants.viewAdjust[0] = static_cast<float>((viewport.width - dxViewportWidth) + actualZFar};
2 * (viewport.x - dxViewportTopLeftX)) / mShaderConstants.onViewportChange(viewport, adjustViewport, is9_3, mCurPresentPathFastEnabled);
dxViewport.Width;
mVertexConstants.viewAdjust[1] = static_cast<float>((viewport.height - dxViewportHeight) +
2 * (viewport.y - dxViewportTopLeftY)) /
dxViewport.Height;
mVertexConstants.viewAdjust[2] = static_cast<float>(viewport.width) / dxViewport.Width;
mVertexConstants.viewAdjust[3] = static_cast<float>(viewport.height) / dxViewport.Height;
}
mPixelConstants.viewCoords[0] = viewport.width * 0.5f;
mPixelConstants.viewCoords[1] = viewport.height * 0.5f;
mPixelConstants.viewCoords[2] = viewport.x + (viewport.width * 0.5f);
mPixelConstants.viewCoords[3] = viewport.y + (viewport.height * 0.5f);
// Instanced pointsprite emulation requires ViewCoords to be defined in the
// the vertex shader.
mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0];
mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1];
mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2];
mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3];
mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
mVertexConstants.depthRange[0] = actualZNear;
mVertexConstants.depthRange[1] = actualZFar;
mVertexConstants.depthRange[2] = actualZFar - actualZNear;
mPixelConstants.depthRange[0] = actualZNear;
mPixelConstants.depthRange[1] = actualZFar;
mPixelConstants.depthRange[2] = actualZFar - actualZNear;
mPixelConstants.viewScale[0] = 1.0f;
mPixelConstants.viewScale[1] = mCurPresentPathFastEnabled ? 1.0f : -1.0f;
// Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw
// framebuffer's layout is changed.
mVertexConstants.viewScale[0] = mPixelConstants.viewScale[0];
mVertexConstants.viewScale[1] = mPixelConstants.viewScale[1];
} }
void StateManager11::invalidateRenderTarget(const gl::Context *context) void StateManager11::invalidateRenderTarget(const gl::Context *context)
...@@ -1178,6 +1334,13 @@ void StateManager11::invalidateEverything(const gl::Context *context) ...@@ -1178,6 +1334,13 @@ void StateManager11::invalidateEverything(const gl::Context *context)
mLastFirstVertex.reset(); mLastFirstVertex.reset();
invalidateTexturesAndSamplers(); invalidateTexturesAndSamplers();
invalidateDriverUniforms();
mCurrentVertexConstantBuffer.dirty();
mCurrentPixelConstantBuffer.dirty();
mCurrentGeometryConstantBuffer.dirty();
mCurrentComputeConstantBuffer.dirty();
} }
void StateManager11::invalidateVertexBuffer() void StateManager11::invalidateVertexBuffer()
...@@ -1204,6 +1367,10 @@ void StateManager11::invalidateSwizzles() ...@@ -1204,6 +1367,10 @@ void StateManager11::invalidateSwizzles()
mDirtySwizzles = true; mDirtySwizzles = true;
} }
void StateManager11::invalidateDriverUniforms()
{
}
void StateManager11::setOneTimeRenderTarget(const gl::Context *context, void StateManager11::setOneTimeRenderTarget(const gl::Context *context,
ID3D11RenderTargetView *rtv, ID3D11RenderTargetView *rtv,
ID3D11DepthStencilView *dsv) ID3D11DepthStencilView *dsv)
...@@ -1371,9 +1538,7 @@ gl::Error StateManager11::initialize(const gl::Caps &caps, const gl::Extensions ...@@ -1371,9 +1538,7 @@ gl::Error StateManager11::initialize(const gl::Caps &caps, const gl::Extensions
mCurPixelSamplerStates.resize(caps.maxTextureImageUnits); mCurPixelSamplerStates.resize(caps.maxTextureImageUnits);
mCurComputeSamplerStates.resize(caps.maxComputeTextureImageUnits); mCurComputeSamplerStates.resize(caps.maxComputeTextureImageUnits);
mSamplerMetadataVS.initData(caps.maxVertexTextureImageUnits); mShaderConstants.init(caps);
mSamplerMetadataPS.initData(caps.maxTextureImageUnits);
mSamplerMetadataCS.initData(caps.maxComputeTextureImageUnits);
mIsMultiviewEnabled = extensions.multiview; mIsMultiviewEnabled = extensions.multiview;
mViewportOffsets.resize(1u); mViewportOffsets.resize(1u);
...@@ -1391,6 +1556,10 @@ void StateManager11::deinitialize() ...@@ -1391,6 +1556,10 @@ void StateManager11::deinitialize()
mInputLayoutCache.clear(); mInputLayoutCache.clear();
mVertexDataManager.deinitialize(); mVertexDataManager.deinitialize();
mIndexDataManager.deinitialize(); mIndexDataManager.deinitialize();
mDriverConstantBufferVS.reset();
mDriverConstantBufferPS.reset();
mDriverConstantBufferCS.reset();
} }
gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer) gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
...@@ -1680,8 +1849,8 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod ...@@ -1680,8 +1849,8 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
// This must happen after viewport sync, because the viewport affects builtin uniforms. // This must happen after viewport sync, because the viewport affects builtin uniforms.
// TODO(jmadill): Use dirty bits. // TODO(jmadill): Use dirty bits.
ANGLE_TRY(programD3D->applyUniforms()); ANGLE_TRY(applyUniforms(programD3D));
ANGLE_TRY(mRenderer->applyDriverUniforms(*programD3D, drawMode)); ANGLE_TRY(applyDriverUniforms(*programD3D, drawMode));
// Check that we haven't set any dirty bits in the flushing of the dirty bits loop. // Check that we haven't set any dirty bits in the flushing of the dirty bits loop.
ASSERT(mInternalDirtyBits.none()); ASSERT(mInternalDirtyBits.none());
...@@ -1852,11 +2021,6 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context, ...@@ -1852,11 +2021,6 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context,
ASSERT(storage); ASSERT(storage);
#endif // !defined(NDEBUG) #endif // !defined(NDEBUG)
// Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the
// sampler state since having it in contiguous memory makes it possible to memcpy to a constant
// buffer, and it doesn't affect the state set by PSSetSamplers/VSSetSamplers.
SamplerMetadata11 *metadata = nullptr;
auto *deviceContext = mRenderer->getDeviceContext(); auto *deviceContext = mRenderer->getDeviceContext();
if (type == gl::SAMPLER_PIXEL) if (type == gl::SAMPLER_PIXEL)
...@@ -1876,8 +2040,6 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context, ...@@ -1876,8 +2040,6 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context,
} }
mForceSetPixelSamplerStates[index] = false; mForceSetPixelSamplerStates[index] = false;
metadata = &mSamplerMetadataPS;
} }
else if (type == gl::SAMPLER_VERTEX) else if (type == gl::SAMPLER_VERTEX)
{ {
...@@ -1897,8 +2059,6 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context, ...@@ -1897,8 +2059,6 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context,
} }
mForceSetVertexSamplerStates[index] = false; mForceSetVertexSamplerStates[index] = false;
metadata = &mSamplerMetadataVS;
} }
else if (type == gl::SAMPLER_COMPUTE) else if (type == gl::SAMPLER_COMPUTE)
{ {
...@@ -1918,14 +2078,14 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context, ...@@ -1918,14 +2078,14 @@ gl::Error StateManager11::setSamplerState(const gl::Context *context,
} }
mForceSetComputeSamplerStates[index] = false; mForceSetComputeSamplerStates[index] = false;
metadata = &mSamplerMetadataCS;
} }
else else
UNREACHABLE(); UNREACHABLE();
ASSERT(metadata != nullptr); // Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the
metadata->update(index, *texture); // sampler state since having it in contiguous memory makes it possible to memcpy to a constant
// buffer, and it doesn't affect the state set by PSSetSamplers/VSSetSamplers.
mShaderConstants.onSamplerChange(type, index, *texture);
return gl::NoError(); return gl::NoError();
} }
...@@ -2223,4 +2383,168 @@ gl::Error StateManager11::generateSwizzles(const gl::Context *context) ...@@ -2223,4 +2383,168 @@ gl::Error StateManager11::generateSwizzles(const gl::Context *context)
return gl::NoError(); return gl::NoError();
} }
gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D)
{
UniformStorage11 *vertexUniformStorage =
GetAs<UniformStorage11>(&programD3D->getVertexUniformStorage());
UniformStorage11 *fragmentUniformStorage =
GetAs<UniformStorage11>(&programD3D->getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
ASSERT(fragmentUniformStorage);
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
const d3d11::Buffer *vertexConstantBuffer = nullptr;
ANGLE_TRY(vertexUniformStorage->getConstantBuffer(mRenderer, &vertexConstantBuffer));
const d3d11::Buffer *pixelConstantBuffer = nullptr;
ANGLE_TRY(fragmentUniformStorage->getConstantBuffer(mRenderer, &pixelConstantBuffer));
bool uniformsDirty = programD3D->areUniformsDirty();
if (vertexUniformStorage->size() > 0 && uniformsDirty)
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
deviceContext->Map(vertexConstantBuffer->get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
ASSERT(SUCCEEDED(result));
memcpy(map.pData, vertexUniformStorage->getDataPointer(0, 0), vertexUniformStorage->size());
deviceContext->Unmap(vertexConstantBuffer->get(), 0);
}
if (fragmentUniformStorage->size() > 0 && uniformsDirty)
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
deviceContext->Map(pixelConstantBuffer->get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
ASSERT(SUCCEEDED(result));
memcpy(map.pData, fragmentUniformStorage->getDataPointer(0, 0),
fragmentUniformStorage->size());
deviceContext->Unmap(pixelConstantBuffer->get(), 0);
}
ID3D11Buffer *appliedVertexConstants = vertexConstantBuffer->get();
if (mCurrentVertexConstantBuffer != reinterpret_cast<uintptr_t>(appliedVertexConstants))
{
deviceContext->VSSetConstantBuffers(
d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &appliedVertexConstants);
mCurrentVertexConstantBuffer = reinterpret_cast<uintptr_t>(appliedVertexConstants);
}
ID3D11Buffer *appliedPixelConstants = pixelConstantBuffer->get();
if (mCurrentPixelConstantBuffer != reinterpret_cast<uintptr_t>(appliedPixelConstants))
{
deviceContext->PSSetConstantBuffers(
d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &appliedPixelConstants);
mCurrentPixelConstantBuffer = reinterpret_cast<uintptr_t>(appliedPixelConstants);
}
programD3D->markUniformsClean();
return gl::NoError();
}
gl::Error StateManager11::applyDriverUniforms(const ProgramD3D &programD3D, GLenum drawMode)
{
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
if (!mDriverConstantBufferVS.valid())
{
size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_VERTEX);
D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferVS));
ID3D11Buffer *driverVSConstants = mDriverConstantBufferVS.get();
deviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
&driverVSConstants);
}
if (!mDriverConstantBufferPS.valid())
{
size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_PIXEL);
D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferPS));
ID3D11Buffer *driverVSConstants = mDriverConstantBufferPS.get();
deviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
&driverVSConstants);
}
// Sampler metadata and driver constants need to coexist in the same constant buffer to conserve
// constant buffer slots. We update both in the constant buffer if needed.
ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_VERTEX, programD3D,
mDriverConstantBufferVS));
ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_PIXEL, programD3D,
mDriverConstantBufferPS));
// GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
if (programD3D.usesGeometryShader(drawMode))
{
// needed for the point sprite geometry shader
ID3D11Buffer *appliedGeometryConstants = mDriverConstantBufferPS.get();
if (mCurrentGeometryConstantBuffer != reinterpret_cast<uintptr_t>(appliedGeometryConstants))
{
ASSERT(mDriverConstantBufferPS.valid());
deviceContext->GSSetConstantBuffers(0, 1, &appliedGeometryConstants);
mCurrentGeometryConstantBuffer = reinterpret_cast<uintptr_t>(appliedGeometryConstants);
}
}
return gl::NoError();
}
gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D)
{
UniformStorage11 *computeUniformStorage =
GetAs<UniformStorage11>(&programD3D->getComputeUniformStorage());
ASSERT(computeUniformStorage);
const d3d11::Buffer *computeConstantBufferObj = nullptr;
ANGLE_TRY(computeUniformStorage->getConstantBuffer(mRenderer, &computeConstantBufferObj));
ID3D11Buffer *computeConstantBuffer = computeConstantBufferObj->get();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
if (computeUniformStorage->size() > 0)
{
D3D11_MAPPED_SUBRESOURCE map = {0};
HRESULT result =
deviceContext->Map(computeConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
ASSERT(SUCCEEDED(result));
memcpy(map.pData, computeUniformStorage->getDataPointer(0, 0),
computeUniformStorage->size());
deviceContext->Unmap(computeConstantBuffer, 0);
}
if (mCurrentComputeConstantBuffer != reinterpret_cast<uintptr_t>(computeConstantBuffer))
{
deviceContext->CSSetConstantBuffers(
d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &computeConstantBuffer);
mCurrentComputeConstantBuffer = reinterpret_cast<uintptr_t>(computeConstantBuffer);
}
if (!mDriverConstantBufferCS.valid())
{
size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_COMPUTE);
D3D11_BUFFER_DESC constantBufferDescription = {0};
d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferCS));
ID3D11Buffer *buffer = mDriverConstantBufferCS.get();
deviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
&buffer);
}
ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_COMPUTE, *programD3D,
mDriverConstantBufferCS));
programD3D->markUniformsClean();
return gl::NoError();
}
} // namespace rx } // namespace rx
...@@ -27,9 +27,34 @@ namespace rx ...@@ -27,9 +27,34 @@ namespace rx
struct RenderTargetDesc; struct RenderTargetDesc;
struct Renderer11DeviceCaps; struct Renderer11DeviceCaps;
struct dx_VertexConstants11 class ShaderConstants11 : angle::NonCopyable
{ {
dx_VertexConstants11() public:
ShaderConstants11();
void init(const gl::Caps &caps);
size_t getRequiredBufferSize(gl::SamplerType samplerType) const;
void markDirty();
void setComputeWorkGroups(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
void setMultiviewWriteToViewportIndex(GLfloat index);
void onViewportChange(const gl::Rectangle &glViewport,
const D3D11_VIEWPORT &dxViewport,
bool is9_3,
bool presentPathFast);
void onSamplerChange(gl::SamplerType samplerType,
unsigned int samplerIndex,
const gl::Texture &texture);
gl::Error updateBuffer(ID3D11DeviceContext *deviceContext,
gl::SamplerType samplerType,
const ProgramD3D &programD3D,
const d3d11::Buffer &driverConstantBuffer);
private:
struct Vertex
{
Vertex()
: depthRange{.0f}, : depthRange{.0f},
viewAdjust{.0f}, viewAdjust{.0f},
viewCoords{.0f}, viewCoords{.0f},
...@@ -38,28 +63,29 @@ struct dx_VertexConstants11 ...@@ -38,28 +63,29 @@ struct dx_VertexConstants11
padding{.0f} padding{.0f}
{ {
} }
float depthRange[4]; float depthRange[4];
float viewAdjust[4]; float viewAdjust[4];
float viewCoords[4]; float viewCoords[4];
float viewScale[2]; float viewScale[2];
// multiviewWriteToViewportIndex is used to select either the side-by-side or layered code-path // multiviewWriteToViewportIndex is used to select either the side-by-side or layered
// in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated whenever a // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated
// multi-view draw framebuffer is made active. // whenever a multi-view draw framebuffer is made active.
float multiviewWriteToViewportIndex; float multiviewWriteToViewportIndex;
// Added here to manually pad the struct. // Added here to manually pad the struct.
float padding; float padding;
}; };
struct dx_PixelConstants11 struct Pixel
{ {
dx_PixelConstants11() Pixel()
: depthRange{.0f}, : depthRange{.0f},
viewCoords{.0f}, viewCoords{.0f},
depthFront{.0f}, depthFront{.0f},
viewScale{.0f}, viewScale{.0f},
multiviewWriteToViewportIndex{.0f}, multiviewWriteToViewportIndex(0),
padding{.0f} padding(0)
{ {
} }
...@@ -67,49 +93,51 @@ struct dx_PixelConstants11 ...@@ -67,49 +93,51 @@ struct dx_PixelConstants11
float viewCoords[4]; float viewCoords[4];
float depthFront[4]; float depthFront[4];
float viewScale[2]; float viewScale[2];
// multiviewWriteToViewportIndex is used to select either the side-by-side or layered code-path // multiviewWriteToViewportIndex is used to select either the side-by-side or layered
// in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated whenever a // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated
// multi-view draw framebuffer is made active. // whenever a multi-view draw framebuffer is made active.
float multiviewWriteToViewportIndex; float multiviewWriteToViewportIndex;
// Added here to manually pad the struct. // Added here to manually pad the struct.
float padding; float padding;
}; };
struct dx_ComputeConstants11 struct Compute
{ {
dx_ComputeConstants11() : numWorkGroups{0u}, padding{0u} {} Compute() : numWorkGroups{0u}, padding(0u) {}
unsigned int numWorkGroups[3]; unsigned int numWorkGroups[3];
unsigned int padding; // This just pads the struct to 16 bytes unsigned int padding; // This just pads the struct to 16 bytes
}; };
class SamplerMetadata11 final : angle::NonCopyable
{
public:
SamplerMetadata11();
~SamplerMetadata11();
struct dx_SamplerMetadata struct SamplerMetadata
{ {
SamplerMetadata() : baseLevel(0), internalFormatBits(0), wrapModes(0), padding(0) {}
int baseLevel; int baseLevel;
int internalFormatBits; int internalFormatBits;
int wrapModes; int wrapModes;
int padding; // This just pads the struct to 16 bytes int padding; // This just pads the struct to 16 bytes
}; };
static_assert(sizeof(dx_SamplerMetadata) == 16u,
"Sampler metadata struct must be one 4-vec / 16 bytes.");
void initData(unsigned int samplerCount);
void update(unsigned int samplerIndex, const gl::Texture &texture);
const dx_SamplerMetadata *getData() const; static_assert(sizeof(SamplerMetadata) == 16u,
size_t sizeBytes() const; "Sampler metadata struct must be one 4-vec / 16 bytes.");
bool isDirty() const { return mDirty; }
void markClean() { mDirty = false; }
private: // Return true if dirty.
std::vector<dx_SamplerMetadata> mSamplerMetadata; bool updateSamplerMetadata(SamplerMetadata *data, const gl::Texture &texture);
bool mDirty;
Vertex mVertex;
bool mVertexDirty;
Pixel mPixel;
bool mPixelDirty;
Compute mCompute;
bool mComputeDirty;
std::vector<SamplerMetadata> mSamplerMetadataVS;
bool mSamplerMetadataVSDirty;
std::vector<SamplerMetadata> mSamplerMetadataPS;
bool mSamplerMetadataPSDirty;
std::vector<SamplerMetadata> mSamplerMetadataCS;
bool mSamplerMetadataCSDirty;
}; };
class StateManager11 final : angle::NonCopyable class StateManager11 final : angle::NonCopyable
...@@ -123,15 +151,6 @@ class StateManager11 final : angle::NonCopyable ...@@ -123,15 +151,6 @@ class StateManager11 final : angle::NonCopyable
void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits); void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits);
// TODO(jmadill): Don't expose these.
const dx_VertexConstants11 &getVertexConstants() const { return mVertexConstants; }
const dx_PixelConstants11 &getPixelConstants() const { return mPixelConstants; }
const dx_ComputeConstants11 &getComputeConstants() const { return mComputeConstants; }
SamplerMetadata11 *getVertexSamplerMetadata() { return &mSamplerMetadataVS; }
SamplerMetadata11 *getPixelSamplerMetadata() { return &mSamplerMetadataPS; }
SamplerMetadata11 *getComputeSamplerMetadata() { return &mSamplerMetadataCS; }
gl::Error updateStateForCompute(const gl::Context *context, gl::Error updateStateForCompute(const gl::Context *context,
GLuint numGroupsX, GLuint numGroupsX,
GLuint numGroupsY, GLuint numGroupsY,
...@@ -152,6 +171,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -152,6 +171,7 @@ class StateManager11 final : angle::NonCopyable
void invalidateViewport(const gl::Context *context); void invalidateViewport(const gl::Context *context);
void invalidateTexturesAndSamplers(); void invalidateTexturesAndSamplers();
void invalidateSwizzles(); void invalidateSwizzles();
void invalidateDriverUniforms();
// Called from VertexArray11::updateVertexAttribStorage. // Called from VertexArray11::updateVertexAttribStorage.
void invalidateCurrentValueAttrib(size_t attribIndex); void invalidateCurrentValueAttrib(size_t attribIndex);
...@@ -214,6 +234,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -214,6 +234,9 @@ class StateManager11 final : angle::NonCopyable
gl::Error updateVertexOffsetsForPointSpritesEmulation(GLint startVertex, gl::Error updateVertexOffsetsForPointSpritesEmulation(GLint startVertex,
GLsizei emulatedInstanceId); GLsizei emulatedInstanceId);
// TODO(jmadill): Should be private.
gl::Error applyComputeUniforms(ProgramD3D *programD3D);
// Only used in testing. // Only used in testing.
InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
...@@ -269,6 +292,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -269,6 +292,9 @@ class StateManager11 final : angle::NonCopyable
gl::Error generateSwizzlesForShader(const gl::Context *context, gl::SamplerType type); gl::Error generateSwizzlesForShader(const gl::Context *context, gl::SamplerType type);
gl::Error generateSwizzles(const gl::Context *context); gl::Error generateSwizzles(const gl::Context *context);
gl::Error applyDriverUniforms(const ProgramD3D &programD3D, GLenum drawMode);
gl::Error applyUniforms(ProgramD3D *programD3D);
enum DirtyBitType enum DirtyBitType
{ {
DIRTY_BIT_RENDER_TARGET, DIRTY_BIT_RENDER_TARGET,
...@@ -320,10 +346,7 @@ class StateManager11 final : angle::NonCopyable ...@@ -320,10 +346,7 @@ class StateManager11 final : angle::NonCopyable
std::vector<gl::Offset> mViewportOffsets; std::vector<gl::Offset> mViewportOffsets;
// Things needed in viewport state // Things needed in viewport state
dx_VertexConstants11 mVertexConstants; ShaderConstants11 mShaderConstants;
dx_PixelConstants11 mPixelConstants;
dx_ComputeConstants11 mComputeConstants;
// Render target variables // Render target variables
gl::Extents mViewportBounds; gl::Extents mViewportBounds;
...@@ -406,10 +429,6 @@ class StateManager11 final : angle::NonCopyable ...@@ -406,10 +429,6 @@ class StateManager11 final : angle::NonCopyable
std::vector<bool> mForceSetComputeSamplerStates; std::vector<bool> mForceSetComputeSamplerStates;
std::vector<gl::SamplerState> mCurComputeSamplerStates; std::vector<gl::SamplerState> mCurComputeSamplerStates;
SamplerMetadata11 mSamplerMetadataVS;
SamplerMetadata11 mSamplerMetadataPS;
SamplerMetadata11 mSamplerMetadataCS;
// Special dirty bit for swizzles. Since they use internal shaders, must be done in a pre-pass. // Special dirty bit for swizzles. Since they use internal shaders, must be done in a pre-pass.
bool mDirtySwizzles; bool mDirtySwizzles;
...@@ -428,6 +447,16 @@ class StateManager11 final : angle::NonCopyable ...@@ -428,6 +447,16 @@ class StateManager11 final : angle::NonCopyable
// ANGLE_multiview. // ANGLE_multiview.
bool mIsMultiviewEnabled; bool mIsMultiviewEnabled;
// Driver Constants.
d3d11::Buffer mDriverConstantBufferVS;
d3d11::Buffer mDriverConstantBufferPS;
d3d11::Buffer mDriverConstantBufferCS;
ResourceSerial mCurrentVertexConstantBuffer;
ResourceSerial mCurrentPixelConstantBuffer;
ResourceSerial mCurrentComputeConstantBuffer;
ResourceSerial mCurrentGeometryConstantBuffer;
}; };
} // namespace rx } // namespace rx
......
...@@ -1842,7 +1842,7 @@ gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode) ...@@ -1842,7 +1842,7 @@ gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode)
mAppliedProgramSerial = programSerial; mAppliedProgramSerial = programSerial;
} }
ANGLE_TRY(programD3D->applyUniforms()); ANGLE_TRY(applyUniforms(programD3D));
// Driver uniforms // Driver uniforms
mStateManager.setShaderConstants(); mStateManager.setShaderConstants();
...@@ -1850,16 +1850,18 @@ gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode) ...@@ -1850,16 +1850,18 @@ gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode)
return gl::NoError(); return gl::NoError();
} }
gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D)
const std::vector<D3DUniform *> &uniformArray)
{ {
for (const D3DUniform *targetUniform : uniformArray) // Skip updates if we're not dirty.
if (!programD3D->areUniformsDirty())
{ {
// Built-in uniforms must be skipped. return gl::NoError();
if (!targetUniform->isReferencedByFragmentShader() && }
!targetUniform->isReferencedByVertexShader())
continue;
const auto &uniformArray = programD3D->getD3DUniforms();
for (const D3DUniform *targetUniform : uniformArray)
{
// Built-in uniforms must be skipped. // Built-in uniforms must be skipped.
if (!targetUniform->isReferencedByFragmentShader() && if (!targetUniform->isReferencedByFragmentShader() &&
!targetUniform->isReferencedByVertexShader()) !targetUniform->isReferencedByVertexShader())
...@@ -1900,6 +1902,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, ...@@ -1900,6 +1902,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
} }
} }
programD3D->markUniformsClean();
return gl::NoError(); return gl::NoError();
} }
...@@ -3225,13 +3228,6 @@ gl::Version Renderer9::getMaxSupportedESVersion() const ...@@ -3225,13 +3228,6 @@ gl::Version Renderer9::getMaxSupportedESVersion() const
return gl::Version(2, 0); return gl::Version(2, 0);
} }
gl::Error Renderer9::applyComputeUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray)
{
UNIMPLEMENTED();
return gl::InternalError() << "Compute shader is not implemented on D3D9";
}
gl::Error Renderer9::clearRenderTarget(RenderTargetD3D *renderTarget, gl::Error Renderer9::clearRenderTarget(RenderTargetD3D *renderTarget,
const gl::ColorF &clearColorValue, const gl::ColorF &clearColorValue,
const float clearDepthValue, const float clearDepthValue,
......
...@@ -147,8 +147,7 @@ class Renderer9 : public RendererD3D ...@@ -147,8 +147,7 @@ class Renderer9 : public RendererD3D
gl::Error applyRenderTarget(const gl::Context *context, gl::Error applyRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *colorAttachment, const gl::FramebufferAttachment *colorAttachment,
const gl::FramebufferAttachment *depthStencilAttachment); const gl::FramebufferAttachment *depthStencilAttachment);
gl::Error applyUniforms(const ProgramD3D &programD3D, gl::Error applyUniforms(ProgramD3D *programD3D);
const std::vector<D3DUniform *> &uniformArray) override;
bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
gl::Error applyVertexBuffer(const gl::State &state, gl::Error applyVertexBuffer(const gl::State &state,
GLenum mode, GLenum mode,
...@@ -390,9 +389,6 @@ class Renderer9 : public RendererD3D ...@@ -390,9 +389,6 @@ class Renderer9 : public RendererD3D
gl::Version getMaxSupportedESVersion() const override; gl::Version getMaxSupportedESVersion() const override;
gl::Error applyComputeUniforms(const ProgramD3D &programD3D,
const std::vector<D3DUniform *> &uniformArray) override;
gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, gl::Error clearRenderTarget(RenderTargetD3D *renderTarget,
const gl::ColorF &clearColorValue, const gl::ColorF &clearColorValue,
const float clearDepthValue, const float clearDepthValue,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment