summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/renderer/d3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h17
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp68
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp245
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp1814
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h184
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp108
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp796
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h195
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp118
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp1711
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h227
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp108
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h38
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp88
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp214
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp549
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp116
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp327
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h84
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp1298
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h152
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp169
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp1817
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h177
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp94
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp227
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp63
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp654
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h43
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp165
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h60
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp756
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h134
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp377
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h46
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h5
85 files changed, 9428 insertions, 4527 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp
index a34ef03fb8..dd0d3f52ad 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp
@@ -9,7 +9,6 @@
#include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/renderer/d3d/VertexBuffer.h"
#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/main.h"
namespace rx
@@ -37,6 +36,13 @@ BufferD3D *BufferD3D::makeBufferD3D(BufferImpl *buffer)
return static_cast<BufferD3D*>(buffer);
}
+BufferD3D *BufferD3D::makeFromBuffer(gl::Buffer *buffer)
+{
+ BufferImpl *impl = buffer->getImplementation();
+ ASSERT(impl);
+ return makeBufferD3D(impl);
+}
+
void BufferD3D::updateSerial()
{
mSerial = mNextSerial++;
@@ -46,11 +52,11 @@ void BufferD3D::initializeStaticData()
{
if (!mStaticVertexBuffer)
{
- mStaticVertexBuffer = new rx::StaticVertexBufferInterface(getRenderer());
+ mStaticVertexBuffer = new StaticVertexBufferInterface(getRenderer());
}
if (!mStaticIndexBuffer)
{
- mStaticIndexBuffer = new rx::StaticIndexBufferInterface(getRenderer());
+ mStaticIndexBuffer = new StaticIndexBufferInterface(getRenderer());
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h
index 44f14cee58..1a1308c545 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h
@@ -12,10 +12,11 @@
#include "libGLESv2/renderer/BufferImpl.h"
#include "libGLESv2/angletypes.h"
+#include <cstdint>
+
namespace rx
{
-
-class Renderer;
+class RendererD3D;
class StaticIndexBufferInterface;
class StaticVertexBufferInterface;
@@ -26,15 +27,17 @@ class BufferD3D : public BufferImpl
virtual ~BufferD3D();
static BufferD3D *makeBufferD3D(BufferImpl *buffer);
+ static BufferD3D *makeFromBuffer(gl::Buffer *buffer);
unsigned int getSerial() const { return mSerial; }
+ virtual gl::Error getData(const uint8_t **outData) = 0;
virtual size_t getSize() const = 0;
virtual bool supportsDirectBinding() const = 0;
- virtual Renderer* getRenderer() = 0;
+ virtual RendererD3D *getRenderer() = 0;
- rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
- rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
+ StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
+ StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
void initializeStaticData();
void invalidateStaticData();
@@ -46,8 +49,8 @@ class BufferD3D : public BufferImpl
void updateSerial();
- rx::StaticVertexBufferInterface *mStaticVertexBuffer;
- rx::StaticIndexBufferInterface *mStaticIndexBuffer;
+ StaticVertexBufferInterface *mStaticVertexBuffer;
+ StaticIndexBufferInterface *mStaticIndexBuffer;
unsigned int mUnmodifiedDataUse;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
index 13411ebe64..3d5bfe0cbe 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -8,10 +8,10 @@
#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/Shader.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Shader.h"
#include "libGLESv2/formatutils.h"
#include "common/utilities.h"
@@ -22,6 +22,9 @@ META_ASSERT(GL_INVALID_INDEX == UINT_MAX);
using namespace gl;
+namespace rx
+{
+
namespace
{
@@ -70,7 +73,7 @@ std::string HLSLTypeString(GLenum type)
return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type));
}
-const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::PixelShaderOutputVariable> &outputVariables,
+const PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<PixelShaderOutputVariable> &outputVariables,
unsigned int location)
{
for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex)
@@ -85,15 +88,12 @@ const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::P
return outputVariables[0];
}
-}
-
-namespace rx
-{
-
const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@";
-DynamicHLSL::DynamicHLSL(rx::Renderer *const renderer)
+}
+
+DynamicHLSL::DynamicHLSL(RendererD3D *const renderer)
: mRenderer(renderer)
{
}
@@ -225,8 +225,8 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
-int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
- rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
+int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader,
+ ShaderD3D *vertexShader, const std::vector<std::string> &transformFeedbackVaryings)
{
// TODO (geofflang): Use context's caps
const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
@@ -262,6 +262,13 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad
for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++)
{
const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex];
+
+ if (transformFeedbackVarying == "gl_Position" || transformFeedbackVarying == "gl_PointSize")
+ {
+ // do not pack builtin XFB varyings
+ continue;
+ }
+
if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end())
{
bool found = false;
@@ -281,7 +288,7 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad
}
}
- if (!found && transformFeedbackVarying != "gl_Position" && transformFeedbackVarying != "gl_PointSize")
+ if (!found)
{
infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str());
return -1;
@@ -400,7 +407,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s
// data reinterpretation (eg for pure integer->float, float->pure integer)
// TODO: issue warning with gl debug info extension, when supported
if (IsMatrixType(shaderAttribute.type) ||
- (mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0)
+ (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0)
{
initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute);
}
@@ -639,7 +646,7 @@ void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
}
}
-void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader,
+void DynamicHLSL::storeUserLinkedVaryings(const ShaderD3D *vertexShader,
std::vector<LinkedVarying> *linkedVaryings) const
{
const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize);
@@ -662,10 +669,11 @@ void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader,
}
}
-bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
- std::string& pixelHLSL, std::string& vertexHLSL,
- rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings,
+bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, int registers,
+ const VaryingPacking packing,
+ std::string &pixelHLSL, std::string &vertexHLSL,
+ ShaderD3D *fragmentShader, ShaderD3D *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
std::vector<LinkedVarying> *linkedVaryings,
std::map<int, VariableLocation> *programOutputVars,
std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
@@ -691,21 +699,17 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
// Write the HLSL input/output declarations
const int shaderModel = mRenderer->getMajorShaderModel();
-
- // TODO (geofflang): Use context's caps
- const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
-
const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0);
// Two cases when writing to gl_FragColor and using ESSL 1.0:
// - with a 3.0 context, the output color is copied to channel 0
// - with a 2.0 context, the output color is broadcast to all channels
- const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3);
- const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getRendererCaps().maxDrawBuffers : 1);
+ const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3);
+ const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1);
int shaderVersion = vertexShader->getShaderVersion();
- if (registersNeeded > maxVaryingVectors)
+ if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
{
infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
return false;
@@ -772,7 +776,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
for (int row = 0; row < variableRows; row++)
{
- int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row;
+ int r = varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row;
vertexHLSL += " output.v" + Str(r);
vertexHLSL += " = _" + varying.name;
@@ -920,7 +924,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
for (int row = 0; row < variableRows; row++)
{
- std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row);
+ std::string n = Str(varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row);
pixelHLSL += " _" + varying.name;
if (varying.isArray())
@@ -966,7 +970,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
return true;
}
-void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
+void DynamicHLSL::defineOutputVariables(ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
{
const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables();
@@ -994,14 +998,14 @@ void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<
}
}
-std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
+std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const
{
// for now we only handle point sprite emulation
ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4);
return generatePointSpriteHLSL(registers, fragmentShader, vertexShader);
}
-std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
+std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const
{
ASSERT(registers >= 0);
ASSERT(vertexShader->mUsesPointSize);
@@ -1047,7 +1051,7 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *f
"void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
"{\n"
" GS_OUTPUT output = (GS_OUTPUT)0;\n"
- " output.gl_Position = input[0].gl_Position;\n";
+ " output.gl_Position = input[0].gl_Position;\n"
" output.gl_PointSize = input[0].gl_PointSize;\n";
for (int r = 0; r < registers; r++)
@@ -1135,7 +1139,7 @@ void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLen
}
else
{
- bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0);
+ bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0);
signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h
index f68ed98401..c46bbf6ce0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h
@@ -10,18 +10,13 @@
#define LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
#include "common/angleutils.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "angle_gl.h"
#include <vector>
#include <map>
-namespace rx
-{
-class Renderer;
-}
-
namespace sh
{
struct Attribute;
@@ -36,11 +31,12 @@ struct LinkedVarying;
struct VertexAttribute;
struct VertexFormat;
struct PackedVarying;
+struct Data;
}
namespace rx
{
-class Renderer;
+class RendererD3D;
class ShaderD3D;
typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4];
@@ -56,30 +52,31 @@ struct PixelShaderOutputVariable
class DynamicHLSL
{
public:
- explicit DynamicHLSL(rx::Renderer *const renderer);
+ explicit DynamicHLSL(RendererD3D *const renderer);
- int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
- rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
+ int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader,
+ ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const gl::VertexFormat inputLayout[],
const sh::Attribute shaderAttributes[]) const;
std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables,
bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
- bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing,
- std::string& pixelHLSL, std::string& vertexHLSL,
- rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings,
+ bool generateShaderLinkHLSL(const gl::Data &data, gl::InfoLog &infoLog, int registers,
+ const VaryingPacking packing,
+ std::string &pixelHLSL, std::string &vertexHLSL,
+ ShaderD3D *fragmentShader, ShaderD3D *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
std::vector<gl::LinkedVarying> *linkedVaryings,
std::map<int, gl::VariableLocation> *programOutputVars,
std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const;
- std::string generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
+ std::string generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const;
void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
private:
DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
struct SemanticInfo;
@@ -88,10 +85,10 @@ class DynamicHLSL
bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(const ShaderD3D *shader) const;
- void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
+ void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const;
- void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
- std::string generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
+ void defineOutputVariables(ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
+ std::string generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const;
// Prepend an underscore
static std::string decorateVariable(const std::string &name);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
index d0131974ee..776d92b202 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
@@ -8,34 +8,116 @@
#include "libGLESv2/Program.h"
#include "libGLESv2/main.h"
+#include "common/features.h"
#include "common/utilities.h"
-#include "common/platform.h"
-#if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL)
+#ifndef QT_D3DCOMPILER_DLL
+#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
+#endif
+#ifndef D3DCOMPILE_RESERVED16
+#define D3DCOMPILE_RESERVED16 (1 << 16)
+#endif
+#ifndef D3DCOMPILE_RESERVED17
+#define D3DCOMPILE_RESERVED17 (1 << 17)
+#endif
-// Add define + typedefs for older MinGW-w64 headers (pre 5783)
+// Definitions local to the translation unit
+namespace
+{
-#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
+#ifdef CREATE_COMPILER_FLAG_INFO
+ #undef CREATE_COMPILER_FLAG_INFO
+#endif
-HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
- const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
- const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
-typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const char *filename,
- const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
- const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
+#define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag }
-#endif // __MINGW32__ && !D3DCOMPILER_DLL
+struct CompilerFlagInfo
+{
+ UINT mFlag;
+ const char *mName;
+};
-#ifndef QT_D3DCOMPILER_DLL
-#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
-#endif
+CompilerFlagInfo CompilerFlagInfos[] =
+{
+ // NOTE: The data below is copied from d3dcompiler.h
+ // If something changes there it should be changed here as well
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_DEBUG), // (1 << 0)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_VALIDATION), // (1 << 1)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_OPTIMIZATION), // (1 << 2)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_ROW_MAJOR), // (1 << 3)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR), // (1 << 4)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PARTIAL_PRECISION), // (1 << 5)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT), // (1 << 6)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT), // (1 << 7)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_NO_PRESHADER), // (1 << 8)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_AVOID_FLOW_CONTROL), // (1 << 9)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PREFER_FLOW_CONTROL), // (1 << 10)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_STRICTNESS), // (1 << 11)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY), // (1 << 12)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_IEEE_STRICTNESS), // (1 << 13)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL0), // (1 << 14)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL1), // 0
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL2), // ((1 << 14) | (1 << 15))
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL3), // (1 << 15)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED16), // (1 << 16)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED17), // (1 << 17)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_WARNINGS_ARE_ERRORS) // (1 << 18)
+};
+
+#undef CREATE_COMPILER_FLAG_INFO
+
+bool IsCompilerFlagSet(UINT mask, UINT flag)
+{
+ bool isFlagSet = IsMaskFlagSet(mask, flag);
+
+ switch(flag)
+ {
+ case D3DCOMPILE_OPTIMIZATION_LEVEL0:
+ return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL3));
+
+ case D3DCOMPILE_OPTIMIZATION_LEVEL1:
+ return (mask & D3DCOMPILE_OPTIMIZATION_LEVEL2) == UINT(0);
+
+ case D3DCOMPILE_OPTIMIZATION_LEVEL3:
+ return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL0));
+
+ default:
+ return isFlagSet;
+ }
+}
+
+const char *GetCompilerFlagName(UINT mask, size_t flagIx)
+{
+ const CompilerFlagInfo &flagInfo = CompilerFlagInfos[flagIx];
+ if (IsCompilerFlagSet(mask, flagInfo.mFlag))
+ {
+ return flagInfo.mName;
+ }
+
+ return nullptr;
+}
+
+}
namespace rx
{
+CompileConfig::CompileConfig()
+ : flags(0),
+ name()
+{
+}
+
+CompileConfig::CompileConfig(UINT flags, const std::string &name)
+ : flags(flags),
+ name(name)
+{
+}
+
HLSLCompiler::HLSLCompiler()
: mD3DCompilerModule(NULL),
- mD3DCompileFunc(NULL)
+ mD3DCompileFunc(NULL),
+ mD3DDisassembleFunc(NULL)
{
}
@@ -46,7 +128,7 @@ HLSLCompiler::~HLSLCompiler()
bool HLSLCompiler::initialize()
{
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
// Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
@@ -85,15 +167,30 @@ bool HLSLCompiler::initialize()
if (!mD3DCompilerModule)
{
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
+ mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
+ }
+
+ if (!mD3DCompilerModule)
+ {
ERR("No D3D compiler module found - aborting!\n");
return false;
}
- mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
+ mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
ASSERT(mD3DCompileFunc);
+
+ mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(GetProcAddress(mD3DCompilerModule, "D3DDisassemble"));
+ ASSERT(mD3DDisassembleFunc);
+
#else
- mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(&D3DCompile);
+ // D3D Shader compiler is linked already into this module, so the export
+ // can be directly assigned.
+ mD3DCompilerModule = NULL;
+ mD3DCompileFunc = reinterpret_cast<pD3DCompile>(D3DCompile);
+ mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(D3DDisassemble);
#endif
+
return mD3DCompileFunc != NULL;
}
@@ -104,61 +201,133 @@ void HLSLCompiler::release()
FreeLibrary(mD3DCompilerModule);
mD3DCompilerModule = NULL;
mD3DCompileFunc = NULL;
+ mD3DDisassembleFunc = NULL;
}
}
-ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
- const UINT optimizationFlags[], const char *flagNames[], int attempts) const
+gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
+ const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
+ ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const
{
-#if !defined(ANGLE_PLATFORM_WINRT)
- ASSERT(mD3DCompilerModule && mD3DCompileFunc);
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ ASSERT(mD3DCompilerModule);
#endif
+ ASSERT(mD3DCompileFunc);
- if (!hlsl)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ if (gl::perfActive())
{
- return NULL;
+ std::string sourcePath = getTempPath();
+ std::string sourceText = FormatString("#line 2 \"%s\"\n\n%s", sourcePath.c_str(), hlsl.c_str());
+ writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
+#endif
+
+ const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : NULL;
- pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
- for (int i = 0; i < attempts; ++i)
+ for (size_t i = 0; i < configs.size(); ++i)
{
ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL;
- HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage);
+ HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, NULL, "main", profile.c_str(),
+ configs[i].flags, 0, &binary, &errorMessage);
if (errorMessage)
{
- const char *message = (const char*)errorMessage->GetBufferPointer();
+ std::string message = reinterpret_cast<const char*>(errorMessage->GetBufferPointer());
+ SafeRelease(errorMessage);
- infoLog.appendSanitized(message);
- TRACE("\n%s", hlsl);
- TRACE("\n%s", message);
+ infoLog.appendSanitized(message.c_str());
+ TRACE("\n%s", hlsl.c_str());
+ TRACE("\n%s", message.c_str());
- SafeRelease(errorMessage);
+ if (message.find("error X3531:") != std::string::npos) // "can't unroll loops marked with loop attribute"
+ {
+ macros = NULL; // Disable [loop] and [flatten]
+
+ // Retry without changing compiler flags
+ i--;
+ continue;
+ }
}
if (SUCCEEDED(result))
{
- return (ShaderBlob*)binary;
+ *outCompiledBlob = binary;
+
+#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ (*outDebugInfo) += "// COMPILER INPUT HLSL BEGIN\n\n" + hlsl + "\n// COMPILER INPUT HLSL END\n";
+ (*outDebugInfo) += "\n\n// ASSEMBLY BEGIN\n\n";
+ (*outDebugInfo) += "// Compiler configuration: " + configs[i].name + "\n// Flags:\n";
+ for (size_t fIx = 0; fIx < ArraySize(CompilerFlagInfos); ++fIx)
+ {
+ const char *flagName = GetCompilerFlagName(configs[i].flags, fIx);
+ if (flagName != nullptr)
+ {
+ (*outDebugInfo) += std::string("// ") + flagName + "\n";
+ }
+ }
+
+ (*outDebugInfo) += "// Macros:\n";
+ if (macros == nullptr)
+ {
+ (*outDebugInfo) += "// - : -\n";
+ }
+ else
+ {
+ for (const D3D_SHADER_MACRO *mIt = macros; mIt->Name != nullptr; ++mIt)
+ {
+ (*outDebugInfo) += std::string("// ") + mIt->Name + " : " + mIt->Definition + "\n";
+ }
+ }
+
+ (*outDebugInfo) += "\n" + disassembleBinary(binary) + "\n// ASSEMBLY END\n";
+#endif
+
+ return gl::Error(GL_NO_ERROR);
}
else
{
if (result == E_OUTOFMEMORY)
{
- return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL);
+ *outCompiledBlob = NULL;
+ return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result);
}
- infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]);
+ infoLog.append("Warning: D3D shader compilation failed with %s flags.", configs[i].name.c_str());
- if (i + 1 < attempts)
+ if (i + 1 < configs.size())
{
- infoLog.append(" Retrying with %s.\n", flagNames[i + 1]);
+ infoLog.append(" Retrying with %s.\n", configs[i + 1].name.c_str());
}
}
}
- return NULL;
+ // None of the configurations succeeded in compiling this shader but the compiler is still intact
+ *outCompiledBlob = NULL;
+ return gl::Error(GL_NO_ERROR);
+}
+
+std::string HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary) const
+{
+ // Retrieve disassembly
+ UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING;
+ ID3DBlob *disassembly = NULL;
+ pD3DDisassemble disassembleFunc = reinterpret_cast<pD3DDisassemble>(mD3DDisassembleFunc);
+ LPCVOID buffer = shaderBinary->GetBufferPointer();
+ SIZE_T bufSize = shaderBinary->GetBufferSize();
+ HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly);
+
+ std::string asmSrc;
+ if (SUCCEEDED(result))
+ {
+ asmSrc = reinterpret_cast<const char*>(disassembly->GetBufferPointer());
+ }
+
+ SafeRelease(disassembly);
+
+ return asmSrc;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h
index 0ce9e44be5..ff56f8035a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h
@@ -1,7 +1,13 @@
#ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
#define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
+#include "common/platform.h"
+
+#include <vector>
+#include <string>
namespace gl
{
@@ -11,8 +17,14 @@ class InfoLog;
namespace rx
{
-typedef void* ShaderBlob;
-typedef void(*CompileFuncPtr)();
+struct CompileConfig
+{
+ UINT flags;
+ std::string name;
+
+ CompileConfig();
+ CompileConfig(UINT flags, const std::string &name);
+};
class HLSLCompiler
{
@@ -23,14 +35,20 @@ class HLSLCompiler
bool initialize();
void release();
- ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
- const UINT optimizationFlags[], const char *flagNames[], int attempts) const;
+ // Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob
+ // even if no GL errors are returned.
+ gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
+ const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
+ ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const;
+
+ std::string disassembleBinary(ID3DBlob* shaderBinary) const;
private:
DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);
HMODULE mD3DCompilerModule;
- CompileFuncPtr mD3DCompileFunc;
+ pD3DCompile mD3DCompileFunc;
+ pD3DDisassemble mD3DDisassembleFunc;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
index 0854b968da..12b919ab5a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
@@ -19,8 +19,8 @@ ImageD3D::ImageD3D()
ImageD3D *ImageD3D::makeImageD3D(Image *img)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::ImageD3D*, img));
- return static_cast<rx::ImageD3D*>(img);
+ ASSERT(HAS_DYNAMIC_TYPE(ImageD3D*, img));
+ return static_cast<ImageD3D*>(img);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
index 60a6ffdf37..554ca0cee0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
@@ -17,6 +17,8 @@
namespace gl
{
class Framebuffer;
+struct ImageIndex;
+struct Box;
}
namespace rx
@@ -33,14 +35,11 @@ class ImageD3D : public Image
virtual bool isDirty() const = 0;
- virtual void setManagedSurface2D(TextureStorage *storage, int level) {};
- virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {};
- virtual void setManagedSurface3D(TextureStorage *storage, int level) {};
- virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {};
- virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
- virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
- virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0;
- virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0;
+ virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ImageD3D);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
index 1dce1270d8..aa614f6cc4 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
@@ -8,7 +8,7 @@
// class with derivations, classes that perform graphics API agnostic index buffer operations.
#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
namespace rx
{
@@ -35,7 +35,7 @@ void IndexBuffer::updateSerial()
}
-IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer)
+IndexBufferInterface::IndexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer)
{
mIndexBuffer = renderer->createIndexBuffer();
@@ -130,7 +130,7 @@ gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum in
}
}
-StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
+StreamingIndexBufferInterface::StreamingIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, true)
{
}
@@ -165,7 +165,7 @@ gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, G
}
-StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
+StaticIndexBufferInterface::StaticIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, false)
{
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h
index 1bb5ae2c4a..a34d30bbf3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h
@@ -16,7 +16,7 @@
namespace rx
{
-class Renderer;
+class RendererD3D;
class IndexBuffer
{
@@ -50,7 +50,7 @@ class IndexBuffer
class IndexBufferInterface
{
public:
- IndexBufferInterface(Renderer *renderer, bool dynamic);
+ IndexBufferInterface(RendererD3D *renderer, bool dynamic);
virtual ~IndexBufferInterface();
virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) = 0;
@@ -76,7 +76,7 @@ class IndexBufferInterface
private:
DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
IndexBuffer* mIndexBuffer;
@@ -87,7 +87,7 @@ class IndexBufferInterface
class StreamingIndexBufferInterface : public IndexBufferInterface
{
public:
- StreamingIndexBufferInterface(Renderer *renderer);
+ StreamingIndexBufferInterface(RendererD3D *renderer);
~StreamingIndexBufferInterface();
virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
@@ -96,7 +96,7 @@ class StreamingIndexBufferInterface : public IndexBufferInterface
class StaticIndexBufferInterface : public IndexBufferInterface
{
public:
- explicit StaticIndexBufferInterface(Renderer *renderer);
+ explicit StaticIndexBufferInterface(RendererD3D *renderer);
~StaticIndexBufferInterface();
virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index 8d455b4bf3..eddd9de887 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -10,7 +10,7 @@
#include "libGLESv2/renderer/d3d/IndexDataManager.h"
#include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/main.h"
#include "libGLESv2/formatutils.h"
@@ -57,7 +57,7 @@ static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void
else UNREACHABLE();
}
-IndexDataManager::IndexDataManager(Renderer *renderer)
+IndexDataManager::IndexDataManager(RendererD3D *renderer)
: mRenderer(renderer),
mStreamingBufferShort(NULL),
mStreamingBufferInt(NULL)
@@ -97,7 +97,14 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL;
@@ -183,7 +190,16 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
return error;
}
- ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
+ const uint8_t *dataPointer = reinterpret_cast<const uint8_t*>(indices);
+ if (staticBuffer)
+ {
+ error = storage->getData(&dataPointer);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ ConvertIndices(type, destinationIndexType, dataPointer, convertCount, output);
error = indexBuffer->unmapBuffer();
if (error.isError())
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h
index 6d0b89e6d4..a1aee1588b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h
@@ -33,7 +33,7 @@ class StaticIndexBufferInterface;
class StreamingIndexBufferInterface;
class IndexBuffer;
class BufferD3D;
-class Renderer;
+class RendererD3D;
struct TranslatedIndexData
{
@@ -50,7 +50,7 @@ struct TranslatedIndexData
class IndexDataManager
{
public:
- explicit IndexDataManager(Renderer *renderer);
+ explicit IndexDataManager(RendererD3D *renderer);
virtual ~IndexDataManager();
gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
@@ -60,7 +60,7 @@ class IndexDataManager
DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
- Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
StreamingIndexBufferInterface *mStreamingBufferShort;
StreamingIndexBufferInterface *mStreamingBufferInt;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
index d7d97cc2bd..75da78110e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
@@ -8,27 +8,163 @@
#include "libGLESv2/renderer/d3d/ProgramD3D.h"
+#include "common/features.h"
#include "common/utilities.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/main.h"
#include "libGLESv2/renderer/ShaderExecutable.h"
#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/main.h"
namespace rx
{
-ProgramD3D::ProgramD3D(rx::Renderer *renderer)
+namespace
+{
+
+GLenum GetTextureType(GLenum samplerType)
+{
+ switch (samplerType)
+ {
+ case GL_SAMPLER_2D:
+ case GL_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_SAMPLER_2D_SHADOW:
+ return GL_TEXTURE_2D;
+ case GL_SAMPLER_3D:
+ case GL_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ return GL_TEXTURE_3D;
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_SHADOW:
+ return GL_TEXTURE_CUBE_MAP;
+ case GL_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ return GL_TEXTURE_CUBE_MAP;
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ return GL_TEXTURE_2D_ARRAY;
+ default: UNREACHABLE();
+ }
+
+ return GL_TEXTURE_2D;
+}
+
+void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
+{
+ size_t layoutIndex = 0;
+ for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
+ {
+ ASSERT(layoutIndex < gl::MAX_VERTEX_ATTRIBS);
+
+ const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
+
+ if (shaderAttr.type != GL_NONE)
+ {
+ GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
+
+ for (size_t rowIndex = 0; static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); rowIndex++, layoutIndex++)
+ {
+ gl::VertexFormat *defaultFormat = &inputLayout[layoutIndex];
+
+ defaultFormat->mType = gl::VariableComponentType(transposedType);
+ defaultFormat->mNormalized = false;
+ defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
+ defaultFormat->mComponents = gl::VariableColumnCount(transposedType);
+ }
+ }
+ }
+}
+
+std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<PixelShaderOutputVariable> &shaderOutputVars)
+{
+ std::vector<GLenum> defaultPixelOutput(1);
+
+ ASSERT(!shaderOutputVars.empty());
+ defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
+
+ return defaultPixelOutput;
+}
+
+bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
+{
+ return var.isRowMajorLayout;
+}
+
+bool IsRowMajorLayout(const sh::ShaderVariable &var)
+{
+ return false;
+}
+
+}
+
+ProgramD3D::VertexExecutable::VertexExecutable(const gl::VertexFormat inputLayout[],
+ const GLenum signature[],
+ ShaderExecutable *shaderExecutable)
+ : mShaderExecutable(shaderExecutable)
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ mInputs[attributeIndex] = inputLayout[attributeIndex];
+ mSignature[attributeIndex] = signature[attributeIndex];
+ }
+}
+
+ProgramD3D::VertexExecutable::~VertexExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+bool ProgramD3D::VertexExecutable::matchesSignature(const GLenum signature[]) const
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (mSignature[attributeIndex] != signature[attributeIndex])
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable)
+ : mOutputSignature(outputSignature),
+ mShaderExecutable(shaderExecutable)
+{
+}
+
+ProgramD3D::PixelExecutable::~PixelExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
+{
+}
+
+ProgramD3D::ProgramD3D(RendererD3D *renderer)
: ProgramImpl(),
mRenderer(renderer),
mDynamicHLSL(NULL),
- mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
- mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+ mGeometryExecutable(NULL),
+ mVertexWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
+ mPixelWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
+ mUsesPointSize(false),
mVertexUniformStorage(NULL),
- mFragmentUniformStorage(NULL)
+ mFragmentUniformStorage(NULL),
+ mUsedVertexSamplerRange(0),
+ mUsedPixelSamplerRange(0),
+ mDirtySamplerMapping(true),
+ mShaderVersion(100)
{
- mDynamicHLSL = new rx::DynamicHLSL(renderer);
+ mDynamicHLSL = new DynamicHLSL(renderer);
}
ProgramD3D::~ProgramD3D()
@@ -49,13 +185,344 @@ const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl)
return static_cast<const ProgramD3D*>(impl);
}
-bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+bool ProgramD3D::usesPointSpriteEmulation() const
+{
+ return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+}
+
+bool ProgramD3D::usesGeometryShader() const
+{
+ return usesPointSpriteEmulation();
+}
+
+GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const
+{
+ GLint logicalTextureUnit = -1;
+
+ switch (type)
+ {
+ case gl::SAMPLER_PIXEL:
+ ASSERT(samplerIndex < caps.maxTextureImageUnits);
+ if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
+ {
+ logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
+ }
+ break;
+ case gl::SAMPLER_VERTEX:
+ ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
+ if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
+ {
+ logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
+ }
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
+ {
+ return logicalTextureUnit;
+ }
+
+ return -1;
+}
+
+// Returns the texture type for a given Direct3D 9 sampler type and
+// index (0-15 for the pixel shader and 0-3 for the vertex shader).
+GLenum ProgramD3D::getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const
+{
+ switch (type)
+ {
+ case gl::SAMPLER_PIXEL:
+ ASSERT(samplerIndex < mSamplersPS.size());
+ ASSERT(mSamplersPS[samplerIndex].active);
+ return mSamplersPS[samplerIndex].textureType;
+ case gl::SAMPLER_VERTEX:
+ ASSERT(samplerIndex < mSamplersVS.size());
+ ASSERT(mSamplersVS[samplerIndex].active);
+ return mSamplersVS[samplerIndex].textureType;
+ default: UNREACHABLE();
+ }
+
+ return GL_TEXTURE_2D;
+}
+
+GLint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const
+{
+ switch (type)
+ {
+ case gl::SAMPLER_PIXEL:
+ return mUsedPixelSamplerRange;
+ case gl::SAMPLER_VERTEX:
+ return mUsedVertexSamplerRange;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+void ProgramD3D::updateSamplerMapping()
+{
+ if (!mDirtySamplerMapping)
+ {
+ return;
+ }
+
+ mDirtySamplerMapping = false;
+
+ // Retrieve sampler uniform values
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ gl::LinkedUniform *targetUniform = mUniforms[uniformIndex];
+
+ if (targetUniform->dirty)
+ {
+ if (gl::IsSampler(targetUniform->type))
+ {
+ int count = targetUniform->elementCount();
+ GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
+
+ if (targetUniform->isReferencedByFragmentShader())
+ {
+ unsigned int firstIndex = targetUniform->psRegisterIndex;
+
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < mSamplersPS.size())
+ {
+ ASSERT(mSamplersPS[samplerIndex].active);
+ mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
+ }
+
+ if (targetUniform->isReferencedByVertexShader())
+ {
+ unsigned int firstIndex = targetUniform->vsRegisterIndex;
+
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < mSamplersVS.size())
+ {
+ ASSERT(mSamplersVS[samplerIndex].active);
+ mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
+ // if any two active samplers in a program are of different types, but refer to the same
+ // texture image unit, and this is the current program, then ValidateProgram will fail, and
+ // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
+ updateSamplerMapping();
+
+ std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
+
+ for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
+ {
+ if (mSamplersPS[i].active)
+ {
+ unsigned int unit = mSamplersPS[i].logicalTextureUnit;
+
+ if (unit >= textureUnitTypes.size())
+ {
+ if (infoLog)
+ {
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
+ }
+
+ return false;
+ }
+
+ if (textureUnitTypes[unit] != GL_NONE)
+ {
+ if (mSamplersPS[i].textureType != textureUnitTypes[unit])
+ {
+ if (infoLog)
+ {
+ infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+ }
+
+ return false;
+ }
+ }
+ else
+ {
+ textureUnitTypes[unit] = mSamplersPS[i].textureType;
+ }
+ }
+ }
+
+ for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
+ {
+ if (mSamplersVS[i].active)
+ {
+ unsigned int unit = mSamplersVS[i].logicalTextureUnit;
+
+ if (unit >= textureUnitTypes.size())
+ {
+ if (infoLog)
+ {
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
+ }
+
+ return false;
+ }
+
+ if (textureUnitTypes[unit] != GL_NONE)
+ {
+ if (mSamplersVS[i].textureType != textureUnitTypes[unit])
+ {
+ if (infoLog)
+ {
+ infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+ }
+
+ return false;
+ }
+ }
+ else
+ {
+ textureUnitTypes[unit] = mSamplersVS[i].textureType;
+ }
+ }
+ }
+
+ return true;
+}
+
+gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+{
+ stream->readInt(&mShaderVersion);
+
+ const unsigned int psSamplerCount = stream->readInt<unsigned int>();
+ for (unsigned int i = 0; i < psSamplerCount; ++i)
+ {
+ Sampler sampler;
+ stream->readBool(&sampler.active);
+ stream->readInt(&sampler.logicalTextureUnit);
+ stream->readInt(&sampler.textureType);
+ mSamplersPS.push_back(sampler);
+ }
+ const unsigned int vsSamplerCount = stream->readInt<unsigned int>();
+ for (unsigned int i = 0; i < vsSamplerCount; ++i)
+ {
+ Sampler sampler;
+ stream->readBool(&sampler.active);
+ stream->readInt(&sampler.logicalTextureUnit);
+ stream->readInt(&sampler.textureType);
+ mSamplersVS.push_back(sampler);
+ }
+
+ stream->readInt(&mUsedVertexSamplerRange);
+ stream->readInt(&mUsedPixelSamplerRange);
+
+ const unsigned int uniformCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ mUniforms.resize(uniformCount);
+ for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
+ {
+ GLenum type = stream->readInt<GLenum>();
+ GLenum precision = stream->readInt<GLenum>();
+ std::string name = stream->readString();
+ unsigned int arraySize = stream->readInt<unsigned int>();
+ int blockIndex = stream->readInt<int>();
+
+ int offset = stream->readInt<int>();
+ int arrayStride = stream->readInt<int>();
+ int matrixStride = stream->readInt<int>();
+ bool isRowMajorMatrix = stream->readBool();
+
+ const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
+
+ gl::LinkedUniform *uniform = new gl::LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
+
+ stream->readInt(&uniform->psRegisterIndex);
+ stream->readInt(&uniform->vsRegisterIndex);
+ stream->readInt(&uniform->registerCount);
+ stream->readInt(&uniform->registerElement);
+
+ mUniforms[uniformIndex] = uniform;
+ }
+
+ const unsigned int uniformIndexCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ mUniformIndex.resize(uniformIndexCount);
+ for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
+ {
+ stream->readString(&mUniformIndex[uniformIndexIndex].name);
+ stream->readInt(&mUniformIndex[uniformIndexIndex].element);
+ stream->readInt(&mUniformIndex[uniformIndexIndex].index);
+ }
+
+ unsigned int uniformBlockCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ mUniformBlocks.resize(uniformBlockCount);
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
+ {
+ std::string name = stream->readString();
+ unsigned int elementIndex = stream->readInt<unsigned int>();
+ unsigned int dataSize = stream->readInt<unsigned int>();
+
+ gl::UniformBlock *uniformBlock = new gl::UniformBlock(name, elementIndex, dataSize);
+
+ stream->readInt(&uniformBlock->psRegisterIndex);
+ stream->readInt(&uniformBlock->vsRegisterIndex);
+
+ unsigned int numMembers = stream->readInt<unsigned int>();
+ uniformBlock->memberUniformIndexes.resize(numMembers);
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
+ {
+ stream->readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]);
+ }
+
+ mUniformBlocks[uniformBlockIndex] = uniformBlock;
+ }
+
+ stream->readInt(&mTransformFeedbackBufferMode);
+ const unsigned int transformFeedbackVaryingCount = stream->readInt<unsigned int>();
+ mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount);
+ for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++)
+ {
+ gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex];
+
+ stream->readString(&varying.name);
+ stream->readInt(&varying.type);
+ stream->readInt(&varying.size);
+ stream->readString(&varying.semanticName);
+ stream->readInt(&varying.semanticIndex);
+ stream->readInt(&varying.semanticIndexCount);
+ }
+
stream->readString(&mVertexHLSL);
stream->readInt(&mVertexWorkarounds);
stream->readString(&mPixelHLSL);
stream->readInt(&mPixelWorkarounds);
stream->readBool(&mUsesFragDepth);
+ stream->readBool(&mUsesPointSize);
const size_t pixelShaderKeySize = stream->readInt<unsigned int>();
mPixelShaderKey.resize(pixelShaderKeySize);
@@ -67,109 +534,513 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
}
- return true;
+ const unsigned char* binary = reinterpret_cast<const unsigned char*>(stream->data());
+
+ const unsigned int vertexShaderCount = stream->readInt<unsigned int>();
+ for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
+ {
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+
+ for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+ {
+ gl::VertexFormat *vertexInput = &inputLayout[inputIndex];
+ stream->readInt(&vertexInput->mType);
+ stream->readInt(&vertexInput->mNormalized);
+ stream->readInt(&vertexInput->mComponents);
+ stream->readBool(&vertexInput->mPureInteger);
+ }
+
+ unsigned int vertexShaderSize = stream->readInt<unsigned int>();
+ const unsigned char *vertexShaderFunction = binary + stream->offset();
+
+ ShaderExecutable *shaderExecutable = NULL;
+ gl::Error error = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
+ SHADER_VERTEX,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ &shaderExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (!shaderExecutable)
+ {
+ infoLog.append("Could not create vertex shader.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ // generated converted input layout
+ GLenum signature[gl::MAX_VERTEX_ATTRIBS];
+ getInputLayoutSignature(inputLayout, signature);
+
+ // add new binary
+ mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
+
+ stream->skip(vertexShaderSize);
+ }
+
+ const size_t pixelShaderCount = stream->readInt<unsigned int>();
+ for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
+ {
+ const size_t outputCount = stream->readInt<unsigned int>();
+ std::vector<GLenum> outputs(outputCount);
+ for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
+ {
+ stream->readInt(&outputs[outputIndex]);
+ }
+
+ const size_t pixelShaderSize = stream->readInt<unsigned int>();
+ const unsigned char *pixelShaderFunction = binary + stream->offset();
+ ShaderExecutable *shaderExecutable = NULL;
+ gl::Error error = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ &shaderExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (!shaderExecutable)
+ {
+ infoLog.append("Could not create pixel shader.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ // add new binary
+ mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
+
+ stream->skip(pixelShaderSize);
+ }
+
+ unsigned int geometryShaderSize = stream->readInt<unsigned int>();
+
+ if (geometryShaderSize > 0)
+ {
+ const unsigned char *geometryShaderFunction = binary + stream->offset();
+ gl::Error error = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ &mGeometryExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (!mGeometryExecutable)
+ {
+ infoLog.append("Could not create geometry shader.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+ stream->skip(geometryShaderSize);
+ }
+
+ GUID binaryIdentifier = {0};
+ stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
+
+ GUID identifier = mRenderer->getAdapterIdentifier();
+ if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ initializeUniformStorage();
+
+ return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
}
-bool ProgramD3D::save(gl::BinaryOutputStream *stream)
+gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
{
+ stream->writeInt(mShaderVersion);
+
+ stream->writeInt(mSamplersPS.size());
+ for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
+ {
+ stream->writeInt(mSamplersPS[i].active);
+ stream->writeInt(mSamplersPS[i].logicalTextureUnit);
+ stream->writeInt(mSamplersPS[i].textureType);
+ }
+
+ stream->writeInt(mSamplersVS.size());
+ for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
+ {
+ stream->writeInt(mSamplersVS[i].active);
+ stream->writeInt(mSamplersVS[i].logicalTextureUnit);
+ stream->writeInt(mSamplersVS[i].textureType);
+ }
+
+ stream->writeInt(mUsedVertexSamplerRange);
+ stream->writeInt(mUsedPixelSamplerRange);
+
+ stream->writeInt(mUniforms.size());
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
+ {
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
+
+ stream->writeInt(uniform.type);
+ stream->writeInt(uniform.precision);
+ stream->writeString(uniform.name);
+ stream->writeInt(uniform.arraySize);
+ stream->writeInt(uniform.blockIndex);
+
+ stream->writeInt(uniform.blockInfo.offset);
+ stream->writeInt(uniform.blockInfo.arrayStride);
+ stream->writeInt(uniform.blockInfo.matrixStride);
+ stream->writeInt(uniform.blockInfo.isRowMajorMatrix);
+
+ stream->writeInt(uniform.psRegisterIndex);
+ stream->writeInt(uniform.vsRegisterIndex);
+ stream->writeInt(uniform.registerCount);
+ stream->writeInt(uniform.registerElement);
+ }
+
+ stream->writeInt(mUniformIndex.size());
+ for (size_t i = 0; i < mUniformIndex.size(); ++i)
+ {
+ stream->writeString(mUniformIndex[i].name);
+ stream->writeInt(mUniformIndex[i].element);
+ stream->writeInt(mUniformIndex[i].index);
+ }
+
+ stream->writeInt(mUniformBlocks.size());
+ for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
+ {
+ const gl::UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
+
+ stream->writeString(uniformBlock.name);
+ stream->writeInt(uniformBlock.elementIndex);
+ stream->writeInt(uniformBlock.dataSize);
+
+ stream->writeInt(uniformBlock.memberUniformIndexes.size());
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
+ {
+ stream->writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]);
+ }
+
+ stream->writeInt(uniformBlock.psRegisterIndex);
+ stream->writeInt(uniformBlock.vsRegisterIndex);
+ }
+
+ stream->writeInt(mTransformFeedbackBufferMode);
+ stream->writeInt(mTransformFeedbackLinkedVaryings.size());
+ for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
+ {
+ const gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i];
+
+ stream->writeString(varying.name);
+ stream->writeInt(varying.type);
+ stream->writeInt(varying.size);
+ stream->writeString(varying.semanticName);
+ stream->writeInt(varying.semanticIndex);
+ stream->writeInt(varying.semanticIndexCount);
+ }
+
stream->writeString(mVertexHLSL);
stream->writeInt(mVertexWorkarounds);
stream->writeString(mPixelHLSL);
stream->writeInt(mPixelWorkarounds);
stream->writeInt(mUsesFragDepth);
+ stream->writeInt(mUsesPointSize);
- const std::vector<rx::PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
+ const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
stream->writeInt(pixelShaderKey.size());
for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++)
{
- const rx::PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
+ const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
stream->writeInt(variable.type);
stream->writeString(variable.name);
stream->writeString(variable.source);
stream->writeInt(variable.outputIndex);
}
- return true;
+ stream->writeInt(mVertexExecutables.size());
+ for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
+ {
+ VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex];
+
+ for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+ {
+ const gl::VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex];
+ stream->writeInt(vertexInput.mType);
+ stream->writeInt(vertexInput.mNormalized);
+ stream->writeInt(vertexInput.mComponents);
+ stream->writeInt(vertexInput.mPureInteger);
+ }
+
+ size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
+ stream->writeInt(vertexShaderSize);
+
+ const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(vertexBlob, vertexShaderSize);
+ }
+
+ stream->writeInt(mPixelExecutables.size());
+ for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
+ {
+ PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
+
+ const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
+ stream->writeInt(outputs.size());
+ for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
+ {
+ stream->writeInt(outputs[outputIndex]);
+ }
+
+ size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
+ stream->writeInt(pixelShaderSize);
+
+ const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(pixelBlob, pixelShaderSize);
+ }
+
+ size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
+ stream->writeInt(geometryShaderSize);
+
+ if (mGeometryExecutable != NULL && geometryShaderSize > 0)
+ {
+ const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
+ stream->writeBytes(geometryBlob, geometryShaderSize);
+ }
+
+ GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
+ stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
+
+ return gl::Error(GL_NO_ERROR);
}
-rx::ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers)
+gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExecutable)
{
+ std::vector<GLenum> outputs;
+
+ const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(mRenderer->getWorkarounds());
+
+ for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
+ {
+ const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+ if (colorbuffer)
+ {
+ outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
+ }
+ else
+ {
+ outputs.push_back(GL_NONE);
+ }
+ }
+
+ return getPixelExecutableForOutputLayout(outputs, outExecutable);
+}
+
+gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature, ShaderExecutable **outExectuable)
+{
+ for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
+ {
+ if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
+ {
+ *outExectuable = mPixelExecutables[executableIndex]->shaderExecutable();
+ return gl::Error(GL_NO_ERROR);
+ }
+ }
+
std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
outputSignature);
// Generate new pixel executable
- rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
- transformFeedbackLinkedVaryings, separatedOutputBuffers,
- mPixelWorkarounds);
+ gl::InfoLog tempInfoLog;
+ ShaderExecutable *pixelExecutable = NULL;
+ gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ mPixelWorkarounds, &pixelExecutable);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!pixelExecutable)
+ {
+ std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
+ tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+ ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
+ }
+ else
+ {
+ mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
+ }
- return pixelExecutable;
+ *outExectuable = pixelExecutable;
+ return gl::Error(GL_NO_ERROR);
}
-rx::ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers)
+gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable)
{
+ GLenum signature[gl::MAX_VERTEX_ATTRIBS];
+ getInputLayoutSignature(inputLayout, signature);
+
+ for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
+ {
+ if (mVertexExecutables[executableIndex]->matchesSignature(signature))
+ {
+ *outExectuable = mVertexExecutables[executableIndex]->shaderExecutable();
+ return gl::Error(GL_NO_ERROR);
+ }
+ }
+
// Generate new dynamic layout with attribute conversions
- std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes);
+ std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes);
// Generate new vertex executable
- rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(),
- rx::SHADER_VERTEX,
- transformFeedbackLinkedVaryings, separatedOutputBuffers,
- mVertexWorkarounds);
+ gl::InfoLog tempInfoLog;
+ ShaderExecutable *vertexExecutable = NULL;
+ gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL, SHADER_VERTEX,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ mVertexWorkarounds, &vertexExecutable);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!vertexExecutable)
+ {
+ std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3);
+ tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+ ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
+ }
+ else
+ {
+ mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
+ }
+
+ *outExectuable = vertexExecutable;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers)
+{
+ ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+
+ gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS];
+ GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
+ ShaderExecutable *defaultVertexExecutable = NULL;
+ gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey());
+ ShaderExecutable *defaultPixelExecutable = NULL;
+ error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (usesGeometryShader())
+ {
+ std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
+
+
+ error = mRenderer->compileToExecutable(infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ ANGLE_D3D_WORKAROUND_NONE, &mGeometryExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+ }
+
+#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ if (usesGeometryShader() && mGeometryExecutable)
+ {
+ // Geometry shaders are currently only used internally, so there is no corresponding shader object at the interface level
+ // For now the geometry shader debug info is pre-pended to the vertex shader, this is a bit of a clutch
+ vertexShaderD3D->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n");
+ vertexShaderD3D->appendDebugInfo(mGeometryExecutable->getDebugInfo());
+ vertexShaderD3D->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n");
+ }
+
+ if (defaultVertexExecutable)
+ {
+ vertexShaderD3D->appendDebugInfo(defaultVertexExecutable->getDebugInfo());
+ }
+
+ if (defaultPixelExecutable)
+ {
+ fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
+ }
+#endif
- return vertexExecutable;
+ bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
+ return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
}
-bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables)
+gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables)
{
- rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
- rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+ ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+
+ mSamplersPS.resize(data.caps->maxTextureImageUnits);
+ mSamplersVS.resize(data.caps->maxVertexTextureImageUnits);
+
+ mTransformFeedbackBufferMode = transformFeedbackBufferMode;
mPixelHLSL = fragmentShaderD3D->getTranslatedSource();
mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds();
mVertexHLSL = vertexShaderD3D->getTranslatedSource();
mVertexWorkarounds = vertexShaderD3D->getD3DWorkarounds();
+ mShaderVersion = vertexShaderD3D->getShaderVersion();
// Map the varyings to the register file
- rx::VaryingPacking packing = { NULL };
+ VaryingPacking packing = { NULL };
*registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings);
if (*registers < 0)
{
- return false;
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader))
{
- return false;
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
- if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
+ if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings,
linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth))
{
- return false;
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
- return true;
+ mUsesPointSize = vertexShaderD3D->usesPointSize();
+
+ return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
+}
+
+void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const
+{
+ mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
}
-void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms)
+void ProgramD3D::initializeUniformStorage()
{
// Compute total default block size
unsigned int vertexRegisters = 0;
unsigned int fragmentRegisters = 0;
- for (size_t uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++)
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
- const gl::LinkedUniform &uniform = *uniforms[uniformIndex];
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
if (!gl::IsSampler(uniform.type))
{
@@ -188,18 +1059,867 @@ void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*>
mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
}
+gl::Error ProgramD3D::applyUniforms()
+{
+ updateSamplerMapping();
+
+ gl::Error error = mRenderer->applyUniforms(*this, mUniforms);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ mUniforms[uniformIndex]->dirty = false;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps)
+{
+ ASSERT(boundBuffers.size() == mUniformBlocks.size());
+
+ const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
+ const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
+
+ const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
+ const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
+
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
+ {
+ gl::UniformBlock *uniformBlock = mUniformBlocks[uniformBlockIndex];
+ gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
+
+ ASSERT(uniformBlock && uniformBuffer);
+
+ if (uniformBuffer->getSize() < uniformBlock->dataSize)
+ {
+ // undefined behaviour
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.");
+ }
+
+ // Unnecessary to apply an unreferenced standard or shared UBO
+ if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
+ {
+ continue;
+ }
+
+ if (uniformBlock->isReferencedByVertexShader())
+ {
+ unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
+ ASSERT(vertexUniformBuffers[registerIndex] == NULL);
+ ASSERT(registerIndex < caps.maxVertexUniformBlocks);
+ vertexUniformBuffers[registerIndex] = uniformBuffer;
+ }
+
+ if (uniformBlock->isReferencedByFragmentShader())
+ {
+ unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
+ ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
+ ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
+ fragmentUniformBuffers[registerIndex] = uniformBuffer;
+ }
+ }
+
+ return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+}
+
+bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
+ unsigned int registerIndex, const gl::Caps &caps)
+{
+ if (shader == GL_VERTEX_SHADER)
+ {
+ uniformBlock->vsRegisterIndex = registerIndex;
+ if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
+ {
+ infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
+ return false;
+ }
+ }
+ else if (shader == GL_FRAGMENT_SHADER)
+ {
+ uniformBlock->psRegisterIndex = registerIndex;
+ if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
+ {
+ infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
+ return false;
+ }
+ }
+ else UNREACHABLE();
+
+ return true;
+}
+
+void ProgramD3D::dirtyAllUniforms()
+{
+ unsigned int numUniforms = mUniforms.size();
+ for (unsigned int index = 0; index < numUniforms; index++)
+ {
+ mUniforms[index]->dirty = true;
+ }
+}
+
+void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ setUniform(location, count, v, GL_FLOAT);
+}
+
+void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniform(location, count, v, GL_FLOAT_VEC2);
+}
+
+void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniform(location, count, v, GL_FLOAT_VEC3);
+}
+
+void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniform(location, count, v, GL_FLOAT_VEC4);
+}
+
+void ProgramD3D::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2);
+}
+
+void ProgramD3D::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3);
+}
+
+void ProgramD3D::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4);
+}
+
+void ProgramD3D::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3);
+}
+
+void ProgramD3D::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2);
+}
+
+void ProgramD3D::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4);
+}
+
+void ProgramD3D::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2);
+}
+
+void ProgramD3D::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4);
+}
+
+void ProgramD3D::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3);
+}
+
+void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT);
+}
+
+void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT_VEC2);
+}
+
+void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT_VEC3);
+}
+
+void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT_VEC4);
+}
+
+void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT);
+}
+
+void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT_VEC2);
+}
+
+void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT_VEC3);
+}
+
+void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
+}
+
+void ProgramD3D::getUniformfv(GLint location, GLfloat *params)
+{
+ getUniformv(location, params, GL_FLOAT);
+}
+
+void ProgramD3D::getUniformiv(GLint location, GLint *params)
+{
+ getUniformv(location, params, GL_INT);
+}
+
+void ProgramD3D::getUniformuiv(GLint location, GLuint *params)
+{
+ getUniformv(location, params, GL_UNSIGNED_INT);
+}
+
+bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+ const gl::Caps &caps)
+{
+ const ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
+ const ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
+
+ const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
+ const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
+
+ // Check that uniforms defined in the vertex and fragment shaders are identical
+ typedef std::map<std::string, const sh::Uniform*> UniformMap;
+ UniformMap linkedUniforms;
+
+ for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
+ {
+ const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
+ linkedUniforms[vertexUniform.name] = &vertexUniform;
+ }
+
+ for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
+ {
+ const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
+ UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
+ if (entry != linkedUniforms.end())
+ {
+ const sh::Uniform &vertexUniform = *entry->second;
+ const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
+ if (!gl::ProgramBinary::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
+ {
+ return false;
+ }
+ }
+ }
+
+ for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
+ {
+ const sh::Uniform &uniform = vertexUniforms[uniformIndex];
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
+ }
+ }
+
+ for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
+ {
+ const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
+ }
+ }
+
+ if (!indexUniforms(infoLog, caps))
+ {
+ return false;
+ }
+
+ initializeUniformStorage();
+
+ // special case for gl_DepthRange, the only built-in uniform (also a struct)
+ if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
+ {
+ const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
+
+ mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
+ mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
+ mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
+ }
+
+ return true;
+}
+
+void ProgramD3D::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
+{
+ ShShaderOutput outputType = ShaderD3D::getCompilerOutputType(shader);
+ sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
+ encoder.skipRegisters(uniformRegister);
+
+ defineUniform(shader, uniform, uniform.name, &encoder);
+}
+
+void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
+ const std::string &fullName, sh::HLSLBlockEncoder *encoder)
+{
+ if (uniform.isStruct())
+ {
+ for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
+ {
+ const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
+
+ encoder->enterAggregateType();
+
+ for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
+ {
+ const sh::ShaderVariable &field = uniform.fields[fieldIndex];
+ const std::string &fieldFullName = (fullName + elementString + "." + field.name);
+
+ defineUniform(shader, field, fieldFullName, encoder);
+ }
+
+ encoder->exitAggregateType();
+ }
+ }
+ else // Not a struct
+ {
+ // Arrays are treated as aggregate types
+ if (uniform.isArray())
+ {
+ encoder->enterAggregateType();
+ }
+
+ gl::LinkedUniform *linkedUniform = getUniformByName(fullName);
+
+ if (!linkedUniform)
+ {
+ linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
+ -1, sh::BlockMemberInfo::getDefaultBlockInfo());
+ ASSERT(linkedUniform);
+ linkedUniform->registerElement = encoder->getCurrentElement();
+ mUniforms.push_back(linkedUniform);
+ }
+
+ ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
+
+ if (shader == GL_FRAGMENT_SHADER)
+ {
+ linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
+ }
+ else if (shader == GL_VERTEX_SHADER)
+ {
+ linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
+ }
+ else UNREACHABLE();
+
+ // Advance the uniform offset, to track registers allocation for structs
+ encoder->encodeType(uniform.type, uniform.arraySize, false);
+
+ // Arrays are treated as aggregate types
+ if (uniform.isArray())
+ {
+ encoder->exitAggregateType();
+ }
+ }
+}
+
+template <typename T>
+static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
+{
+ ASSERT(dest != NULL);
+ ASSERT(dirtyFlag != NULL);
+
+ *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0);
+ *dest = source;
+}
+
+template <typename T>
+void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
+{
+ const int components = gl::VariableComponentCount(targetUniformType);
+ const GLenum targetBoolType = gl::VariableBoolVectorType(targetUniformType);
+
+ gl::LinkedUniform *targetUniform = getUniformByLocation(location);
+
+ int elementCount = targetUniform->elementCount();
+
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+
+ if (targetUniform->type == targetUniformType)
+ {
+ T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ for (int i = 0; i < count; i++)
+ {
+ T *dest = target + (i * 4);
+ const T *source = v + (i * components);
+
+ for (int c = 0; c < components; c++)
+ {
+ SetIfDirty(dest + c, source[c], &targetUniform->dirty);
+ }
+ for (int c = components; c < 4; c++)
+ {
+ SetIfDirty(dest + c, T(0), &targetUniform->dirty);
+ }
+ }
+ }
+ else if (targetUniform->type == targetBoolType)
+ {
+ GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ for (int i = 0; i < count; i++)
+ {
+ GLint *dest = boolParams + (i * 4);
+ const T *source = v + (i * components);
+
+ for (int c = 0; c < components; c++)
+ {
+ SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
+ }
+ for (int c = components; c < 4; c++)
+ {
+ SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
+ }
+ }
+ }
+ else if (gl::IsSampler(targetUniform->type))
+ {
+ ASSERT(targetUniformType == GL_INT);
+
+ GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ bool wasDirty = targetUniform->dirty;
+
+ for (int i = 0; i < count; i++)
+ {
+ GLint *dest = target + (i * 4);
+ const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
+
+ SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
+ SetIfDirty(dest + 1, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 2, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 3, 0, &targetUniform->dirty);
+ }
+
+ if (!wasDirty && targetUniform->dirty)
+ {
+ mDirtySamplerMapping = true;
+ }
+ }
+ else UNREACHABLE();
+}
+
+template<typename T>
+bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
+{
+ bool dirty = false;
+ int copyWidth = std::min(targetHeight, srcWidth);
+ int copyHeight = std::min(targetWidth, srcHeight);
+
+ for (int x = 0; x < copyWidth; x++)
+ {
+ for (int y = 0; y < copyHeight; y++)
+ {
+ SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty);
+ }
+ }
+ // clear unfilled right side
+ for (int y = 0; y < copyWidth; y++)
+ {
+ for (int x = copyHeight; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+ // clear unfilled bottom.
+ for (int y = copyWidth; y < targetHeight; y++)
+ {
+ for (int x = 0; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+
+ return dirty;
+}
+
+template<typename T>
+bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
+{
+ bool dirty = false;
+ int copyWidth = std::min(targetWidth, srcWidth);
+ int copyHeight = std::min(targetHeight, srcHeight);
+
+ for (int y = 0; y < copyHeight; y++)
+ {
+ for (int x = 0; x < copyWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty);
+ }
+ }
+ // clear unfilled right side
+ for (int y = 0; y < copyHeight; y++)
+ {
+ for (int x = copyWidth; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+ // clear unfilled bottom.
+ for (int y = copyHeight; y < targetHeight; y++)
+ {
+ for (int x = 0; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+
+ return dirty;
+}
+
+template <int cols, int rows>
+void ProgramD3D::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
+{
+ gl::LinkedUniform *targetUniform = getUniformByLocation(location);
+
+ int elementCount = targetUniform->elementCount();
+
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+ const unsigned int targetMatrixStride = (4 * rows);
+ GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride);
+
+ for (int i = 0; i < count; i++)
+ {
+ // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
+ if (transpose == GL_FALSE)
+ {
+ targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty;
+ }
+ else
+ {
+ targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty;
+ }
+ target += targetMatrixStride;
+ value += cols * rows;
+ }
+}
+
+template <typename T>
+void ProgramD3D::getUniformv(GLint location, T *params, GLenum uniformType)
+{
+ gl::LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
+
+ if (gl::IsMatrixType(targetUniform->type))
+ {
+ const int rows = gl::VariableRowCount(targetUniform->type);
+ const int cols = gl::VariableColumnCount(targetUniform->type);
+ transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
+ }
+ else if (uniformType == gl::VariableComponentType(targetUniform->type))
+ {
+ unsigned int size = gl::VariableComponentCount(targetUniform->type);
+ memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
+ size * sizeof(T));
+ }
+ else
+ {
+ unsigned int size = gl::VariableComponentCount(targetUniform->type);
+ switch (gl::VariableComponentType(targetUniform->type))
+ {
+ case GL_BOOL:
+ {
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1);
+ }
+ }
+ break;
+
+ case GL_FLOAT:
+ {
+ GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(floatParams[i]);
+ }
+ }
+ break;
+
+ case GL_INT:
+ {
+ GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(intParams[i]);
+ }
+ }
+ break;
+
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(uintParams[i]);
+ }
+ }
+ break;
+
+ default: UNREACHABLE();
+ }
+ }
+}
+
+template <typename VarT>
+void ProgramD3D::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout)
+{
+ for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
+ {
+ const VarT &field = fields[uniformIndex];
+ const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
+
+ if (field.isStruct())
+ {
+ bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
+ for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
+ {
+ encoder->enterAggregateType();
+
+ const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
+ defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
+
+ encoder->exitAggregateType();
+ }
+ }
+ else
+ {
+ bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
+
+ sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
+
+ gl::LinkedUniform *newUniform = new gl::LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
+ blockIndex, memberInfo);
+
+ // add to uniform list, but not index, since uniform block uniforms have no location
+ blockUniformIndexes->push_back(mUniforms.size());
+ mUniforms.push_back(newUniform);
+ }
+ }
+}
+
+bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
+ const gl::Caps &caps)
+{
+ const ShaderD3D* shaderD3D = ShaderD3D::makeShaderD3D(shader.getImplementation());
+
+ // create uniform block entries if they do not exist
+ if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
+ {
+ std::vector<unsigned int> blockUniformIndexes;
+ const unsigned int blockIndex = mUniformBlocks.size();
+
+ // define member uniforms
+ sh::BlockLayoutEncoder *encoder = NULL;
+
+ if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
+ {
+ encoder = new sh::Std140BlockEncoder;
+ }
+ else
+ {
+ encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
+ }
+ ASSERT(encoder);
+
+ defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
+
+ size_t dataSize = encoder->getBlockSize();
+
+ // create all the uniform blocks
+ if (interfaceBlock.arraySize > 0)
+ {
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++)
+ {
+ gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize);
+ newUniformBlock->memberUniformIndexes = blockUniformIndexes;
+ mUniformBlocks.push_back(newUniformBlock);
+ }
+ }
+ else
+ {
+ gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize);
+ newUniformBlock->memberUniformIndexes = blockUniformIndexes;
+ mUniformBlocks.push_back(newUniformBlock);
+ }
+ }
+
+ if (interfaceBlock.staticUse)
+ {
+ // Assign registers to the uniform blocks
+ const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
+ const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
+ ASSERT(blockIndex != GL_INVALID_INDEX);
+ ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
+
+ unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
+
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
+ {
+ gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
+ ASSERT(uniformBlock->name == interfaceBlock.name);
+
+ if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
+ interfaceBlockRegister + uniformBlockElement, caps))
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex,
+ GLenum samplerType,
+ unsigned int samplerCount,
+ std::vector<Sampler> &outSamplers,
+ GLuint *outUsedRange)
+{
+ unsigned int samplerIndex = startSamplerIndex;
+
+ do
+ {
+ if (samplerIndex < outSamplers.size())
+ {
+ Sampler& sampler = outSamplers[samplerIndex];
+ sampler.active = true;
+ sampler.textureType = GetTextureType(samplerType);
+ sampler.logicalTextureUnit = 0;
+ *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
+ }
+ else
+ {
+ return false;
+ }
+
+ samplerIndex++;
+ } while (samplerIndex < startSamplerIndex + samplerCount);
+
+ return true;
+}
+
+bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps)
+{
+ ASSERT(gl::IsSampler(uniform.type));
+ ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
+
+ if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
+ {
+ if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
+ &mUsedVertexSamplerRange))
+ {
+ infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
+ mSamplersVS.size());
+ return false;
+ }
+
+ unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
+ if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
+ {
+ infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
+ caps.maxVertexUniformVectors);
+ return false;
+ }
+ }
+
+ if (uniform.psRegisterIndex != GL_INVALID_INDEX)
+ {
+ if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
+ &mUsedPixelSamplerRange))
+ {
+ infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
+ mSamplersPS.size());
+ return false;
+ }
+
+ unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
+ if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
+ {
+ infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
+ caps.maxFragmentUniformVectors);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
+{
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
+
+ if (gl::IsSampler(uniform.type))
+ {
+ if (!indexSamplerUniform(uniform, infoLog, caps))
+ {
+ return false;
+ }
+ }
+
+ for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++)
+ {
+ mUniformIndex.push_back(gl::VariableLocation(uniform.name, arrayElementIndex, uniformIndex));
+ }
+ }
+
+ return true;
+}
+
void ProgramD3D::reset()
{
+ ProgramImpl::reset();
+
+ SafeDeleteContainer(mVertexExecutables);
+ SafeDeleteContainer(mPixelExecutables);
+ SafeDelete(mGeometryExecutable);
+
+ mTransformFeedbackBufferMode = GL_NONE;
+
mVertexHLSL.clear();
- mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+ mVertexWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
+ mShaderVersion = 100;
mPixelHLSL.clear();
- mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+ mPixelWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
mUsesFragDepth = false;
mPixelShaderKey.clear();
+ mUsesPointSize = false;
SafeDelete(mVertexUniformStorage);
SafeDelete(mFragmentUniformStorage);
+
+ mSamplersPS.clear();
+ mSamplersVS.clear();
+
+ mUsedVertexSamplerRange = 0;
+ mUsedPixelSamplerRange = 0;
+ mDirtySamplerMapping = true;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h
index d645c57daa..4baab9aa19 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_PROGRAMD3D_H_
#include "libGLESv2/renderer/ProgramImpl.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include <string>
#include <vector>
@@ -23,63 +24,194 @@ struct VertexFormat;
namespace rx
{
-
+class RendererD3D;
class UniformStorage;
class ProgramD3D : public ProgramImpl
{
public:
- ProgramD3D(rx::Renderer *renderer);
+ ProgramD3D(RendererD3D *renderer);
virtual ~ProgramD3D();
static ProgramD3D *makeProgramD3D(ProgramImpl *impl);
static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl);
- Renderer *getRenderer() { return mRenderer; }
- DynamicHLSL *getDynamicHLSL() { return mDynamicHLSL; }
- const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
-
- GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
- bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
- bool save(gl::BinaryOutputStream *stream);
+ const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
+ int getShaderVersion() const { return mShaderVersion; }
+ GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
- ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers);
- ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers);
+ GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const;
+ GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
+ GLint getUsedSamplerRange(gl::SamplerType type) const;
+ void updateSamplerMapping();
+ bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps);
- bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables);
+ bool usesPointSize() const { return mUsesPointSize; }
+ bool usesPointSpriteEmulation() const;
+ bool usesGeometryShader() const;
- // D3D only
- void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms);
+ GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
+ gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
+ gl::Error save(gl::BinaryOutputStream *stream);
+
+ gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExectuable);
+ gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutable **outExectuable);
+ gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable);
+ ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; }
+
+ gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers);
+
+ gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables);
+
+ void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
+
+ void initializeUniformStorage();
+ gl::Error applyUniforms();
+ gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps);
+ bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
+ unsigned int registerIndex, const gl::Caps &caps);
+ void dirtyAllUniforms();
+
+ void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform1iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform2iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform3iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform4iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+
+ void getUniformfv(GLint location, GLfloat *params);
+ void getUniformiv(GLint location, GLint *params);
+ void getUniformuiv(GLint location, GLuint *params);
const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+ bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+ const gl::Caps &caps);
+ bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps);
+
void reset();
private:
DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
- Renderer *mRenderer;
+ class VertexExecutable
+ {
+ public:
+ VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+ const GLenum signature[gl::MAX_VERTEX_ATTRIBS],
+ ShaderExecutable *shaderExecutable);
+ ~VertexExecutable();
+
+ bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const;
+
+ const gl::VertexFormat *inputs() const { return mInputs; }
+ const GLenum *signature() const { return mSignature; }
+ ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS];
+ GLenum mSignature[gl::MAX_VERTEX_ATTRIBS];
+ ShaderExecutable *mShaderExecutable;
+ };
+
+ class PixelExecutable
+ {
+ public:
+ PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable);
+ ~PixelExecutable();
+
+ bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
+
+ const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
+ ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ std::vector<GLenum> mOutputSignature;
+ ShaderExecutable *mShaderExecutable;
+ };
+
+ struct Sampler
+ {
+ Sampler();
+
+ bool active;
+ GLint logicalTextureUnit;
+ GLenum textureType;
+ };
+
+ void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
+ void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName,
+ sh::HLSLBlockEncoder *encoder);
+ bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
+ bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
+ static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
+ std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
+
+ template <typename T>
+ void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
+
+ template <int cols, int rows>
+ void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
+
+ template <typename T>
+ void getUniformv(GLint location, T *params, GLenum uniformType);
+
+ template <typename VarT>
+ void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout);
+
+ RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL;
+ std::vector<VertexExecutable *> mVertexExecutables;
+ std::vector<PixelExecutable *> mPixelExecutables;
+ ShaderExecutable *mGeometryExecutable;
+
std::string mVertexHLSL;
- rx::D3DWorkaroundType mVertexWorkarounds;
+ D3DWorkaroundType mVertexWorkarounds;
std::string mPixelHLSL;
- rx::D3DWorkaroundType mPixelWorkarounds;
+ D3DWorkaroundType mPixelWorkarounds;
bool mUsesFragDepth;
- std::vector<rx::PixelShaderOutputVariable> mPixelShaderKey;
+ std::vector<PixelShaderOutputVariable> mPixelShaderKey;
+
+ bool mUsesPointSize;
UniformStorage *mVertexUniformStorage;
UniformStorage *mFragmentUniformStorage;
+
+ GLenum mTransformFeedbackBufferMode;
+
+ std::vector<Sampler> mSamplersPS;
+ std::vector<Sampler> mSamplersVS;
+ GLuint mUsedVertexSamplerRange;
+ GLuint mUsedPixelSamplerRange;
+ bool mDirtySamplerMapping;
+
+ int mShaderVersion;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
new file mode 100644
index 0000000000..cb4af367a2
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl
+
+
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
+
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace rx
+{
+RenderbufferD3D::RenderbufferD3D(RendererD3D *renderer) : mRenderer(renderer)
+{
+ mRenderTarget = NULL;
+}
+
+RenderbufferD3D::~RenderbufferD3D()
+{
+ SafeDelete(mRenderTarget);
+}
+
+RenderbufferD3D *RenderbufferD3D::makeRenderbufferD3D(RenderbufferImpl *renderbuffer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RenderbufferD3D*, renderbuffer));
+ return static_cast<RenderbufferD3D*>(renderbuffer);
+}
+
+gl::Error RenderbufferD3D::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
+{
+ // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage, but we should create depth and stencil buffers
+ // as DEPTH24_STENCIL8
+ GLenum creationFormat = internalformat;
+ if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8)
+ {
+ creationFormat = GL_DEPTH24_STENCIL8_OES;
+ }
+
+ RenderTarget *newRT = NULL;
+ gl::Error error = mRenderer->createRenderTarget(width, height, creationFormat, samples, &newRT);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ SafeDelete(mRenderTarget);
+ mRenderTarget = newRT;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RenderbufferD3D::setStorage(SwapChain *swapChain, bool depth)
+{
+ RenderTarget *newRT = NULL;
+ gl::Error error = mRenderer->createRenderTarget(swapChain, depth, &newRT);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ SafeDelete(mRenderTarget);
+ mRenderTarget = newRT;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+GLsizei RenderbufferD3D::getWidth() const
+{
+ return (mRenderTarget ? mRenderTarget->getWidth() : 0);
+}
+
+GLsizei RenderbufferD3D::getHeight() const
+{
+ return (mRenderTarget ? mRenderTarget->getHeight() : 0);
+}
+
+GLenum RenderbufferD3D::getInternalFormat() const
+{
+ return (mRenderTarget ? mRenderTarget->getInternalFormat() : GL_RGBA4);
+}
+
+GLenum RenderbufferD3D::getActualFormat() const
+{
+ return (mRenderTarget ? mRenderTarget->getActualFormat() : GL_RGBA4);
+}
+
+GLsizei RenderbufferD3D::getSamples() const
+{
+ return (mRenderTarget ? mRenderTarget->getSamples() : 0);
+}
+
+RenderTarget *RenderbufferD3D::getRenderTarget()
+{
+ return mRenderTarget;
+}
+
+unsigned int RenderbufferD3D::getRenderTargetSerial() const
+{
+ return (mRenderTarget ? mRenderTarget->getSerial() : 0);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
new file mode 100644
index 0000000000..9440a449f2
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferD3d.h: Defines the RenderbufferD3D class which implements RenderbufferImpl.
+
+#ifndef LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
+#define LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
+
+#include "angle_gl.h"
+
+#include "common/angleutils.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+class RendererD3D;
+class RenderTarget;
+class SwapChain;
+
+class RenderbufferD3D : public RenderbufferImpl
+{
+ public:
+ RenderbufferD3D(RendererD3D *renderer);
+ virtual ~RenderbufferD3D();
+
+ static RenderbufferD3D *makeRenderbufferD3D(RenderbufferImpl *renderbuffer);
+
+ virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) override;
+ gl::Error setStorage(SwapChain *swapChain, bool depth);
+
+ virtual GLsizei getWidth() const;
+ virtual GLsizei getHeight() const;
+ virtual GLenum getInternalFormat() const;
+ virtual GLenum getActualFormat() const;
+ virtual GLsizei getSamples() const;
+
+ RenderTarget *getRenderTarget();
+ unsigned int getRenderTargetSerial() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderbufferD3D);
+
+ RendererD3D *mRenderer;
+ RenderTarget *mRenderTarget;
+};
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
new file mode 100644
index 0000000000..97da6da7fd
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
@@ -0,0 +1,796 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RendererD3D.cpp: Implementation of the base D3D Renderer.
+
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
+
+#include "libGLESv2/renderer/d3d/IndexDataManager.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/State.h"
+#include "libGLESv2/VertexArray.h"
+#include "libGLESv2/formatutils.h"
+#include "common/utilities.h"
+
+namespace rx
+{
+
+RendererD3D::RendererD3D(egl::Display *display)
+ : mDisplay(display)
+{
+}
+
+RendererD3D::~RendererD3D()
+{
+ for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
+ {
+ i->second.set(NULL);
+ }
+ mIncompleteTextures.clear();
+}
+
+// static
+RendererD3D *RendererD3D::makeRendererD3D(Renderer *renderer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RendererD3D*, renderer));
+ return static_cast<RendererD3D*>(renderer);
+}
+
+gl::Error RendererD3D::drawElements(const gl::Data &data,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange)
+{
+ ASSERT(data.state->getCurrentProgramId() != 0);
+
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ programBinary->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ gl::VertexArray *vao = data.state->getVertexArray();
+ TranslatedIndexData indexInfo;
+ indexInfo.indexRange = indexRange;
+ error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+ error = applyVertexBuffer(*data.state, indexInfo.indexRange.start, vertexCount, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
+ // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
+ // layer.
+ ASSERT(!transformFeedbackActive);
+
+ error = applyShaders(data, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::drawArrays(const gl::Data &data,
+ GLenum mode, GLint first,
+ GLsizei count, GLsizei instances)
+{
+ ASSERT(data.state->getCurrentProgramId() != 0);
+
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ programBinary->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyVertexBuffer(*data.state, first, count, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
+
+ error = applyShaders(data, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawArrays(mode, count, instances, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (transformFeedbackActive)
+ {
+ markTransformFeedbackUsage(data);
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ size_t samplerRange = programBinary->getUsedSamplerRange(type);
+
+ for (size_t i = 0; i < samplerRange; i++)
+ {
+ GLenum textureType = programBinary->getSamplerTextureType(type, i);
+ GLint textureUnit = programBinary->getSamplerMapping(type, i, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ if (texture->getSamplerState().swizzleRequired())
+ {
+ gl::Error error = generateSwizzle(texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data)
+{
+ gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = generateSwizzles(data, gl::SAMPLER_PIXEL);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and
+// scissor rectangle to the renderer
+gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ ASSERT(framebufferObject && framebufferObject->completeness(data) == GL_FRAMEBUFFER_COMPLETE);
+
+ gl::Error error = applyRenderTarget(framebufferObject);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ float nearZ, farZ;
+ data.state->getDepthRange(&nearZ, &farZ);
+ setViewport(data.state->getViewport(), nearZ, farZ, drawMode,
+ data.state->getRasterizerState().frontFace, ignoreViewport);
+
+ setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device
+gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ int samples = framebufferObject->getSamples(data);
+
+ gl::RasterizerState rasterizer = data.state->getRasterizerState();
+ rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+ rasterizer.multiSample = (samples != 0);
+
+ gl::Error error = setRasterizerState(rasterizer);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ unsigned int mask = 0;
+ if (data.state->isSampleCoverageEnabled())
+ {
+ GLclampf coverageValue;
+ bool coverageInvert = false;
+ data.state->getSampleCoverageParams(&coverageValue, &coverageInvert);
+ if (coverageValue != 0)
+ {
+ float threshold = 0.5f;
+
+ for (int i = 0; i < samples; ++i)
+ {
+ mask <<= 1;
+
+ if ((i + 1) * coverageValue >= threshold)
+ {
+ threshold += 1.0f;
+ mask |= 1;
+ }
+ }
+ }
+
+ if (coverageInvert)
+ {
+ mask = ~mask;
+ }
+ }
+ else
+ {
+ mask = 0xFFFFFFFF;
+ }
+ error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(),
+ data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool RendererD3D::applyTransformFeedbackBuffers(const gl::Data &data)
+{
+ gl::TransformFeedback *curTransformFeedback = data.state->getCurrentTransformFeedback();
+ if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
+ {
+ applyTransformFeedbackBuffers(*data.state);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// Applies the shaders and shader constants to the Direct3D device
+gl::Error RendererD3D::applyShaders(const gl::Data &data, bool transformFeedbackActive)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+ gl::VertexFormat::GetInputLayout(inputLayout, programBinary, *data.state);
+
+ const gl::Framebuffer *fbo = data.state->getDrawFramebuffer();
+
+ gl::Error error = applyShaders(programBinary, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return programBinary->applyUniforms();
+}
+
+// For each Direct3D sampler of either the pixel or vertex stage,
+// looks up the corresponding OpenGL texture image unit and texture type,
+// and sets the texture and its addressing/filtering state (or NULL when inactive).
+gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
+ for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
+ {
+ GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
+ GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ gl::SamplerState sampler = texture->getSamplerState();
+
+ gl::Sampler *samplerObject = data.state->getSampler(textureUnit);
+ if (samplerObject)
+ {
+ samplerObject->getState(&sampler);
+ }
+
+ // TODO: std::binary_search may become unavailable using older versions of GCC
+ if (texture->isSamplerComplete(sampler, *data.textureCaps, *data.extensions, data.clientVersion) &&
+ !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
+ {
+ gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setTexture(shaderType, samplerIndex, texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
+ gl::Texture *incompleteTexture = getIncompleteTexture(textureType);
+ gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ else
+ {
+ // No texture bound to this slot even though it is used by the shader, bind a NULL texture
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+
+ // Set all the remaining textures to NULL
+ size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits
+ : data.caps->maxVertexTextureImageUnits;
+ for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
+ {
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::applyTextures(const gl::Data &data)
+{
+ FramebufferTextureSerialArray framebufferSerials;
+ size_t framebufferSerialCount = getBoundFramebufferTextureSerials(data, &framebufferSerials);
+
+ gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::applyUniformBuffers(const gl::Data &data)
+{
+ gl::Program *programObject = data.resourceManager->getProgram(data.state->getCurrentProgramId());
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+ std::vector<gl::Buffer*> boundBuffers;
+
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
+ {
+ GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
+
+ if (data.state->getIndexedUniformBuffer(blockBinding)->id() == 0)
+ {
+ // undefined behaviour
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
+ }
+ else
+ {
+ gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(blockBinding);
+ ASSERT(uniformBuffer);
+ boundBuffers.push_back(uniformBuffer);
+ }
+ }
+
+ return programBinary->applyUniformBuffers(boundBuffers, *data.caps);
+}
+
+bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode)
+{
+ if (drawMode == GL_POINTS)
+ {
+ // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
+ // which affects varying interpolation. Since the value of gl_PointSize is
+ // undefined when not written, just skip drawing to avoid unexpected results.
+ if (!data.state->getCurrentProgramBinary()->usesPointSize())
+ {
+ // This is stictly speaking not an error, but developers should be
+ // notified of risking undefined behavior.
+ ERR("Point rendering without writing to gl_PointSize.");
+
+ return true;
+ }
+ }
+ else if (gl::IsTriangleMode(drawMode))
+ {
+ if (data.state->getRasterizerState().cullFace && data.state->getRasterizerState().cullMode == GL_FRONT_AND_BACK)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void RendererD3D::markTransformFeedbackUsage(const gl::Data &data)
+{
+ for (size_t i = 0; i < data.caps->maxTransformFeedbackSeparateAttributes; i++)
+ {
+ gl::Buffer *buffer = data.state->getIndexedTransformFeedbackBuffer(i);
+ if (buffer)
+ {
+ buffer->markTransformFeedbackUsage();
+ }
+ }
+}
+
+size_t RendererD3D::getBoundFramebufferTextureSerials(const gl::Data &data,
+ FramebufferTextureSerialArray *outSerialArray)
+{
+ size_t serialCount = 0;
+
+ const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
+ {
+ gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
+ if (attachment && attachment->isTexture())
+ {
+ gl::Texture *texture = attachment->getTexture();
+ (*outSerialArray)[serialCount++] = texture->getTextureSerial();
+ }
+ }
+
+ gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
+ if (depthStencilAttachment && depthStencilAttachment->isTexture())
+ {
+ gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture();
+ (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
+ }
+
+ std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
+
+ return serialCount;
+}
+
+gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
+{
+ if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
+ {
+ const GLubyte color[] = { 0, 0, 0, 255 };
+ const gl::PixelUnpackState incompleteUnpackState(1);
+
+ gl::Texture* t = NULL;
+ switch (type)
+ {
+ default:
+ UNREACHABLE();
+ // default falls through to TEXTURE_2D
+
+ case GL_TEXTURE_2D:
+ {
+ gl::Texture2D *incomplete2d = new gl::Texture2D(createTexture(GL_TEXTURE_2D), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ t = incomplete2d;
+ }
+ break;
+
+ case GL_TEXTURE_CUBE_MAP:
+ {
+ gl::TextureCubeMap *incompleteCube = new gl::TextureCubeMap(createTexture(GL_TEXTURE_CUBE_MAP), gl::Texture::INCOMPLETE_TEXTURE_ID);
+
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incompleteCube;
+ }
+ break;
+
+ case GL_TEXTURE_3D:
+ {
+ gl::Texture3D *incomplete3d = new gl::Texture3D(createTexture(GL_TEXTURE_3D), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incomplete3d;
+ }
+ break;
+
+ case GL_TEXTURE_2D_ARRAY:
+ {
+ gl::Texture2DArray *incomplete2darray = new gl::Texture2DArray(createTexture(GL_TEXTURE_2D_ARRAY), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incomplete2darray;
+ }
+ break;
+ }
+
+ mIncompleteTextures[type].set(t);
+ }
+
+ return mIncompleteTextures[type].get();
+}
+
+gl::Error RendererD3D::clear(const gl::Data &data, GLbitfield mask)
+{
+ gl::ClearParameters clearParams = data.state->getClearParameters(mask);
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values)
+{
+ // glClearBufferfv can be called to clear the color buffer or depth buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_FLOAT;
+ }
+
+ if (buffer == GL_DEPTH)
+ {
+ clearParams.clearDepth = true;
+ clearParams.depthClearValue = values[0];
+ }
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values)
+{
+ // glClearBufferuiv can only be called to clear a color buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_UNSIGNED_INT;
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values)
+{
+ // glClearBufferiv can be called to clear the color buffer or stencil buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_INT;
+ }
+
+ if (buffer == GL_STENCIL)
+ {
+ clearParams.clearStencil = true;
+ clearParams.stencilClearValue = values[1];
+ }
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer,
+ GLfloat depth, GLint stencil)
+{
+ if (data.state->isRasterizerDiscardEnabled())
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ // glClearBufferfi can only be called to clear a depth stencil buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+ clearParams.clearDepth = true;
+ clearParams.depthClearValue = depth;
+ clearParams.clearStencil = true;
+ clearParams.stencilClearValue = stencil;
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::blitFramebuffer(const gl::Data &data,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ const gl::Framebuffer *readFramebuffer = data.state->getReadFramebuffer();
+ const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
+
+ bool blitRenderTarget = false;
+ bool blitDepth = false;
+ bool blitStencil = false;
+ if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
+ {
+ blitRenderTarget = true;
+ }
+ if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
+ {
+ blitStencil = true;
+ }
+ if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
+ {
+ blitDepth = true;
+ }
+
+ gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+ gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+ if (blitRenderTarget || blitDepth || blitStencil)
+ {
+ const gl::Rectangle *scissor = data.state->isScissorTestEnabled() ? &data.state->getScissor() : NULL;
+ gl::Error error = blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
+ blitRenderTarget, blitDepth, blitStencil, filter);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+{
+ const gl::Framebuffer *framebuffer = data.state->getReadFramebuffer();
+
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type);
+ const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
+ GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, data.state->getPackAlignment());
+
+ return readPixels(framebuffer, x, y, width, height, format, type, outputPitch, data.state->getPackState(),
+ reinterpret_cast<uint8_t*>(pixels));
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
new file mode 100644
index 0000000000..9919207667
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
@@ -0,0 +1,195 @@
+
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RendererD3D.h: Defines a back-end specific class for the DirectX renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERERD3D_H_
+#define LIBGLESV2_RENDERER_RENDERERD3D_H_
+
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Data.h"
+
+//FIXME(jmadill): std::array is currently prohibited by Chromium style guide
+#include <array>
+
+namespace gl
+{
+class InfoLog;
+struct LinkedVarying;
+class Texture;
+}
+
+namespace rx
+{
+class TextureStorage;
+class VertexBuffer;
+class IndexBuffer;
+class ShaderExecutable;
+class SwapChain;
+class RenderTarget;
+class Image;
+class TextureStorage;
+class UniformStorage;
+
+class RendererD3D : public Renderer
+{
+ public:
+ explicit RendererD3D(egl::Display *display);
+ virtual ~RendererD3D();
+
+ static RendererD3D *makeRendererD3D(Renderer *renderer);
+
+ gl::Error drawArrays(const gl::Data &data,
+ GLenum mode, GLint first,
+ GLsizei count, GLsizei instances) override;
+
+ gl::Error drawElements(const gl::Data &data,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange) override;
+
+ gl::Error clear(const gl::Data &data, GLbitfield mask) override;
+ gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLfloat *values) override;
+ gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLuint *values) override;
+ gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLint *values) override;
+ gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
+
+ gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, void* pixels) override;
+
+ gl::Error blitFramebuffer(const gl::Data &data,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter) override;
+
+ // Direct3D Specific methods
+ virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+
+ virtual gl::Error generateSwizzle(gl::Texture *texture) = 0;
+ virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0;
+ virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
+
+ virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0;
+
+ virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0;
+ virtual gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) = 0;
+ virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
+ int stencilBackRef, bool frontFaceCCW) = 0;
+
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
+ virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+ bool ignoreViewport) = 0;
+
+ virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
+ virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ bool rasterizerDiscard, bool transformFeedbackActive) = 0;
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
+ virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0;
+
+ virtual void markAllStateDirty() = 0;
+
+ virtual unsigned int getReservedVertexUniformVectors() const = 0;
+ virtual unsigned int getReservedFragmentUniformVectors() const = 0;
+ virtual unsigned int getReservedVertexUniformBuffers() const = 0;
+ virtual unsigned int getReservedFragmentUniformBuffers() const = 0;
+ virtual bool getShareHandleSupport() const = 0;
+ virtual bool getPostSubBufferSupport() const = 0;
+
+ // Pixel operations
+ virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0;
+ virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0;
+ virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
+ virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
+
+ virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0;
+
+ // RenderTarget creation
+ virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) = 0;
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) = 0;
+
+ // Shader operations
+ virtual void releaseShaderCompiler() = 0;
+ virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable) = 0;
+ virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable) = 0;
+ virtual UniformStorage *createUniformStorage(size_t storageSize) = 0;
+
+ // Image operations
+ virtual Image *createImage() = 0;
+ virtual gl::Error generateMipmap(Image *dest, Image *source) = 0;
+ virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0;
+ virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0;
+ virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0;
+ virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
+ virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
+
+ // Buffer-to-texture and Texture-to-buffer copies
+ virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0;
+
+ virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0;
+ virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0;
+
+ virtual VertexBuffer *createVertexBuffer() = 0;
+ virtual IndexBuffer *createIndexBuffer() = 0;
+
+ protected:
+ virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
+ virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
+ gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
+ virtual gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) = 0;
+ virtual gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter) = 0;
+
+ egl::Display *mDisplay;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RendererD3D);
+
+ //FIXME(jmadill): std::array is currently prohibited by Chromium style guide
+ typedef std::array<unsigned int, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
+
+ gl::Error generateSwizzles(const gl::Data &data, gl::SamplerType type);
+ gl::Error generateSwizzles(const gl::Data &data);
+
+ gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport);
+ gl::Error applyState(const gl::Data &data, GLenum drawMode);
+ bool applyTransformFeedbackBuffers(const gl::Data &data);
+ gl::Error applyShaders(const gl::Data &data, bool transformFeedbackActive);
+ gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount);
+ gl::Error applyTextures(const gl::Data &data);
+ gl::Error applyUniformBuffers(const gl::Data &data);
+
+ bool skipDraw(const gl::Data &data, GLenum drawMode);
+ void markTransformFeedbackUsage(const gl::Data &data);
+
+ size_t getBoundFramebufferTextureSerials(const gl::Data &data,
+ FramebufferTextureSerialArray *outSerialArray);
+ gl::Texture *getIncompleteTexture(GLenum type);
+
+ gl::TextureMap mIncompleteTextures;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERERD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
index c472113eba..8a97579e16 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
@@ -6,13 +6,36 @@
// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "common/features.h"
#include "common/utilities.h"
+// Definitions local to the translation unit
+namespace
+{
+
+const char *GetShaderTypeString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_VERTEX_SHADER:
+ return "VERTEX";
+
+ case GL_FRAGMENT_SHADER:
+ return "FRAGMENT";
+
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+}
+
namespace rx
{
@@ -44,13 +67,13 @@ const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableLis
return variableList;
}
-ShaderD3D::ShaderD3D(GLenum type, rx::Renderer *renderer)
+ShaderD3D::ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer)
: mType(type),
mRenderer(renderer),
mShaderVersion(100)
{
uncompile();
- initializeCompiler();
+ initializeCompiler(data);
}
ShaderD3D::~ShaderD3D()
@@ -69,23 +92,28 @@ const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl)
return static_cast<const ShaderD3D*>(impl);
}
+std::string ShaderD3D::getDebugInfo() const
+{
+ return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mType) + " SHADER END\n";
+}
+
// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
-void ShaderD3D::initializeCompiler()
+void ShaderD3D::initializeCompiler(const gl::Data &data)
{
if (!mFragmentCompiler)
{
- int result = ShInitialize();
+ bool result = ShInitialize();
if (result)
{
+ ShShaderSpec specVersion = (data.clientVersion >= 3) ? SH_GLES3_SPEC : SH_GLES2_SPEC;
ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
ShBuiltInResources resources;
ShInitBuiltInResources(&resources);
- // TODO(geofflang): use context's caps
- const gl::Caps &caps = mRenderer->getRendererCaps();
- const gl::Extensions &extensions = mRenderer->getRendererExtensions();
+ const gl::Caps &caps = *data.caps;
+ const gl::Extensions &extensions = *data.extensions;
resources.MaxVertexAttribs = caps.maxVertexAttributes;
resources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
@@ -107,8 +135,8 @@ void ShaderD3D::initializeCompiler()
resources.MinProgramTexelOffset = caps.minProgramTexelOffset;
resources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
- mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
- mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
+ mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, specVersion, hlslVersion, &resources);
+ mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, specVersion, hlslVersion, &resources);
}
}
}
@@ -126,7 +154,7 @@ void ShaderD3D::releaseCompiler()
void ShaderD3D::parseVaryings(void *compiler)
{
- if (!mHlsl.empty())
+ if (!mHlsl.empty())
{
const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler);
ASSERT(varyings);
@@ -183,21 +211,25 @@ void ShaderD3D::uncompile()
mInterfaceBlocks.clear();
mActiveAttributes.clear();
mActiveOutputVariables.clear();
+ mDebugInfo.clear();
}
-void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
+void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::string &source)
{
// ensure the compiler is loaded
- initializeCompiler();
+ initializeCompiler(data);
int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);
std::string sourcePath;
+
+#if !defined (ANGLE_ENABLE_WINDOWS_STORE)
if (gl::perfActive())
{
sourcePath = getTempPath();
writeFile(sourcePath.c_str(), source.c_str(), source.length());
compileOptions |= SH_LINE_DIRECTIVES;
}
+#endif
int result;
if (sourcePath.empty())
@@ -220,25 +252,20 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH);
}
- size_t shaderVersion = 100;
- ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion);
+ mShaderVersion = ShGetShaderVersion(compiler);
- mShaderVersion = static_cast<int>(shaderVersion);
-
- if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3)
+ if (mShaderVersion == 300 && data.clientVersion < 3)
{
mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
TRACE("\n%s", mInfoLog.c_str());
}
else if (result)
{
- size_t objCodeLen = 0;
- ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
-
- char* outputHLSL = new char[objCodeLen];
- ShGetObjectCode(compiler, outputHLSL);
+ mHlsl = ShGetObjectCode(compiler);
#ifdef _DEBUG
+ // Prefix hlsl shader with commented out glsl shader
+ // Useful in diagnostics tools like pix which capture the hlsl shaders
std::ostringstream hlslStream;
hlslStream << "// GLSL\n";
hlslStream << "//\n";
@@ -254,14 +281,10 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
}
hlslStream << "\n\n";
- hlslStream << outputHLSL;
+ hlslStream << mHlsl;
mHlsl = hlslStream.str();
-#else
- mHlsl = outputHLSL;
#endif
- SafeDeleteArray(outputHLSL);
-
mUniforms = *GetShaderVariables(ShGetUniforms(compiler));
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
@@ -271,7 +294,7 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
if (uniform.staticUse)
{
unsigned int index = -1;
- bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
+ bool result = ShGetUniformRegister(compiler, uniform.name, &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
@@ -288,7 +311,7 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
if (interfaceBlock.staticUse)
{
unsigned int index = -1;
- bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index);
+ bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
@@ -298,24 +321,19 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
}
else
{
- size_t infoLogLen = 0;
- ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
-
- char* infoLog = new char[infoLogLen];
- ShGetInfoLog(compiler, infoLog);
- mInfoLog = infoLog;
+ mInfoLog = ShGetInfoLog(compiler);
TRACE("\n%s", mInfoLog.c_str());
}
}
-rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
+D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
{
if (mUsesDiscardRewriting)
{
// ANGLE issue 486:
// Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
- return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
+ return ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
}
if (mUsesNestedBreak)
@@ -323,10 +341,10 @@ rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
// ANGLE issue 603:
// Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization
// We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence
- return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
+ return ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
}
- return rx::ANGLE_D3D_WORKAROUND_NONE;
+ return ANGLE_D3D_WORKAROUND_NONE;
}
// true if varying x has a higher priority in packing than y
@@ -387,19 +405,16 @@ ShShaderOutput ShaderD3D::getCompilerOutputType(GLenum shader)
default: UNREACHABLE(); return SH_HLSL9_OUTPUT;
}
- size_t outputType = 0;
- ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType);
-
- return static_cast<ShShaderOutput>(outputType);
+ return ShGetShaderOutputType(compiler);
}
-bool ShaderD3D::compile(const std::string &source)
+bool ShaderD3D::compile(const gl::Data &data, const std::string &source)
{
uncompile();
void *compiler = getCompiler();
- compileToHLSL(compiler, source);
+ compileToHLSL(data, compiler, source);
if (mType == GL_VERTEX_SHADER)
{
@@ -420,6 +435,15 @@ bool ShaderD3D::compile(const std::string &source)
}
}
+#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ mDebugInfo += std::string("// ") + GetShaderTypeString(mType) + " SHADER BEGIN\n";
+ mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n";
+ mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n";
+ // Successive steps will append more info
+#else
+ mDebugInfo += getTranslatedSource();
+#endif
+
return !getTranslatedSource().empty();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h
index 40e64cf36c..3c9aac2c12 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_SHADERD3D_H_
#include "libGLESv2/renderer/ShaderImpl.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include "libGLESv2/Shader.h"
#include <map>
@@ -17,22 +18,23 @@
namespace rx
{
class DynamicHLSL;
-class Renderer;
+class RendererD3D;
class ShaderD3D : public ShaderImpl
{
friend class DynamicHLSL;
public:
- ShaderD3D(GLenum type, rx::Renderer *renderer);
+ ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer);
virtual ~ShaderD3D();
static ShaderD3D *makeShaderD3D(ShaderImpl *impl);
static const ShaderD3D *makeShaderD3D(const ShaderImpl *impl);
// ShaderImpl implementation
- const std::string &getInfoLog() const { return mInfoLog; }
- const std::string &getTranslatedSource() const { return mHlsl; }
+ virtual const std::string &getInfoLog() const { return mInfoLog; }
+ virtual const std::string &getTranslatedSource() const { return mHlsl; }
+ virtual std::string getDebugInfo() const;
// D3D-specific methods
virtual void uncompile();
@@ -40,8 +42,9 @@ class ShaderD3D : public ShaderImpl
unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
int getSemanticIndex(const std::string &attributeName) const;
+ void appendDebugInfo(const std::string &info) { mDebugInfo += info; }
- rx::D3DWorkaroundType getD3DWorkarounds() const;
+ D3DWorkaroundType getD3DWorkarounds() const;
int getShaderVersion() const { return mShaderVersion; }
bool usesDepthRange() const { return mUsesDepthRange; }
bool usesPointSize() const { return mUsesPointSize; }
@@ -49,15 +52,15 @@ class ShaderD3D : public ShaderImpl
static void releaseCompiler();
static ShShaderOutput getCompilerOutputType(GLenum shader);
- virtual bool compile(const std::string &source);
+ virtual bool compile(const gl::Data &data, const std::string &source);
private:
DISALLOW_COPY_AND_ASSIGN(ShaderD3D);
- void compileToHLSL(void *compiler, const std::string &source);
+ void compileToHLSL(const gl::Data &data, void *compiler, const std::string &source);
void parseVaryings(void *compiler);
- void initializeCompiler();
+ void initializeCompiler(const gl::Data &data);
void parseAttributes(void *compiler);
void *getCompiler();
@@ -67,7 +70,7 @@ class ShaderD3D : public ShaderImpl
static void *mVertexCompiler;
GLenum mType;
- rx::Renderer *mRenderer;
+ RendererD3D *mRenderer;
int mShaderVersion;
@@ -85,6 +88,7 @@ class ShaderD3D : public ShaderImpl
std::string mHlsl;
std::string mInfoLog;
+ std::string mDebugInfo;
std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index 96c84977cb..4a67701fdf 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -6,9 +6,6 @@
// TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends.
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
-#include "libGLESv2/renderer/d3d/ImageD3D.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/Texture.h"
@@ -16,7 +13,11 @@
#include "libGLESv2/formatutils.h"
#include "libGLESv2/renderer/BufferImpl.h"
#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
+#include "libGLESv2/renderer/d3d/ImageD3D.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libEGL/Surface.h"
@@ -26,16 +27,51 @@
namespace rx
{
+namespace
+{
+
+gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const void *pixels, const uint8_t **pointerOut)
+{
+ if (unpack.pixelBuffer.id() != 0)
+ {
+ // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
+ gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
+ ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+
+ // TODO: this is the only place outside of renderer that asks for a buffers raw data.
+ // This functionality should be moved into renderer and the getData method of BufferImpl removed.
+ BufferD3D *bufferD3D = BufferD3D::makeBufferD3D(pixelBuffer->getImplementation());
+ ASSERT(bufferD3D);
+ const uint8_t *bufferData = NULL;
+ gl::Error error = bufferD3D->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *pointerOut = bufferData + offset;
+ }
+ else
+ {
+ *pointerOut = static_cast<const uint8_t *>(pixels);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
bool IsRenderTargetUsage(GLenum usage)
{
return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
}
-TextureD3D::TextureD3D(Renderer *renderer)
+}
+
+TextureD3D::TextureD3D(RendererD3D *renderer)
: mRenderer(renderer),
mUsage(GL_NONE),
mDirtyImages(true),
- mImmutable(false)
+ mImmutable(false),
+ mTexStorage(NULL)
{
}
@@ -54,13 +90,12 @@ TextureStorage *TextureD3D::getNativeTexture()
// ensure the underlying texture is created
initializeStorage(false);
- TextureStorage *storage = getBaseLevelStorage();
- if (storage)
+ if (mTexStorage)
{
updateStorage();
}
- return storage;
+ return mTexStorage;
}
GLint TextureD3D::getBaseLevelWidth() const
@@ -90,50 +125,79 @@ GLenum TextureD3D::getBaseLevelInternalFormat() const
return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
}
-void TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image)
+bool TextureD3D::shouldUseSetData(const Image *image) const
+{
+ if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload)
+ {
+ return false;
+ }
+
+ gl::InternalFormat internalFormat = gl::GetInternalFormatInfo(image->getInternalFormat());
+
+ // We can only handle full updates for depth-stencil textures, so to avoid complications
+ // disable them entirely.
+ if (internalFormat.depthBits > 0 || internalFormat.stencilBits > 0)
+ {
+ return false;
+ }
+
+ // TODO(jmadill): Handle compressed internal formats
+ return (mTexStorage && !internalFormat.compressed);
+}
+
+gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index)
{
+ Image *image = getImage(index);
+ ASSERT(image);
+
// No-op
if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
// From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
- const void *pixelData = pixels;
-
- if (unpack.pixelBuffer.id() != 0)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
- gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
- ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
- // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
- // This functionality should be moved into renderer and the getData method of BufferImpl removed.
- const void *bufferData = pixelBuffer->getImplementation()->getData();
- pixelData = static_cast<const unsigned char *>(bufferData) + offset;
+ return error;
}
if (pixelData != NULL)
{
- image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
+ gl::Error error(GL_NO_ERROR);
+
+ if (shouldUseSetData(image))
+ {
+ error = mTexStorage->setData(index, image, NULL, type, unpack, pixelData);
+ }
+ else
+ {
+ error = image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
+ }
+
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
+
+ return gl::Error(GL_NO_ERROR);
}
-bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
+gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
{
- const void *pixelData = pixels;
-
// CPU readback & copy where direct GPU copy is not supported
- if (unpack.pixelBuffer.id() != 0)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
- ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
- // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
- // This functionality should be moved into renderer and the getData method of BufferImpl removed.
- const void *bufferData = pixelBuffer->getImplementation()->getData();
- pixelData = static_cast<const unsigned char *>(bufferData) + offset;
+ return error;
}
if (pixelData != NULL)
@@ -141,32 +205,78 @@ bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei w
Image *image = getImage(index);
ASSERT(image);
- image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData);
+ gl::Box region(xoffset, yoffset, zoffset, width, height, depth);
+ if (shouldUseSetData(image))
+ {
+ return mTexStorage->setData(index, image, &region, type, unpack, pixelData);
+ }
+
+ gl::Error error = image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment,
+ type, pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
+gl::Error TextureD3D::setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image)
{
- if (pixels != NULL)
+ // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
+ // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (pixelData != NULL)
{
- image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels);
+ gl::Error error = image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
+
+ return gl::Error(GL_NO_ERROR);
}
-bool TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const void *pixels, Image *image)
+gl::Error TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image)
{
- if (pixels != NULL)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (pixelData != NULL)
{
- image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels);
+ gl::Error error = image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat)
@@ -174,21 +284,28 @@ bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum siz
return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
}
-bool TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
- GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget)
+gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
+ GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget)
{
+ // No-op
if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
{
- return true;
+ return gl::Error(GL_NO_ERROR);
}
// In order to perform the fast copy through the shader, we must have the right format, and be able
// to create a render target.
ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
- ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+ uintptr_t offset = reinterpret_cast<uintptr_t>(pixels);
- return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
+ gl::Error error = mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
@@ -210,10 +327,192 @@ int TextureD3D::mipLevels() const
return gl::log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
}
+TextureStorage *TextureD3D::getStorage()
+{
+ ASSERT(mTexStorage);
+ return mTexStorage;
+}
-TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+Image *TextureD3D::getBaseLevelImage() const
+{
+ return getImage(getImageIndex(0, 0));
+}
+
+gl::Error TextureD3D::generateMipmaps()
+{
+ GLint mipCount = mipLevels();
+
+ if (mipCount == 1)
+ {
+ return gl::Error(GL_NO_ERROR); // no-op
+ }
+
+ // Set up proper mipmap chain in our Image array.
+ initMipmapsImages();
+
+ // We know that all layers have the same dimension, for the texture to be complete
+ GLint layerCount = static_cast<GLint>(getLayerCount(0));
+
+ // When making mipmaps with the setData workaround enabled, the texture storage has
+ // the image data already. For non-render-target storage, we have to pull it out into
+ // an image layer.
+ if (mRenderer->getWorkarounds().setDataFasterThanImageUpload && mTexStorage)
+ {
+ if (!mTexStorage->isRenderTarget())
+ {
+ // Copy from the storage mip 0 to Image mip 0
+ for (GLint layer = 0; layer < layerCount; ++layer)
+ {
+ gl::ImageIndex srcIndex = getImageIndex(0, layer);
+
+ Image *image = getImage(srcIndex);
+ gl::Rectangle area(0, 0, image->getWidth(), image->getHeight());
+ gl::Error error = image->copy(0, 0, 0, area, srcIndex, mTexStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ else
+ {
+ gl::Error error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+
+ bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget());
+
+ for (GLint layer = 0; layer < layerCount; ++layer)
+ {
+ for (GLint mip = 1; mip < mipCount; ++mip)
+ {
+ ASSERT(getLayerCount(mip) == layerCount);
+
+ gl::ImageIndex sourceIndex = getImageIndex(mip - 1, layer);
+ gl::ImageIndex destIndex = getImageIndex(mip, layer);
+
+ if (renderableStorage)
+ {
+ // GPU-side mipmapping
+ gl::Error error = mTexStorage->generateMipmap(sourceIndex, destIndex);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ // CPU-side mipmapping
+ gl::Error error = mRenderer->generateMipmap(getImage(destIndex), getImage(sourceIndex));
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool TextureD3D::isBaseImageZeroSize() const
+{
+ Image *baseImage = getBaseLevelImage();
+
+ if (!baseImage || baseImage->getWidth() <= 0)
+ {
+ return true;
+ }
+
+ if (!gl::IsCubemapTextureTarget(baseImage->getTarget()) && baseImage->getHeight() <= 0)
+ {
+ return true;
+ }
+
+ if (baseImage->getTarget() == GL_TEXTURE_3D && baseImage->getDepth() <= 0)
+ {
+ return true;
+ }
+
+ if (baseImage->getTarget() == GL_TEXTURE_2D_ARRAY && getLayerCount(0) <= 0)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+gl::Error TextureD3D::ensureRenderTarget()
+{
+ gl::Error error = initializeStorage(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!isBaseImageZeroSize())
+ {
+ ASSERT(mTexStorage);
+ if (!mTexStorage->isRenderTarget())
+ {
+ TextureStorage *newRenderTargetStorage = NULL;
+ error = createCompleteStorage(true, &newRenderTargetStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = mTexStorage->copyToStorage(newRenderTargetStorage);
+ if (error.isError())
+ {
+ SafeDelete(newRenderTargetStorage);
+ return error;
+ }
+
+ error = setCompleteTexStorage(newRenderTargetStorage);
+ if (error.isError())
+ {
+ SafeDelete(newRenderTargetStorage);
+ return error;
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
+{
+ Image *image = getImage(index);
+ bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
+ return (image->isRenderableFormat() && levelsComplete);
+}
+
+gl::Error TextureD3D::commitRegion(const gl::ImageIndex &index, const gl::Box &region)
+{
+ if (mTexStorage)
+ {
+ ASSERT(isValidIndex(index));
+ Image *image = getImage(index);
+ ImageD3D *imageD3D = ImageD3D::makeImageD3D(image);
+ gl::Error error = imageD3D->copyToStorage(mTexStorage, index, region);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ image->markClean();
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+TextureD3D_2D::TextureD3D_2D(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
@@ -292,7 +591,9 @@ bool TextureD3D_2D::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1);
@@ -302,142 +603,209 @@ void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei
redefineImage(level, sizedInternalFormat, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
// Attempt a fast gpu copy of the pixel data to the surface
if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level))
{
- gl::ImageIndex index = gl::ImageIndex::Make2D(level);
-
// Will try to create RT storage if it does not exist
- RenderTarget *destRenderTarget = getRenderTarget(index);
+ RenderTarget *destRenderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
- if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
+ error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
-
- fastUnpacked = true;
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
if (!fastUnpacked)
{
- TextureD3D::setImage(unpack, type, pixels, mImageArray[level]);
+ gl::Error error = TextureD3D::setImage(unpack, type, pixels, index);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1);
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height);
- TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
}
-void TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
bool fastUnpacked = false;
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
{
- RenderTarget *renderTarget = getRenderTarget(index);
- gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
-
- if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget))
+ RenderTarget *renderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &renderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
+ return error;
+ }
- fastUnpacked = true;
+ error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget);
+ if (error.isError())
+ {
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
- if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
+ if (!fastUnpacked)
{
- commitRect(level, xoffset, yoffset, width, height);
+ return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type,
+ unpack, pixels, index);
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
- if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[level]);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, width, height);
+ return error;
}
+
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Box region(xoffset, yoffset, 0, width, height, 1);
+ return commitRegion(index, region);
}
-void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
+ gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(level, sizedInternalFormat, width, height);
- if (!mImageArray[level]->isRenderableFormat())
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[level]->copy(0, 0, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[level]->copy(0, 0, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
mImageArray[level]->markClean();
if (width != 0 && height != 0 && isValidLevel(level))
{
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
-
- mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
+ gl::Error error = mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D && zoffset == 0);
// can only make our texture storage to a render target if level 0 is defined (with a width & height) and
// the current level we're copying to is defined (with appropriate format, width & height)
- bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
- if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[level]->copy(xoffset, yoffset, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[level]->copy(xoffset, yoffset, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidLevel(level))
{
- updateStorageLevel(level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageLevel(level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImage2D(source, sourceRect,
- gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, mTexStorage, level);
+ error = mRenderer->copyImage2D(source, sourceRect,
+ gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+ xoffset, yoffset, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1);
@@ -453,11 +821,20 @@ void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat
mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2D::bindTexImage(egl::Surface *surface)
@@ -489,7 +866,7 @@ void TextureD3D_2D::releaseTexImage()
}
}
-void TextureD3D_2D::generateMipmaps()
+void TextureD3D_2D::initMipmapsImages()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
int levelCount = mipLevels();
@@ -499,42 +876,32 @@ void TextureD3D_2D::generateMipmaps()
std::max(getBaseLevelWidth() >> level, 1),
std::max(getBaseLevelHeight() >> level, 1));
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
- for (int level = 1; level < levelCount; level++)
- {
- mImageArray[level]->markClean();
- }
- }
- else
- {
- for (int level = 1; level < levelCount; level++)
- {
- mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
- }
- }
}
unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index)
{
ASSERT(!index.hasLayer());
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(!index.hasLayer());
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = updateStorageLevel(index.mipIndex);
+ if (error.isError())
{
- return NULL;
+ return error;
}
- updateStorageLevel(index.mipIndex);
- return mTexStorage->getRenderTarget(index);
+ return mTexStorage->getRenderTarget(index, outRT);
}
bool TextureD3D_2D::isValidLevel(int level) const
@@ -586,31 +953,55 @@ bool TextureD3D_2D::isLevelComplete(int level) const
return true;
}
+bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.mipIndex);
+}
+
// Constructs a native texture resource from the texture images
-void TextureD3D_2D::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_2D::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isLevelComplete(0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
@@ -621,26 +1012,35 @@ TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
- return mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
+ // TODO(geofflang): Determine if the texture creation succeeded
+ *outTexStorage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
- SafeDelete(mTexStorage);
- mTexStorage = newCompleteTexStorage;
-
- if (mTexStorage && mTexStorage->isManaged())
+ if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
{
- for (int level = 0; level < mTexStorage->getLevelCount(); level++)
+ for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
{
- mImageArray[level]->setManagedSurface2D(mTexStorage, level);
+ gl::Error error = mImageArray[level]->setManagedSurface2D(newCompleteTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+ SafeDelete(mTexStorage);
+ mTexStorage = newCompleteTexStorage;
+
mDirtyImages = true;
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::updateStorage()
+gl::Error TextureD3D_2D::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -648,54 +1048,34 @@ void TextureD3D_2D::updateStorage()
{
if (mImageArray[level]->isDirty() && isLevelComplete(level))
{
- updateStorageLevel(level);
- }
- }
-}
-
-bool TextureD3D_2D::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTarget2D(newRenderTargetStorage, mTexStorage))
+ gl::Error error = updateStorageLevel(level);
+ if (error.isError())
{
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-TextureStorage *TextureD3D_2D::getBaseLevelStorage()
-{
- return mTexStorage;
+ return gl::Error(GL_NO_ERROR);
}
-const ImageD3D *TextureD3D_2D::getBaseLevelImage() const
-{
- return mImageArray[0];
-}
-
-void TextureD3D_2D::updateStorageLevel(int level)
+gl::Error TextureD3D_2D::updateStorageLevel(int level)
{
ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
ASSERT(isLevelComplete(level));
if (mImageArray[level]->isDirty())
{
- commitRect(level, 0, 0, getWidth(level), getHeight(level));
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
@@ -727,22 +1107,25 @@ void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei wi
}
}
-void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::ImageIndexIterator TextureD3D_2D::imageIterator() const
{
- if (isValidLevel(level))
- {
- ImageD3D *image = mImageArray[level];
- if (image->copyToStorage2D(mTexStorage, level, xoffset, yoffset, width, height))
- {
- image->markClean();
- }
- }
+ return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
+}
+
+gl::ImageIndex TextureD3D_2D::getImageIndex(GLint mip, GLint /*layer*/) const
+{
+ // "layer" does not apply to 2D Textures.
+ return gl::ImageIndex::Make2D(mip);
}
+bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.type == GL_TEXTURE_2D &&
+ index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
+}
-TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+TextureD3D_Cube::TextureD3D_Cube(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int i = 0; i < 6; i++)
{
@@ -802,19 +1185,23 @@ bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const
return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0;
}
-void TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(depth == 1);
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- redefineImage(faceIndex, level, sizedInternalFormat, width, height);
+ redefineImage(index.layerIndex, level, sizedInternalFormat, width, height);
- TextureD3D::setImage(unpack, type, pixels, mImageArray[faceIndex][level]);
+ return TextureD3D::setImage(unpack, type, pixels, index);
}
-void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1);
@@ -823,101 +1210,129 @@ void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum form
redefineImage(faceIndex, level, format, width, height);
- TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[faceIndex][level]);
}
-void TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1 && zoffset == 0);
-
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
-
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
- {
- commitRect(faceIndex, level, xoffset, yoffset, width, height);
- }
+ return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index);
}
-void TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1 && zoffset == 0);
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[index.layerIndex][level]);
+ if (error.isError())
{
- commitRect(faceIndex, level, xoffset, yoffset, width, height);
+ return error;
}
+
+ gl::Box region(xoffset, yoffset, 0, width, height, 1);
+ return commitRegion(index, region);
}
-void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
+ GLsizei width, GLsizei height, gl::Framebuffer *source)
{
int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(faceIndex, level, sizedInternalFormat, width, height);
- if (!mImageArray[faceIndex][level]->isRenderableFormat())
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
mImageArray[faceIndex][level]->markClean();
ASSERT(width == height);
if (width > 0 && isValidFaceLevel(faceIndex, level))
{
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
-
- mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
+ error = mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
- // We can only make our texture storage to a render target if the level we're copying *to* is complete
- // and the base level is cube-complete. The base level must be cube complete (common case) because we cannot
- // rely on the "getBaseLevel*" methods reliably otherwise.
- bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete();
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
+ gl::Error error =mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidFaceLevel(faceIndex, level))
{
- updateStorageFaceLevel(faceIndex, level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageFaceLevel(faceIndex, level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, mTexStorage, target, level);
+ error = mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+ xoffset, yoffset, mTexStorage, target, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(width == height);
ASSERT(depth == 1);
@@ -939,11 +1354,20 @@ void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalform
}
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorageCube(internalformat, renderTarget, width, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -984,7 +1408,7 @@ void TextureD3D_Cube::releaseTexImage()
}
-void TextureD3D_Cube::generateMipmaps()
+void TextureD3D_Cube::initMipmapsImages()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
int levelCount = mipLevels();
@@ -996,74 +1420,76 @@ void TextureD3D_Cube::generateMipmaps()
redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
}
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 1; level < levelCount; level++)
- {
- mImageArray[faceIndex][level]->markClean();
- }
- }
- }
- else
- {
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 1; level < levelCount; level++)
- {
- mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
- }
- }
- }
}
unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index)
{
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(gl::IsCubemapTextureTarget(index.type));
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = updateStorageFaceLevel(index.layerIndex, index.mipIndex);
+ if (error.isError())
{
- return NULL;
+ return error;
}
- updateStorageFaceLevel(index.layerIndex, index.mipIndex);
- return mTexStorage->getRenderTarget(index);
+ return mTexStorage->getRenderTarget(index, outRT);
}
-void TextureD3D_Cube::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_Cube::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isFaceLevelComplete(0, 0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const
{
GLsizei size = getBaseLevelWidth();
@@ -1072,29 +1498,37 @@ TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
- return mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
+ // TODO (geofflang): detect if storage creation succeeded
+ *outTexStorage = mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
- SafeDelete(mTexStorage);
- mTexStorage = newCompleteTexStorage;
-
- if (mTexStorage && mTexStorage->isManaged())
+ if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
{
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- for (int level = 0; level < mTexStorage->getLevelCount(); level++)
+ for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
{
- mImageArray[faceIndex][level]->setManagedSurfaceCube(mTexStorage, faceIndex, level);
+ gl::Error error = mImageArray[faceIndex][level]->setManagedSurfaceCube(newCompleteTexStorage, faceIndex, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+ SafeDelete(mTexStorage);
+ mTexStorage = newCompleteTexStorage;
+
mDirtyImages = true;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::updateStorage()
+gl::Error TextureD3D_Cube::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -1104,46 +1538,16 @@ void TextureD3D_Cube::updateStorage()
{
if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
{
- updateStorageFaceLevel(face, level);
- }
- }
- }
-}
-
-bool TextureD3D_Cube::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTargetCube(newRenderTargetStorage, mTexStorage))
- {
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ gl::Error error = updateStorageFaceLevel(face, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-TextureStorage *TextureD3D_Cube::getBaseLevelStorage()
-{
- return mTexStorage;
-}
-
-const ImageD3D *TextureD3D_Cube::getBaseLevelImage() const
-{
- // Note: if we are not cube-complete, there is no single base level image that can describe all
- // cube faces, so this method is only well-defined for a cube-complete base level.
- return mImageArray[0][0];
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
@@ -1191,15 +1595,29 @@ bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
return true;
}
-void TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
+bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isFaceLevelComplete(index.layerIndex, index.mipIndex);
+}
+
+gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
{
ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
ImageD3D *image = mImageArray[faceIndex][level];
if (image->isDirty())
{
- commitRect(faceIndex, level, 0, 0, image->getWidth(), image->getHeight());
+ GLenum faceTarget = gl::TextureCubeMap::layerIndexToTarget(faceIndex);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level);
+ gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1);
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height)
@@ -1235,20 +1653,25 @@ void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalf
}
}
-void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
{
- if (isValidFaceLevel(faceIndex, level))
- {
- ImageD3D *image = mImageArray[faceIndex][level];
- if (image->copyToStorageCube(mTexStorage, faceIndex, level, xoffset, yoffset, width, height))
- image->markClean();
- }
+ return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount());
}
+gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const
+{
+ // The "layer" of the image index corresponds to the cube face
+ return gl::ImageIndex::MakeCube(gl::TextureCubeMap::layerIndexToTarget(layer), mip);
+}
-TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && gl::IsCubemapTextureTarget(index.type) &&
+ index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
+}
+
+TextureD3D_3D::TextureD3D_3D(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
@@ -1327,7 +1750,9 @@ bool TextureD3D_3D::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
@@ -1336,40 +1761,60 @@ void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei
bool fastUnpacked = false;
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
if (isFastUnpackable(unpack, sizedInternalFormat))
{
// Will try to create RT storage if it does not exist
- gl::ImageIndex index = gl::ImageIndex::Make3D(level);
- RenderTarget *destRenderTarget = getRenderTarget(index);
+ RenderTarget *destRenderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
- if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
+ error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
-
- fastUnpacked = true;
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
if (!fastUnpacked)
{
- TextureD3D::setImage(unpack, type, pixels, mImageArray[level]);
+ gl::Error error = TextureD3D::setImage(unpack, type, pixels, index);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height,GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height, depth);
- TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
}
-void TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
@@ -1380,74 +1825,108 @@ void TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yo
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
if (isFastUnpackable(unpack, getInternalFormat(level)))
{
- RenderTarget *destRenderTarget = getRenderTarget(index);
- gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
-
- if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget))
+ RenderTarget *destRenderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
+ return error;
+ }
- fastUnpacked = true;
+ gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
+ error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget);
+ if (error.isError())
+ {
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
- if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, index))
+ if (!fastUnpacked)
{
- commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
+ return TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type,
+ unpack, pixels, index);
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
- if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth,
+ format, imageSize, unpack, pixels, mImageArray[level]);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
+ return error;
}
+
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+ gl::Box region(xoffset, yoffset, zoffset, width, height, depth);
+ return commitRegion(index, region);
}
-void TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
+ GLsizei width, GLsizei height, gl::Framebuffer *source)
{
UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "Copying 3D textures is unimplemented.");
}
-void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_3D);
- // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
- // the current level we're copying to is defined (with appropriate format, width & height)
- bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
- if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ if (canCreateRenderTargetForImage(index))
{
- mImageArray[level]->copy(xoffset, yoffset, zoffset, x, y, width, height, source);
+ gl::Error error = mImageArray[level]->copy(xoffset, yoffset, zoffset, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidLevel(level))
{
- updateStorageLevel(level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageLevel(level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImage3D(source, sourceRect,
- gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, zoffset, mTexStorage, level);
+ error = mRenderer->copyImage3D(source, sourceRect,
+ gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+ xoffset, yoffset, zoffset, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(target == GL_TEXTURE_3D);
@@ -1464,11 +1943,20 @@ void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat
mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true);
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_3D::bindTexImage(egl::Surface *surface)
@@ -1482,7 +1970,7 @@ void TextureD3D_3D::releaseTexImage()
}
-void TextureD3D_3D::generateMipmaps()
+void TextureD3D_3D::initMipmapsImages()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
int levelCount = mipLevels();
@@ -1493,74 +1981,85 @@ void TextureD3D_3D::generateMipmaps()
std::max(getBaseLevelHeight() >> level, 1),
std::max(getBaseLevelDepth() >> level, 1));
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
-
- for (int level = 1; level < levelCount; level++)
- {
- mImageArray[level]->markClean();
- }
- }
- else
- {
- for (int level = 1; level < levelCount; level++)
- {
- mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
- }
- }
}
unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index)
{
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
{
- return NULL;
+ return error;
}
if (index.hasLayer())
{
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
else
{
- updateStorageLevel(index.mipIndex);
+ error = updateStorageLevel(index.mipIndex);
+ if (error.isError())
+ {
+ return error;
+ }
}
- return mTexStorage->getRenderTarget(index);
+ return mTexStorage->getRenderTarget(index, outRT);
}
-void TextureD3D_3D::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_3D::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isLevelComplete(0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_3D::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
@@ -1572,10 +2071,13 @@ TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth));
- return mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels);
+ // TODO: Verify creation of the storage succeeded
+ *outStorage = mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage;
@@ -1583,9 +2085,11 @@ void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
// We do not support managed 3D storage, as that is D3D9/ES2-only
ASSERT(!mTexStorage->isManaged());
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::updateStorage()
+gl::Error TextureD3D_3D::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -1593,43 +2097,15 @@ void TextureD3D_3D::updateStorage()
{
if (mImageArray[level]->isDirty() && isLevelComplete(level))
{
- updateStorageLevel(level);
- }
- }
-}
-
-bool TextureD3D_3D::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTarget3D(newRenderTargetStorage, mTexStorage))
+ gl::Error error = updateStorageLevel(level);
+ if (error.isError())
{
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-TextureStorage *TextureD3D_3D::getBaseLevelStorage()
-{
- return mTexStorage;
-}
-
-const ImageD3D *TextureD3D_3D::getBaseLevelImage() const
-{
- return mImageArray[0];
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D_3D::isValidLevel(int level) const
@@ -1685,15 +2161,28 @@ bool TextureD3D_3D::isLevelComplete(int level) const
return true;
}
-void TextureD3D_3D::updateStorageLevel(int level)
+bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.mipIndex);
+}
+
+gl::Error TextureD3D_3D::updateStorageLevel(int level)
{
ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
ASSERT(isLevelComplete(level));
if (mImageArray[level]->isDirty())
{
- commitRect(level, 0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
@@ -1727,22 +2216,26 @@ void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei wi
}
}
-void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
+gl::ImageIndexIterator TextureD3D_3D::imageIterator() const
{
- if (isValidLevel(level))
- {
- ImageD3D *image = mImageArray[level];
- if (image->copyToStorage3D(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth))
- {
- image->markClean();
- }
- }
+ return gl::ImageIndexIterator::Make3D(0, mTexStorage->getLevelCount(),
+ gl::ImageIndex::ENTIRE_LEVEL, gl::ImageIndex::ENTIRE_LEVEL);
}
+gl::ImageIndex TextureD3D_3D::getImageIndex(GLint mip, GLint /*layer*/) const
+{
+ // The "layer" here does not apply to 3D images. We use one Image per mip.
+ return gl::ImageIndex::Make3D(mip);
+}
-TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.type == GL_TEXTURE_3D &&
+ index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
+}
+
+TextureD3D_2DArray::TextureD3D_2DArray(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
{
@@ -1791,11 +2284,6 @@ GLsizei TextureD3D_2DArray::getHeight(GLint level) const
return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getHeight() : 0;
}
-GLsizei TextureD3D_2DArray::getLayers(GLint level) const
-{
- return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mLayerCounts[level] : 0;
-}
-
GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const
{
return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getInternalFormat() : GL_NONE;
@@ -1806,7 +2294,9 @@ bool TextureD3D_2DArray::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1820,11 +2310,20 @@ void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLs
for (int i = 0; i < depth; i++)
{
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- TextureD3D::setImage(unpack, type, layerPixels, mImageArray[level][i]);
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i);
+ gl::Error error = TextureD3D::setImage(unpack, type, layerPixels, index);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1837,11 +2336,19 @@ void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum f
for (int i = 0; i < depth; i++)
{
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- TextureD3D::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]);
+ gl::Error error = TextureD3D::setCompressedImage(unpack, imageSize, layerPixels, mImageArray[level][i]);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1854,14 +2361,20 @@ void TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLi
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
- if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, index))
+ gl::Error error = TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type,
+ unpack, layerPixels, index);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, layer, width, height);
+ return error;
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1873,52 +2386,75 @@ void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xo
int layer = zoffset + i;
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, unpack, layerPixels, mImageArray[level][layer]);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+ gl::Box region(xoffset, yoffset, 0, width, height, 1);
+ error = commitRegion(index, region);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, layer, width, height);
+ return error;
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "Copying 2D array textures is unimplemented.");
}
-void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
- // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
- // the current level we're copying to is defined (with appropriate format, width & height)
- bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zoffset);
- if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ if (canCreateRenderTargetForImage(index))
{
- mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidLevel(level))
{
- updateStorageLevel(level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageLevel(level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
- xoffset, yoffset, zoffset, mTexStorage, level);
+ error = mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
+ xoffset, yoffset, zoffset, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1945,11 +2481,20 @@ void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalf
}
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2DArray::bindTexImage(egl::Surface *surface)
@@ -1963,7 +2508,7 @@ void TextureD3D_2DArray::releaseTexImage()
}
-void TextureD3D_2DArray::generateMipmaps()
+void TextureD3D_2DArray::initMipmapsImages()
{
int baseWidth = getBaseLevelWidth();
int baseHeight = getBaseLevelHeight();
@@ -1976,76 +2521,78 @@ void TextureD3D_2DArray::generateMipmaps()
{
redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
-
- for (int level = 1; level < levelCount; level++)
- {
- for (int layer = 0; layer < mLayerCounts[level]; layer++)
- {
- mImageArray[level][layer]->markClean();
- }
- }
- }
- else
- {
- for (int level = 1; level < levelCount; level++)
- {
- for (int layer = 0; layer < mLayerCounts[level]; layer++)
- {
- mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]);
- }
- }
- }
}
unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index)
{
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
{
- return NULL;
+ return error;
}
- updateStorageLevel(index.mipIndex);
- return mTexStorage->getRenderTarget(index);
+ error = updateStorageLevel(index.mipIndex);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return mTexStorage->getRenderTarget(index, outRT);
}
-void TextureD3D_2DArray::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_2DArray::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isLevelComplete(0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_2DArray::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
- GLsizei depth = getLayers(0);
+ GLsizei depth = getLayerCount(0);
GLenum internalFormat = getBaseLevelInternalFormat();
ASSERT(width > 0 && height > 0 && depth > 0);
@@ -2053,10 +2600,13 @@ TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) con
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
- return mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels);
+ // TODO(geofflang): Verify storage creation succeeds
+ *outStorage = mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage;
@@ -2064,9 +2614,11 @@ void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexSto
// We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
ASSERT(!mTexStorage->isManaged());
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::updateStorage()
+gl::Error TextureD3D_2DArray::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -2074,43 +2626,15 @@ void TextureD3D_2DArray::updateStorage()
{
if (isLevelComplete(level))
{
- updateStorageLevel(level);
- }
- }
-}
-
-bool TextureD3D_2DArray::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getLayers(0) > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTarget2DArray(newRenderTargetStorage, mTexStorage))
+ gl::Error error = updateStorageLevel(level);
+ if (error.isError())
{
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-const ImageD3D *TextureD3D_2DArray::getBaseLevelImage() const
-{
- return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL);
-}
-
-TextureStorage *TextureD3D_2DArray::getBaseLevelStorage()
-{
- return mTexStorage;
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D_2DArray::isValidLevel(int level) const
@@ -2129,7 +2653,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
- GLsizei layers = getLayers(0);
+ GLsizei layers = getLayerCount(0);
if (width <= 0 || height <= 0 || layers <= 0)
{
@@ -2156,7 +2680,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
return false;
}
- if (getLayers(level) != layers)
+ if (getLayerCount(level) != layers)
{
return false;
}
@@ -2164,7 +2688,12 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
return true;
}
-void TextureD3D_2DArray::updateStorageLevel(int level)
+bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.mipIndex);
+}
+
+gl::Error TextureD3D_2DArray::updateStorageLevel(int level)
{
ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts));
ASSERT(isLevelComplete(level));
@@ -2174,9 +2703,17 @@ void TextureD3D_2DArray::updateStorageLevel(int level)
ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL);
if (mImageArray[level][layer]->isDirty())
{
- commitRect(level, 0, 0, layer, getWidth(level), getHeight(level));
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2DArray::deleteImages()
@@ -2198,7 +2735,7 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz
// If there currently is a corresponding storage texture image, it has these parameters
const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
- const int storageDepth = getLayers(0);
+ const int storageDepth = getLayerCount(0);
const GLenum storageFormat = getBaseLevelInternalFormat();
for (int layer = 0; layer < mLayerCounts[level]; layer++)
@@ -2245,16 +2782,32 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz
}
}
-void TextureD3D_2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height)
+gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts);
+}
+
+gl::ImageIndex TextureD3D_2DArray::getImageIndex(GLint mip, GLint layer) const
+{
+ return gl::ImageIndex::Make2DArray(mip, layer);
+}
+
+bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const
{
- if (isValidLevel(level) && layerTarget < getLayers(level))
+ // Check for having a storage and the right type of index
+ if (!mTexStorage || index.type != GL_TEXTURE_2D_ARRAY)
{
- ImageD3D *image = mImageArray[level][layerTarget];
- if (image->copyToStorage2DArray(mTexStorage, level, xoffset, yoffset, layerTarget, width, height))
- {
- image->markClean();
- }
+ return false;
}
+
+ // Check the mip index
+ if (index.mipIndex < 0 || index.mipIndex >= mTexStorage->getLevelCount())
+ {
+ return false;
+ }
+
+ // Check the layer index
+ return (!index.hasLayer() || (index.layerIndex >= 0 && index.layerIndex < mLayerCounts[index.mipIndex]));
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h
index 41c73180de..083a6335b9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -11,7 +11,7 @@
#include "libGLESv2/renderer/TextureImpl.h"
#include "libGLESv2/angletypes.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
namespace gl
{
@@ -23,19 +23,19 @@ namespace rx
class Image;
class ImageD3D;
-class Renderer;
+class RendererD3D;
class RenderTarget;
class TextureStorage;
class TextureD3D : public TextureImpl
{
public:
- TextureD3D(Renderer *renderer);
+ TextureD3D(RendererD3D *renderer);
virtual ~TextureD3D();
static TextureD3D *makeTextureD3D(TextureImpl *texture);
- virtual TextureStorage *getNativeTexture();
+ TextureStorage *getNativeTexture();
virtual void setUsage(GLenum usage) { mUsage = usage; }
bool hasDirtyImages() const { return mDirtyImages; }
@@ -48,45 +48,68 @@ class TextureD3D : public TextureImpl
bool isImmutable() const { return mImmutable; }
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0;
+ // Returns an iterator over all "Images" for this particular Texture.
+ virtual gl::ImageIndexIterator imageIterator() const = 0;
+
+ // Returns an ImageIndex for a particular "Image". 3D Textures do not have images for
+ // slices of their depth texures, so 3D textures ignore the layer parameter.
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const = 0;
+
+ virtual gl::Error generateMipmaps();
+ TextureStorage *getStorage();
+ Image *getBaseLevelImage() const;
+
protected:
- void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image);
- bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index);
- void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
- bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const void *pixels, Image *image);
+ gl::Error setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index);
+ gl::Error subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index);
+ gl::Error setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image);
+ gl::Error subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image);
bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat);
- bool fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
- GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
+ gl::Error fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
+ GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
int mipLevels() const;
+ virtual void initMipmapsImages() = 0;
+ bool isBaseImageZeroSize() const;
+ virtual bool isImageComplete(const gl::ImageIndex &index) const = 0;
- Renderer *mRenderer;
+ bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const;
+ virtual gl::Error ensureRenderTarget();
+
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const = 0;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage) = 0;
+ gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region);
+
+ RendererD3D *mRenderer;
GLenum mUsage;
bool mDirtyImages;
bool mImmutable;
+ TextureStorage *mTexStorage;
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D);
- virtual void initializeStorage(bool renderTarget) = 0;
+ virtual gl::Error initializeStorage(bool renderTarget) = 0;
- virtual void updateStorage() = 0;
- virtual TextureStorage *getBaseLevelStorage() = 0;
- virtual const ImageD3D *getBaseLevelImage() const = 0;
+ virtual gl::Error updateStorage() = 0;
+
+ bool shouldUseSetData(const Image *image) const;
};
class TextureD3D_2D : public TextureD3D
{
public:
- TextureD3D_2D(Renderer *renderer);
+ TextureD3D_2D(RendererD3D *renderer);
virtual ~TextureD3D_2D();
virtual Image *getImage(int level, int layer) const;
@@ -99,50 +122,49 @@ class TextureD3D_2D : public TextureD3D
GLenum getActualFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
- void updateStorageLevel(int level);
+ gl::Error updateStorageLevel(int level);
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
- void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- TextureStorage *mTexStorage;
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
class TextureD3D_Cube : public TextureD3D
{
public:
- TextureD3D_Cube(Renderer *renderer);
+ TextureD3D_Cube(RendererD3D *renderer);
virtual ~TextureD3D_Cube();
virtual Image *getImage(int level, int layer) const;
@@ -156,51 +178,49 @@ class TextureD3D_Cube : public TextureD3D
GLenum getInternalFormat(GLint level, GLint layer) const;
bool isDepth(GLint level, GLint layer) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidFaceLevel(int faceIndex, int level) const;
bool isFaceLevelComplete(int faceIndex, int level) const;
bool isCubeComplete() const;
- void updateStorageFaceLevel(int faceIndex, int level);
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
+ gl::Error updateStorageFaceLevel(int faceIndex, int level);
void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
- void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
- TextureStorage *mTexStorage;
};
class TextureD3D_3D : public TextureD3D
{
public:
- TextureD3D_3D(Renderer *renderer);
+ TextureD3D_3D(RendererD3D *renderer);
virtual ~TextureD3D_3D();
virtual Image *getImage(int level, int layer) const;
@@ -213,50 +233,48 @@ class TextureD3D_3D : public TextureD3D
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
- void updateStorageLevel(int level);
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
+ gl::Error updateStorageLevel(int level);
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
- void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
- TextureStorage *mTexStorage;
};
class TextureD3D_2DArray : public TextureD3D
{
public:
- TextureD3D_2DArray(Renderer *renderer);
+ TextureD3D_2DArray(RendererD3D *renderer);
virtual ~TextureD3D_2DArray();
virtual Image *getImage(int level, int layer) const;
@@ -265,45 +283,44 @@ class TextureD3D_2DArray : public TextureD3D
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
- GLsizei getLayers(GLint level) const;
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
- void updateStorageLevel(int level);
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
+ gl::Error updateStorageLevel(int level);
void deleteImages();
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
- void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height);
// Storing images as an array of single depth textures since D3D11 treats each array level of a
// Texture2D object as a separate subresource. Each layer would have to be looped over
@@ -311,8 +328,6 @@ class TextureD3D_2DArray : public TextureD3D
// sense for the Image class to not have to worry about layer subresource as well as mip subresources.
GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
- TextureStorage *mTexStorage;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp
index dedd266c09..320b74b8ed 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp
@@ -8,6 +8,7 @@
#include "libGLESv2/renderer/d3d/TextureStorage.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Texture.h"
@@ -18,17 +19,14 @@
namespace rx
{
-unsigned int TextureStorage::mCurrentTextureSerial = 1;
-
TextureStorage::TextureStorage()
- : mTextureSerial(issueTextureSerial()),
- mFirstRenderTargetSerial(0),
+ : mFirstRenderTargetSerial(0),
mRenderTargetSerialsLayerStride(0)
{}
void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride)
{
- mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(rtSerialsToReserve);
+ mFirstRenderTargetSerial = RenderTarget::issueSerials(rtSerialsToReserve);
mRenderTargetSerialsLayerStride = rtSerialsLayerStride;
}
@@ -38,14 +36,4 @@ unsigned int TextureStorage::getRenderTargetSerial(const gl::ImageIndex &index)
return mFirstRenderTargetSerial + static_cast<unsigned int>(index.mipIndex) + layerOffset;
}
-unsigned int TextureStorage::getTextureSerial() const
-{
- return mTextureSerial;
-}
-
-unsigned int TextureStorage::issueTextureSerial()
-{
- return mCurrentTextureSerial++;
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h
index 9cc2c2977b..da92be3c74 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h
@@ -9,20 +9,26 @@
#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
#define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+#include "libGLESv2/Error.h"
+
#include "common/debug.h"
+#include "libGLESv2/Error.h"
#include <GLES2/gl2.h>
+#include <cstdint>
namespace gl
{
struct ImageIndex;
+struct Box;
+struct PixelUnpackState;
}
namespace rx
{
-class Renderer;
class SwapChain;
class RenderTarget;
+class Image;
class TextureStorage
{
@@ -35,8 +41,12 @@ class TextureStorage
virtual bool isManaged() const = 0;
virtual int getLevelCount() const = 0;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
- virtual void generateMipmaps() = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
+
+ virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0;
+ virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData) = 0;
unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const;
unsigned int getTextureSerial() const;
@@ -47,11 +57,6 @@ class TextureStorage
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage);
- const unsigned int mTextureSerial;
- static unsigned int issueTextureSerial();
-
- static unsigned int mCurrentTextureSerial;
-
unsigned int mFirstRenderTargetSerial;
unsigned int mRenderTargetSerialsLayerStride;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
index 4f85eb94fa..73f0c79e19 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
@@ -9,7 +9,7 @@
#include "libGLESv2/renderer/d3d/VertexBuffer.h"
#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/VertexAttribute.h"
#include "common/mathutil.h"
@@ -38,7 +38,7 @@ unsigned int VertexBuffer::getSerial() const
return mSerial;
}
-VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
+VertexBufferInterface::VertexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer)
{
mDynamic = dynamic;
mWritePosition = 0;
@@ -127,7 +127,7 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute
mWritePosition += spaceRequired;
// Align to 16-byte boundary
- mWritePosition = rx::roundUp(mWritePosition, 16u);
+ mWritePosition = roundUp(mWritePosition, 16u);
return gl::Error(GL_NO_ERROR);
}
@@ -153,7 +153,7 @@ gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &a
mReservedSpace += requiredSpace;
// Align to 16-byte boundary
- mReservedSpace = rx::roundUp(mReservedSpace, 16u);
+ mReservedSpace = roundUp(mReservedSpace, 16u);
return gl::Error(GL_NO_ERROR);
}
@@ -197,7 +197,7 @@ bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &att
return !requiresConversion && isAligned;
}
-StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
+StreamingVertexBufferInterface::StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
{
setBufferSize(initialSize);
}
@@ -231,7 +231,7 @@ gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size)
return gl::Error(GL_NO_ERROR);
}
-StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
+StaticVertexBufferInterface::StaticVertexBufferInterface(RendererD3D *renderer) : VertexBufferInterface(renderer, false)
{
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h
index fa747d9cb4..4b40818f8e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h
@@ -26,7 +26,7 @@ struct VertexAttribCurrentValueData;
namespace rx
{
-class Renderer;
+class RendererD3D;
class VertexBuffer
{
@@ -60,7 +60,7 @@ class VertexBuffer
class VertexBufferInterface
{
public:
- VertexBufferInterface(rx::Renderer *renderer, bool dynamic);
+ VertexBufferInterface(RendererD3D *renderer, bool dynamic);
virtual ~VertexBufferInterface();
gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
@@ -90,7 +90,7 @@ class VertexBufferInterface
private:
DISALLOW_COPY_AND_ASSIGN(VertexBufferInterface);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
VertexBuffer* mVertexBuffer;
@@ -102,7 +102,7 @@ class VertexBufferInterface
class StreamingVertexBufferInterface : public VertexBufferInterface
{
public:
- StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize);
+ StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize);
~StreamingVertexBufferInterface();
protected:
@@ -112,7 +112,7 @@ class StreamingVertexBufferInterface : public VertexBufferInterface
class StaticVertexBufferInterface : public VertexBufferInterface
{
public:
- explicit StaticVertexBufferInterface(rx::Renderer *renderer);
+ explicit StaticVertexBufferInterface(RendererD3D *renderer);
~StaticVertexBufferInterface();
gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
index 7034b78eab..8d3df31c8b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
@@ -14,6 +14,7 @@
#include "libGLESv2/Buffer.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
+#include "libGLESv2/State.h"
namespace
{
@@ -51,7 +52,7 @@ static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int ve
return vertexDrawCount;
}
-VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
+VertexDataManager::VertexDataManager(RendererD3D *renderer) : mRenderer(renderer)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
@@ -82,8 +83,8 @@ VertexDataManager::~VertexDataManager()
}
}
-gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
- gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
+gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count,
+ TranslatedAttribute *translated, GLsizei instances)
{
if (!mStreamingBuffer)
{
@@ -93,20 +94,22 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
// Invalidate static buffers that don't contain matching attributes
for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
{
- translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ translated[attributeIndex].active = (state.getCurrentProgramBinary()->getSemanticIndex(attributeIndex) != -1);
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(attributeIndex);
- if (translated[attributeIndex].active && attribs[attributeIndex].enabled)
+ if (translated[attributeIndex].active && curAttrib.enabled)
{
- invalidateMatchingStaticData(attribs[attributeIndex], currentValues[attributeIndex]);
+ invalidateMatchingStaticData(curAttrib, state.getVertexAttribCurrentValue(attributeIndex));
}
}
// Reserve the required space in the buffers
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
- if (translated[i].active && attribs[i].enabled)
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
+ if (translated[i].active && curAttrib.enabled)
{
- gl::Error error = reserveSpaceForAttrib(attribs[i], currentValues[i], count, instances);
+ gl::Error error = reserveSpaceForAttrib(curAttrib, state.getVertexAttribCurrentValue(i), count, instances);
if (error.isError())
{
return error;
@@ -117,12 +120,14 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
// Perform the vertex data translations
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
if (translated[i].active)
{
- if (attribs[i].enabled)
+ if (curAttrib.enabled)
{
- gl::Error error = storeAttribute(attribs[i], currentValues[i], &translated[i],
- start, count, instances);
+ gl::Error error = storeAttribute(curAttrib, state.getVertexAttribCurrentValue(i),
+ &translated[i], start, count, instances);
+
if (error.isError())
{
return error;
@@ -135,7 +140,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
}
- gl::Error error = storeCurrentValue(attribs[i], currentValues[i], &translated[i],
+ gl::Error error = storeCurrentValue(curAttrib, state.getVertexAttribCurrentValue(i), &translated[i],
&mCurrentValue[i], &mCurrentValueOffsets[i],
mCurrentValueBuffer[i]);
if (error.isError())
@@ -148,14 +153,15 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
- if (translated[i].active && attribs[i].enabled)
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
+ if (translated[i].active && curAttrib.enabled)
{
- gl::Buffer *buffer = attribs[i].buffer.get();
+ gl::Buffer *buffer = curAttrib.buffer.get();
if (buffer)
{
BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
- bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(attribs[i]));
+ bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(curAttrib));
}
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h
index 7728722246..64ef653221 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h
@@ -16,8 +16,9 @@
namespace gl
{
-struct VertexAttribute;
class ProgramBinary;
+class State;
+struct VertexAttribute;
struct VertexAttribCurrentValueData;
}
@@ -26,7 +27,7 @@ namespace rx
class BufferD3D;
class StreamingVertexBufferInterface;
class VertexBuffer;
-class Renderer;
+class RendererD3D;
struct TranslatedAttribute
{
@@ -49,11 +50,11 @@ struct TranslatedAttribute
class VertexDataManager
{
public:
- VertexDataManager(rx::Renderer *renderer);
+ VertexDataManager(RendererD3D *renderer);
virtual ~VertexDataManager();
- gl::Error prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
- gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
+ gl::Error prepareVertexData(const gl::State &state, GLint start, GLsizei count,
+ TranslatedAttribute *outAttribs, GLsizei instances);
private:
DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
@@ -80,7 +81,7 @@ class VertexDataManager
size_t *cachedOffset,
StreamingVertexBufferInterface *buffer);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
StreamingVertexBufferInterface *mStreamingBuffer;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
index d43e65ea78..06aea9befe 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
@@ -172,7 +172,7 @@ static void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &source
*outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
-Blit11::Blit11(rx::Renderer11 *renderer)
+Blit11::Blit11(Renderer11 *renderer)
: mRenderer(renderer), mBlitShaderMap(compareBlitParameters), mSwizzleShaderMap(compareSwizzleParameters),
mVertexBuffer(NULL), mPointSampler(NULL), mLinearSampler(NULL), mScissorEnabledRasterizerState(NULL),
mScissorDisabledRasterizerState(NULL), mDepthStencilState(NULL),
@@ -209,7 +209,7 @@ Blit11::Blit11(rx::Renderer11 *renderer)
pointSamplerDesc.BorderColor[2] = 0.0f;
pointSamplerDesc.BorderColor[3] = 0.0f;
pointSamplerDesc.MinLOD = 0.0f;
- pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f;
+ pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
ASSERT(SUCCEEDED(result));
@@ -228,7 +228,7 @@ Blit11::Blit11(rx::Renderer11 *renderer)
linearSamplerDesc.BorderColor[2] = 0.0f;
linearSamplerDesc.BorderColor[3] = 0.0f;
linearSamplerDesc.MinLOD = 0.0f;
- linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f;
+ linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
ASSERT(SUCCEEDED(result));
@@ -468,8 +468,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
- ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
// Apply render target
mRenderer->setOneTimeRenderTarget(dest);
@@ -485,7 +484,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &source);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler);
@@ -494,7 +493,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
@@ -507,9 +506,9 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
return gl::Error(GL_NO_ERROR);
}
-bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, GLenum destFormat, GLenum filter)
+gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, GLenum destFormat, GLenum filter)
{
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -531,7 +530,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
if (i == mBlitShaderMap.end())
{
UNREACHABLE();
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Could not find appropriate shader for internal texture blit.");
}
const Shader& shader = i->second;
@@ -541,8 +540,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
- ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result);
}
UINT stride = 0;
@@ -587,8 +585,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
- ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
// Apply render target
mRenderer->setOneTimeRenderTarget(dest);
@@ -604,7 +601,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &source);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
ID3D11SamplerState *sampler = NULL;
@@ -612,7 +609,10 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
{
case GL_NEAREST: sampler = mPointSampler; break;
case GL_LINEAR: sampler = mLinearSampler; break;
- default: UNREACHABLE(); return false;
+
+ default:
+ UNREACHABLE();
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal error, unknown blit filter mode.");
}
deviceContext->PSSetSamplers(0, 1, &sampler);
@@ -620,7 +620,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
@@ -630,21 +630,21 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
mRenderer->markAllStateDirty();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor)
+gl::Error Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor)
{
return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize,
dest, destSubresource, destArea, destSize,
scissor, true);
}
-bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor)
+gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor)
{
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -654,8 +654,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
- ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result);
}
UINT stride = 0;
@@ -700,8 +699,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
deviceContext->GSSetShader(NULL, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
- ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
// Apply render target
deviceContext->OMSetRenderTargets(0, NULL, dest);
@@ -717,7 +715,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &source);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler);
@@ -726,7 +724,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
@@ -736,21 +734,21 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
mRenderer->markAllStateDirty();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor)
+gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor)
{
return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize,
dest, destSubresource, destArea, destSize,
scissor, false);
}
-bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, bool stencilOnly)
+gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, bool stencilOnly)
{
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -764,7 +762,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso
{
SafeRelease(sourceStaging);
SafeRelease(destStaging);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging textures for depth stencil blit.");
}
DXGI_FORMAT format = GetTextureFormat(source);
@@ -785,23 +783,23 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso
dxgiFormatInfo.depthBits % 8 == 0);
}
- D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping;
- deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping);
- deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping);
+ D3D11_MAPPED_SUBRESOURCE sourceMapping;
+ HRESULT result = deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping);
+ if (FAILED(result))
+ {
+ SafeRelease(sourceStaging);
+ SafeRelease(destStaging);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal source staging texture for depth stencil blit, HRESULT: 0x%X.", result);
+ }
- if (!sourceMapping.pData || !destMapping.pData)
+ D3D11_MAPPED_SUBRESOURCE destMapping;
+ result = deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping);
+ if (FAILED(result))
{
- if (!sourceMapping.pData)
- {
- deviceContext->Unmap(sourceStaging, 0);
- }
- if (!destMapping.pData)
- {
- deviceContext->Unmap(destStaging, 0);
- }
+ deviceContext->Unmap(sourceStaging, 0);
SafeRelease(sourceStaging);
SafeRelease(destStaging);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal destination staging texture for depth stencil blit, HRESULT: 0x%X.", result);
}
gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
@@ -880,7 +878,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso
SafeRelease(sourceStaging);
SafeRelease(destStaging);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
bool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b)
@@ -1001,12 +999,12 @@ void Blit11::buildShaderMap()
add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" ));
add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" ));
add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" ));
- add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" ));
add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" ));
- add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
+ add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" ));
add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" ));
+ add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" ));
add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" ));
add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" ));
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
index d6a0b795f4..821fa9d0cc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
@@ -19,12 +19,6 @@ namespace rx
{
class Renderer11;
-enum Filter
-{
- Point,
- Linear,
-};
-
class Blit11
{
public:
@@ -34,24 +28,24 @@ class Blit11
gl::Error swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size,
GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
- bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, GLenum destFormat, GLenum filter);
-
- bool copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor);
+ gl::Error copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, GLenum destFormat, GLenum filter);
- bool copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor);
-
- bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor);
+ gl::Error copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor);
+
+ gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor);
+
private:
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
struct BlitParameters
{
@@ -60,9 +54,9 @@ class Blit11
bool m3DBlit;
};
- bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, bool stencilOnly);
+ gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, bool stencilOnly);
static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
index ecd4d4672b..5aab37938f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
@@ -86,7 +86,7 @@ class Buffer11::BufferStorage11
virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
size_t size, size_t destOffset) = 0;
- virtual bool resize(size_t size, bool preserveData) = 0;
+ virtual gl::Error resize(size_t size, bool preserveData) = 0;
virtual void *map(size_t offset, size_t length, GLbitfield access) = 0;
virtual void unmap() = 0;
@@ -112,17 +112,17 @@ class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11
virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
size_t size, size_t destOffset);
- virtual bool resize(size_t size, bool preserveData);
+ virtual gl::Error resize(size_t size, bool preserveData);
virtual void *map(size_t offset, size_t length, GLbitfield access);
virtual void unmap();
- bool setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset);
+ gl::Error setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset);
private:
ID3D11Buffer *mNativeBuffer;
- static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize);
+ static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize);
};
// Pack storage represents internal storage for pack buffers. We implement pack buffers
@@ -135,7 +135,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
size_t size, size_t destOffset);
- virtual bool resize(size_t size, bool preserveData);
+ virtual gl::Error resize(size_t size, bool preserveData);
virtual void *map(size_t offset, size_t length, GLbitfield access);
virtual void unmap();
@@ -144,7 +144,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
private:
- void flushQueuedPackCommand();
+ gl::Error flushQueuedPackCommand();
ID3D11Texture2D *mStagingTexture;
DXGI_FORMAT mTextureFormat;
@@ -195,14 +195,14 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
return error;
}
-void *Buffer11::getData()
+gl::Error Buffer11::getData(const uint8_t **outData)
{
NativeBuffer11 *stagingBuffer = getStagingBuffer();
if (!stagingBuffer)
{
// Out-of-memory
- return NULL;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get internal staging buffer.");
}
if (stagingBuffer->getDataRevision() > mResolvedDataRevision)
@@ -211,7 +211,7 @@ void *Buffer11::getData()
{
if (!mResolvedData.resize(stagingBuffer->getSize()))
{
- return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer.");
}
}
@@ -221,7 +221,7 @@ void *Buffer11::getData()
HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource);
if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result);
}
memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize());
@@ -238,13 +238,14 @@ void *Buffer11::getData()
{
if (!mResolvedData.resize(mSize))
{
- return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer.");
}
}
ASSERT(mResolvedData.size() >= mSize);
- return mResolvedData.data();
+ *outData = mResolvedData.data();
+ return gl::Error(GL_NO_ERROR);
}
gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
@@ -265,15 +266,17 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
if (stagingBuffer->getSize() < requiredSize)
{
bool preserveData = (offset > 0);
- if (!stagingBuffer->resize(requiredSize, preserveData))
+ gl::Error error = stagingBuffer->resize(requiredSize, preserveData);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer.");
+ return error;
}
}
- if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset))
+ gl::Error error = stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer.");
+ return error;
}
stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
@@ -411,7 +414,7 @@ void Buffer11::markBufferUsage()
}
}
-Renderer* Buffer11::getRenderer()
+RendererD3D* Buffer11::getRenderer()
{
return mRenderer;
}
@@ -527,7 +530,7 @@ Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage)
// resize buffer
if (directBuffer->getSize() < mSize)
{
- if (!directBuffer->resize(mSize, true))
+ if (directBuffer->resize(mSize, true).isError())
{
// Out of memory error
return NULL;
@@ -667,6 +670,9 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s
// Offset bounds are validated at the API layer
ASSERT(sourceOffset + size <= destOffset + mBufferSize);
memcpy(destPointer, sourcePointer, size);
+
+ context->Unmap(mNativeBuffer, 0);
+ source->unmap();
}
else
{
@@ -689,7 +695,7 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s
return createBuffer;
}
-bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
+gl::Error Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
{
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -702,7 +708,7 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", result);
}
if (mNativeBuffer && preserveData)
@@ -727,10 +733,10 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
mBufferSize = bufferDesc.ByteWidth;
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
+void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer,
BufferUsage usage, unsigned int bufferSize)
{
bufferDesc->ByteWidth = bufferSize;
@@ -748,7 +754,7 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren
case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
- if (!static_cast<Renderer11 *>(renderer)->isLevel9())
+ if (!renderer->isLevel9())
bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
bufferDesc->CPUAccessFlags = 0;
break;
@@ -797,7 +803,7 @@ void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield acc
return static_cast<GLubyte*>(mappedResource.pData) + offset;
}
-bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset)
+gl::Error Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset)
{
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -805,7 +811,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s
HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource);
if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result);
}
uint8_t *offsetBufferPointer = reinterpret_cast<uint8_t *>(mappedResource.pData) + offset;
@@ -813,7 +819,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s
context->Unmap(mNativeBuffer, 0);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
void Buffer11::NativeBuffer11::unmap()
@@ -847,18 +853,18 @@ bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t so
return false;
}
-bool Buffer11::PackStorage11::resize(size_t size, bool preserveData)
+gl::Error Buffer11::PackStorage11::resize(size_t size, bool preserveData)
{
if (size != mBufferSize)
{
if (!mMemoryBuffer.resize(size))
{
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer storage.");
}
mBufferSize = size;
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield access)
@@ -869,7 +875,12 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce
// and if D3D packs the staging texture memory identically to how we would fill
// the pack buffer according to the current pack state.
- flushQueuedPackCommand();
+ gl::Error error = flushQueuedPackCommand();
+ if (error.isError())
+ {
+ return NULL;
+ }
+
mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
return mMemoryBuffer.data() + offset;
@@ -882,7 +893,12 @@ void Buffer11::PackStorage11::unmap()
gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
{
- flushQueuedPackCommand();
+ gl::Error error = flushQueuedPackCommand();
+ if (error.isError())
+ {
+ return error;
+ }
+
mQueuedPackCommand = new PackPixelsParams(params);
D3D11_TEXTURE2D_DESC textureDesc;
@@ -947,15 +963,21 @@ gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT s
return gl::Error(GL_NO_ERROR);
}
-void Buffer11::PackStorage11::flushQueuedPackCommand()
+gl::Error Buffer11::PackStorage11::flushQueuedPackCommand()
{
ASSERT(mMemoryBuffer.size() > 0);
if (mQueuedPackCommand)
{
- mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
+ gl::Error error = mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
SafeDelete(mQueuedPackCommand);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
index 5f24fb4e2d..1c06bbf88a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
@@ -47,7 +47,7 @@ typedef size_t DataRevision;
class Buffer11 : public BufferD3D
{
public:
- Buffer11(rx::Renderer11 *renderer);
+ Buffer11(Renderer11 *renderer);
virtual ~Buffer11();
static Buffer11 *makeBuffer11(BufferImpl *buffer);
@@ -60,11 +60,11 @@ class Buffer11 : public BufferD3D
// BufferD3D implementation
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const;
- virtual Renderer* getRenderer();
+ RendererD3D *getRenderer() override;
// BufferImpl implementation
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
- virtual void *getData();
+ gl::Error getData(const uint8_t **outData) override;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
@@ -78,7 +78,7 @@ class Buffer11 : public BufferD3D
class NativeBuffer11;
class PackStorage11;
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
size_t mSize;
BufferStorage11 *mMappedStorage;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
index 765d34fd3f..7185a05506 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
@@ -104,7 +104,7 @@ Clear11::Clear11(Renderer11 *renderer)
rsDesc.DepthBias = 0;
rsDesc.DepthBiasClamp = 0.0f;
rsDesc.SlopeScaledDepthBias = 0.0f;
- rsDesc.DepthClipEnable = mRenderer->isLevel9();
+ rsDesc.DepthClipEnable = renderer->isLevel9();
rsDesc.ScissorEnable = FALSE;
rsDesc.MultisampleEnable = FALSE;
rsDesc.AntialiasedLineEnable = FALSE;
@@ -119,7 +119,6 @@ Clear11::Clear11(Renderer11 *renderer)
memset(&mIntClearShader, 0, sizeof(ClearShader));
return;
}
-
mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint );
mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
}
@@ -154,7 +153,7 @@ Clear11::~Clear11()
SafeRelease(mRasterizerState);
}
-gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
{
// First determine if a scissored clear is needed, this will always require drawing a quad.
//
@@ -217,10 +216,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::
gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment);
if (attachment)
{
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
- if (!renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
+ return error;
}
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
@@ -290,10 +290,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::
gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
if (attachment)
{
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
- if (!renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
+ return error;
}
const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
index be8e187c40..a7e8fea56a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
@@ -32,7 +32,7 @@ class Clear11
~Clear11();
// Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied.
- gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+ gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer);
private:
Renderer11 *mRenderer;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
index a841b52862..f44d934056 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
@@ -4,67 +4,229 @@
// found in the LICENSE file.
//
-// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl.
+// Fence11.cpp: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl.
#include "libGLESv2/renderer/d3d/d3d11/Fence11.h"
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/main.h"
+#include "common/utilities.h"
+
namespace rx
{
-Fence11::Fence11(rx::Renderer11 *renderer)
+//
+// Template helpers for set and test operations.
+//
+
+template<class FenceClass>
+gl::Error FenceSetHelper(FenceClass *fence)
{
- mRenderer = renderer;
- mQuery = NULL;
+ if (!fence->mQuery)
+ {
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_EVENT;
+ queryDesc.MiscFlags = 0;
+
+ HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result);
+ }
+ }
+
+ fence->mRenderer->getDeviceContext()->End(fence->mQuery);
+ return gl::Error(GL_NO_ERROR);
}
-Fence11::~Fence11()
+template <class FenceClass>
+gl::Error FenceTestHelper(FenceClass *fence, bool flushCommandBuffer, GLboolean *outFinished)
+{
+ ASSERT(fence->mQuery);
+
+ UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);
+ HRESULT result = fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, NULL, 0, getDataFlags);
+
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result);
+ }
+ else if (fence->mRenderer->isDeviceLost())
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query.");
+ }
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE);
+ return gl::Error(GL_NO_ERROR);
+}
+
+//
+// FenceNV11
+//
+
+FenceNV11::FenceNV11(Renderer11 *renderer)
+ : FenceNVImpl(),
+ mRenderer(renderer),
+ mQuery(NULL)
+{
+}
+
+FenceNV11::~FenceNV11()
{
SafeRelease(mQuery);
}
-bool Fence11::isSet() const
+gl::Error FenceNV11::set()
{
- return mQuery != NULL;
+ return FenceSetHelper(this);
}
-void Fence11::set()
+gl::Error FenceNV11::test(bool flushCommandBuffer, GLboolean *outFinished)
{
- if (!mQuery)
- {
- D3D11_QUERY_DESC queryDesc;
- queryDesc.Query = D3D11_QUERY_EVENT;
- queryDesc.MiscFlags = 0;
+ return FenceTestHelper(this, flushCommandBuffer, outFinished);
+}
+
+gl::Error FenceNV11::finishFence(GLboolean *outFinished)
+{
+ ASSERT(outFinished);
- if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery)))
+ while (*outFinished != GL_TRUE)
+ {
+ gl::Error error = test(true, outFinished);
+ if (error.isError())
{
- return gl::error(GL_OUT_OF_MEMORY);
+ return error;
}
+
+ Sleep(0);
}
- mRenderer->getDeviceContext()->End(mQuery);
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence11::test(bool flushCommandBuffer)
+//
+// FenceSync11
+//
+
+// Important note on accurate timers in Windows:
+//
+// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
+// as timeGetTime on laptops and "jumping" during certain hardware events.
+//
+// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
+// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
+//
+// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
+// from buggy implementations.
+
+FenceSync11::FenceSync11(Renderer11 *renderer)
+ : FenceSyncImpl(),
+ mRenderer(renderer),
+ mQuery(NULL)
{
- ASSERT(mQuery);
+ LARGE_INTEGER counterFreqency = { 0 };
+ BOOL success = QueryPerformanceFrequency(&counterFreqency);
+ UNUSED_ASSERTION_VARIABLE(success);
+ ASSERT(success);
- UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);
- HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, getDataFlags);
+ mCounterFrequency = counterFreqency.QuadPart;
+}
- if (mRenderer->isDeviceLost())
+FenceSync11::~FenceSync11()
+{
+ SafeRelease(mQuery);
+}
+
+gl::Error FenceSync11::set()
+{
+ return FenceSetHelper(this);
+}
+
+gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
+{
+ ASSERT(outResult);
+
+ bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
+
+ GLboolean result = GL_FALSE;
+ gl::Error error = FenceTestHelper(this, flushCommandBuffer, &result);
+ if (error.isError())
{
- return gl::error(GL_OUT_OF_MEMORY, true);
+ *outResult = GL_WAIT_FAILED;
+ return error;
}
- ASSERT(result == S_OK || result == S_FALSE);
- return (result == S_OK);
+ if (result == GL_TRUE)
+ {
+ *outResult = GL_ALREADY_SIGNALED;
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ if (timeout == 0)
+ {
+ *outResult = GL_TIMEOUT_EXPIRED;
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ LARGE_INTEGER currentCounter = { 0 };
+ BOOL success = QueryPerformanceCounter(&currentCounter);
+ UNUSED_ASSERTION_VARIABLE(success);
+ ASSERT(success);
+
+ LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
+ LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
+
+ while (currentCounter.QuadPart < endCounter && !result)
+ {
+ Sleep(0);
+ BOOL success = QueryPerformanceCounter(&currentCounter);
+ UNUSED_ASSERTION_VARIABLE(success);
+ ASSERT(success);
+
+ error = FenceTestHelper(this, flushCommandBuffer, &result);
+ if (error.isError())
+ {
+ *outResult = GL_WAIT_FAILED;
+ return error;
+ }
+ }
+
+ if (currentCounter.QuadPart >= endCounter)
+ {
+ *outResult = GL_TIMEOUT_EXPIRED;
+ }
+ else
+ {
+ *outResult = GL_CONDITION_SATISFIED;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence11::hasError() const
+gl::Error FenceSync11::serverWait(GLbitfield flags, GLuint64 timeout)
{
- return mRenderer->isDeviceLost();
+ // Because our API is currently designed to be called from a single thread, we don't need to do
+ // extra work for a server-side fence. GPU commands issued after the fence is created will always
+ // be processed after the fence is signaled.
+ return gl::Error(GL_NO_ERROR);
}
+gl::Error FenceSync11::getStatus(GLint *outResult)
+{
+ GLboolean result = GL_FALSE;
+ gl::Error error = FenceTestHelper(this, false, &result);
+ if (error.isError())
+ {
+ // The spec does not specify any way to report errors during the status test (e.g. device lost)
+ // so we report the fence is unblocked in case of error or signaled.
+ *outResult = GL_SIGNALED;
+
+ return error;
+ }
+
+ *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED);
+ return gl::Error(GL_NO_ERROR);
}
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
index 50c7621776..1223a53b90 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
@@ -4,10 +4,10 @@
// found in the LICENSE file.
//
-// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl.
+// Fence11.h: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl.
-#ifndef LIBGLESV2_RENDERER_Fence11_H_
-#define LIBGLESV2_RENDERER_Fence11_H_
+#ifndef LIBGLESV2_RENDERER_FENCE11_H_
+#define LIBGLESV2_RENDERER_FENCE11_H_
#include "libGLESv2/renderer/FenceImpl.h"
@@ -15,22 +15,46 @@ namespace rx
{
class Renderer11;
-class Fence11 : public FenceImpl
+class FenceNV11 : public FenceNVImpl
{
public:
- explicit Fence11(rx::Renderer11 *renderer);
- virtual ~Fence11();
+ explicit FenceNV11(Renderer11 *renderer);
+ virtual ~FenceNV11();
- bool isSet() const;
- void set();
- bool test(bool flushCommandBuffer);
- bool hasError() const;
+ gl::Error set();
+ gl::Error test(bool flushCommandBuffer, GLboolean *outFinished);
+ gl::Error finishFence(GLboolean *outFinished);
private:
- DISALLOW_COPY_AND_ASSIGN(Fence11);
+ DISALLOW_COPY_AND_ASSIGN(FenceNV11);
- rx::Renderer11 *mRenderer;
+ template<class T> friend gl::Error FenceSetHelper(T *fence);
+ template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished);
+
+ Renderer11 *mRenderer;
+ ID3D11Query *mQuery;
+};
+
+class FenceSync11 : public FenceSyncImpl
+{
+ public:
+ explicit FenceSync11(Renderer11 *renderer);
+ virtual ~FenceSync11();
+
+ gl::Error set();
+ gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
+ gl::Error serverWait(GLbitfield flags, GLuint64 timeout);
+ gl::Error getStatus(GLint *outResult);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FenceSync11);
+
+ template<class T> friend gl::Error FenceSetHelper(T *fence);
+ template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished);
+
+ Renderer11 *mRenderer;
ID3D11Query *mQuery;
+ LONGLONG mCounterFrequency;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
index 7536713af4..e6f3e90683 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
@@ -9,6 +9,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
@@ -22,15 +23,16 @@ namespace rx
{
Image11::Image11()
+ : mRenderer(NULL),
+ mDXGIFormat(DXGI_FORMAT_UNKNOWN),
+ mStagingTexture(NULL),
+ mStagingSubresource(0),
+ mRecoverFromStorage(false),
+ mAssociatedStorage(NULL),
+ mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()),
+ mRecoveredFromStorageCount(0)
+
{
- mStagingTexture = NULL;
- mRenderer = NULL;
- mDXGIFormat = DXGI_FORMAT_UNKNOWN;
- mRecoverFromStorage = false;
- mAssociatedStorage = NULL;
- mAssociatedStorageLevel = 0;
- mAssociatedStorageLayerTarget = 0;
- mRecoveredFromStorageCount = 0;
}
Image11::~Image11()
@@ -41,11 +43,11 @@ Image11::~Image11()
Image11 *Image11::makeImage11(Image *img)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
- return static_cast<rx::Image11*>(img);
+ ASSERT(HAS_DYNAMIC_TYPE(Image11*, img));
+ return static_cast<Image11*>(img);
}
-void Image11::generateMipmap(Image11 *dest, Image11 *src)
+gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src)
{
ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
@@ -55,21 +57,18 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src)
ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL);
D3D11_MAPPED_SUBRESOURCE destMapped;
- HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped);
- if (FAILED(destMapResult))
+ gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped);
+ if (error.isError())
{
- ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult);
- return;
+ return error;
}
D3D11_MAPPED_SUBRESOURCE srcMapped;
- HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped);
- if (FAILED(srcMapResult))
+ error = src->map(D3D11_MAP_READ, &srcMapped);
+ if (error.isError())
{
- ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult);
-
dest->unmap();
- return;
+ return error;
}
const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData);
@@ -83,6 +82,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src)
src->unmap();
dest->markDirty();
+
+ return gl::Error(GL_NO_ERROR);
}
bool Image11::isDirty() const
@@ -99,32 +100,10 @@ bool Image11::isDirty() const
return mDirty;
}
-bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region)
{
- TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
- return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
-}
+ TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(storage);
-bool Image11::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
- TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
- return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height);
-}
-
-bool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
-{
- TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
- return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
-}
-
-bool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height)
-{
- TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
- return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height);
-}
-
-bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
// If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times,
// then we should just keep the staging texture around to prevent the copying from impacting perf.
// We allow the Image11 to copy its data to/from TextureStorage once.
@@ -134,23 +113,38 @@ bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int laye
if (attemptToReleaseStagingTexture)
{
// If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it.
- storage11->releaseAssociatedImage(level, layerTarget, this);
+ gl::Error error = storage11->releaseAssociatedImage(index, this);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ ID3D11Resource *stagingTexture = NULL;
+ unsigned int stagingSubresourceIndex = 0;
+ gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
+ if (error.isError())
+ {
+ return error;
}
- bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1);
+ error = storage11->updateSubresourceLevel(stagingTexture, stagingSubresourceIndex, index, region);
+ if (error.isError())
+ {
+ return error;
+ }
// Once the image data has been copied into the Storage, we can release it locally.
- if (attemptToReleaseStagingTexture && updateSubresourceSuccess)
+ if (attemptToReleaseStagingTexture)
{
- storage11->associateImage(this, level, layerTarget);
+ storage11->associateImage(this, index);
releaseStagingTexture();
mRecoverFromStorage = true;
mAssociatedStorage = storage11;
- mAssociatedStorageLevel = level;
- mAssociatedStorageLayerTarget = layerTarget;
+ mAssociatedImageIndex = index;
}
- return updateSubresourceSuccess;
+ return gl::Error(GL_NO_ERROR);
}
bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const
@@ -158,13 +152,17 @@ bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const
return (mAssociatedStorage == textureStorage);
}
-bool Image11::recoverFromAssociatedStorage()
+gl::Error Image11::recoverFromAssociatedStorage()
{
if (mRecoverFromStorage)
{
- createStagingTexture();
+ gl::Error error = createStagingTexture();
+ if (error.isError())
+ {
+ return error;
+ }
- bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
+ bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, this);
// This means that the cached TextureStorage has been modified after this Image11 released its copy of its data.
// This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten.
@@ -173,17 +171,21 @@ bool Image11::recoverFromAssociatedStorage()
if (textureStorageCorrect)
{
// CopySubResource from the Storage to the Staging texture
- mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth);
+ gl::Box region(0, 0, 0, mWidth, mHeight, mDepth);
+ error = mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region);
+ if (error.isError())
+ {
+ return error;
+ }
+
mRecoveredFromStorageCount += 1;
}
// Reset all the recovery parameters, even if the texture storage association is broken.
disassociateStorage();
-
- return textureStorageCorrect;
}
- return false;
+ return gl::Error(GL_NO_ERROR);
}
void Image11::disassociateStorage()
@@ -191,16 +193,15 @@ void Image11::disassociateStorage()
if (mRecoverFromStorage)
{
// Make the texturestorage release the Image11 too
- mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
+ mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this);
mRecoverFromStorage = false;
mAssociatedStorage = NULL;
- mAssociatedStorageLevel = 0;
- mAssociatedStorageLayerTarget = 0;
+ mAssociatedImageIndex = gl::ImageIndex::MakeInvalid();
}
}
-bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
+bool Image11::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
{
if (mWidth != width ||
mHeight != height ||
@@ -227,7 +228,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat,
mActualFormat = dxgiFormatInfo.internalFormat;
mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
- SafeRelease(mStagingTexture);
+ releaseStagingTexture();
mDirty = (formatInfo.dataInitializerFunction != NULL);
return true;
@@ -247,8 +248,8 @@ DXGI_FORMAT Image11::getDXGIFormat() const
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle.
-void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input)
+gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input)
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
@@ -261,11 +262,10 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
D3D11_MAPPED_SUBRESOURCE mappedImage;
- HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
- if (FAILED(result))
+ gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
+ if (error.isError())
{
- ERR("Could not map image for loading.");
- return;
+ return error;
}
uint8_t* offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch));
@@ -274,10 +274,12 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt
offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
unmap();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input)
+gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input)
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
@@ -295,11 +297,10 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
D3D11_MAPPED_SUBRESOURCE mappedImage;
- HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
- if (FAILED(result))
+ gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
+ if (error.isError())
{
- ERR("Could not map image for loading.");
- return;
+ return error;
}
uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch +
@@ -311,81 +312,130 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL
offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
unmap();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
{
- gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
+ RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source);
+ ASSERT(sourceRenderTarget->getTexture());
- if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat)
+ UINT subresourceIndex = sourceRenderTarget->getSubresourceIndex();
+ ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(sourceRenderTarget->getTexture());
+
+ if (!sourceTexture2D)
{
- // No conversion needed-- use copyback fastpath
- ID3D11Texture2D *colorBufferTexture = NULL;
- unsigned int subresourceIndex = 0;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source RenderTarget.");
+ }
+
+ gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
+
+ SafeRelease(sourceTexture2D);
+
+ return error;
+}
+
+gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source)
+{
+ TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source);
+
+ UINT subresourceIndex = sourceStorage11->getSubresourceIndex(sourceIndex);
+ ID3D11Resource *resource = NULL;
+ gl::Error error = sourceStorage11->getResource(&resource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
+
+ if (!sourceTexture2D)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source TextureStorage.");
+ }
+
+ error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
+
+ SafeRelease(sourceTexture2D);
+
+ return error;
+}
+
+gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource)
+{
+ D3D11_TEXTURE2D_DESC textureDesc;
+ source->GetDesc(&textureDesc);
- if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+ if (textureDesc.Format == mDXGIFormat)
+ {
+ // No conversion needed-- use copyback fastpath
+ ID3D11Resource *stagingTexture = NULL;
+ unsigned int stagingSubresourceIndex = 0;
+ gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
+ if (error.isError())
{
- D3D11_TEXTURE2D_DESC textureDesc;
- colorBufferTexture->GetDesc(&textureDesc);
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- ID3D11Texture2D* srcTex = NULL;
- if (textureDesc.SampleDesc.Count > 1)
- {
- D3D11_TEXTURE2D_DESC resolveDesc;
- resolveDesc.Width = textureDesc.Width;
- resolveDesc.Height = textureDesc.Height;
- resolveDesc.MipLevels = 1;
- resolveDesc.ArraySize = 1;
- resolveDesc.Format = textureDesc.Format;
- resolveDesc.SampleDesc.Count = 1;
- resolveDesc.SampleDesc.Quality = 0;
- resolveDesc.Usage = D3D11_USAGE_DEFAULT;
- resolveDesc.BindFlags = 0;
- resolveDesc.CPUAccessFlags = 0;
- resolveDesc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
- if (FAILED(result))
- {
- ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
- return;
- }
-
- deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
- subresourceIndex = 0;
- }
- else
+ UINT subresourceAfterResolve = sourceSubResource;
+
+ ID3D11Texture2D* srcTex = NULL;
+ if (textureDesc.SampleDesc.Count > 1)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = textureDesc.Width;
+ resolveDesc.Height = textureDesc.Height;
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureDesc.Format;
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = 0;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
+ if (FAILED(result))
{
- srcTex = colorBufferTexture;
- srcTex->AddRef();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
}
- D3D11_BOX srcBox;
- srcBox.left = x;
- srcBox.right = x + width;
- srcBox.top = y;
- srcBox.bottom = y + height;
- srcBox.front = 0;
- srcBox.back = 1;
+ deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format);
+ subresourceAfterResolve = 0;
+ }
+ else
+ {
+ srcTex = source;
+ }
- deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox);
+ D3D11_BOX srcBox;
+ srcBox.left = sourceArea.x;
+ srcBox.right = sourceArea.x + sourceArea.width;
+ srcBox.top = sourceArea.y;
+ srcBox.bottom = sourceArea.y + sourceArea.height;
+ srcBox.front = 0;
+ srcBox.back = 1;
+ deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox);
+
+ if (textureDesc.SampleDesc.Count > 1)
+ {
SafeRelease(srcTex);
- SafeRelease(colorBufferTexture);
}
}
else
{
// This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
D3D11_MAPPED_SUBRESOURCE mappedImage;
- HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
- if (FAILED(result))
+ gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
+ if (error.isError())
{
- ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result);
- return;
+ return error;
}
// determine the offset coordinate into the destination buffer
@@ -394,17 +444,32 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
+ error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
unmap();
+
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ mDirty = true;
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *Image11::getStagingTexture()
+gl::Error Image11::getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex)
{
- createStagingTexture();
+ gl::Error error = createStagingTexture();
+ if (error.isError())
+ {
+ return error;
+ }
- return mStagingTexture;
+ *outStagingTexture = mStagingTexture;
+ *outSubresourceIndex = mStagingSubresource;
+ return gl::Error(GL_NO_ERROR);
}
void Image11::releaseStagingTexture()
@@ -412,149 +477,149 @@ void Image11::releaseStagingTexture()
SafeRelease(mStagingTexture);
}
-unsigned int Image11::getStagingSubresource()
-{
- createStagingTexture();
-
- return mStagingSubresource;
-}
-
-void Image11::createStagingTexture()
+gl::Error Image11::createStagingTexture()
{
if (mStagingTexture)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
+ ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0);
+
const DXGI_FORMAT dxgiFormat = getDXGIFormat();
- if (mWidth > 0 && mHeight > 0 && mDepth > 0)
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- int lodOffset = 1;
- GLsizei width = mWidth;
- GLsizei height = mHeight;
+ int lodOffset = 1;
+ GLsizei width = mWidth;
+ GLsizei height = mHeight;
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
- if (mTarget == GL_TEXTURE_3D)
+ if (mTarget == GL_TEXTURE_3D)
+ {
+ ID3D11Texture3D *newTexture = NULL;
+
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.Depth = mDepth;
+ desc.MipLevels = lodOffset + 1;
+ desc.Format = dxgiFormat;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ desc.MiscFlags = 0;
+
+ if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
{
- ID3D11Texture3D *newTexture = NULL;
-
- D3D11_TEXTURE3D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.Depth = mDepth;
- desc.MipLevels = lodOffset + 1;
- desc.Format = dxgiFormat;
- desc.Usage = D3D11_USAGE_STAGING;
- desc.BindFlags = 0;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
- desc.MiscFlags = 0;
-
- if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
- {
- std::vector<D3D11_SUBRESOURCE_DATA> initialData;
- std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
- lodOffset + 1, &initialData, &textureData);
+ std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+ std::vector< std::vector<BYTE> > textureData;
+ d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
+ lodOffset + 1, &initialData, &textureData);
- result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
- }
- else
- {
- result = device->CreateTexture3D(&desc, NULL, &newTexture);
- }
-
- if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- return gl::error(GL_OUT_OF_MEMORY);
- }
-
- mStagingTexture = newTexture;
- mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
}
- else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
+ else
{
- ID3D11Texture2D *newTexture = NULL;
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = lodOffset + 1;
- desc.ArraySize = 1;
- desc.Format = dxgiFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_STAGING;
- desc.BindFlags = 0;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
- desc.MiscFlags = 0;
-
- if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
- {
- std::vector<D3D11_SUBRESOURCE_DATA> initialData;
- std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
- lodOffset + 1, &initialData, &textureData);
+ result = device->CreateTexture3D(&desc, NULL, &newTexture);
+ }
- result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
- }
- else
- {
- result = device->CreateTexture2D(&desc, NULL, &newTexture);
- }
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
+ }
- if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- return gl::error(GL_OUT_OF_MEMORY);
- }
+ mStagingTexture = newTexture;
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ }
+ else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
+ {
+ ID3D11Texture2D *newTexture = NULL;
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = lodOffset + 1;
+ desc.ArraySize = 1;
+ desc.Format = dxgiFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ desc.MiscFlags = 0;
+
+ if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
+ {
+ std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+ std::vector< std::vector<BYTE> > textureData;
+ d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
+ lodOffset + 1, &initialData, &textureData);
- mStagingTexture = newTexture;
- mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
}
else
{
- UNREACHABLE();
+ result = device->CreateTexture2D(&desc, NULL, &newTexture);
}
+
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
+ }
+
+ mStagingTexture = newTexture;
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ }
+ else
+ {
+ UNREACHABLE();
}
mDirty = false;
+ return gl::Error(GL_NO_ERROR);
}
-HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
+gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
{
- createStagingTexture();
-
// We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
- recoverFromAssociatedStorage();
-
- HRESULT result = E_FAIL;
+ gl::Error error = recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
- if (mStagingTexture)
+ ID3D11Resource *stagingTexture = NULL;
+ unsigned int subresourceIndex = 0;
+ error = getStagingTexture(&stagingTexture, &subresourceIndex);
+ if (error.isError())
{
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
+ return error;
+ }
- // this can fail if the device is removed (from TDR)
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- }
- else if (SUCCEEDED(result))
- {
- mDirty = true;
- }
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ ASSERT(mStagingTexture);
+ HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map);
+
+ // this can fail if the device is removed (from TDR)
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ }
+ else if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result);
}
- return result;
+ mDirty = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void Image11::unmap()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h
index a76a61f036..a936e6d7b2 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h
@@ -11,6 +11,7 @@
#define LIBGLESV2_RENDERER_IMAGE11_H_
#include "libGLESv2/renderer/d3d/ImageD3D.h"
+#include "libGLESv2/ImageIndex.h"
#include "common/debug.h"
@@ -21,7 +22,6 @@ class Framebuffer;
namespace rx
{
-class Renderer;
class Renderer11;
class TextureStorage11;
@@ -33,42 +33,41 @@ class Image11 : public ImageD3D
static Image11 *makeImage11(Image *img);
- static void generateMipmap(Image11 *dest, Image11 *src);
+ static gl::Error generateMipmap(Image11 *dest, Image11 *src);
virtual bool isDirty() const;
- virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
- virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height);
+ virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
- virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
+ bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override;
DXGI_FORMAT getDXGIFormat() const;
-
- virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input);
- virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input);
- virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input);
+ virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input);
- bool recoverFromAssociatedStorage();
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ const gl::ImageIndex &sourceIndex, TextureStorage *source);
+
+ gl::Error recoverFromAssociatedStorage();
bool isAssociatedStorageValid(TextureStorage11* textureStorage) const;
void disassociateStorage();
protected:
- HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
+ gl::Error map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
void unmap();
private:
DISALLOW_COPY_AND_ASSIGN(Image11);
- bool copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+ gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box &region);
+ gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource);
- ID3D11Resource *getStagingTexture();
- unsigned int getStagingSubresource();
- void createStagingTexture();
+ gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex);
+ gl::Error createStagingTexture();
void releaseStagingTexture();
Renderer11 *mRenderer;
@@ -79,8 +78,7 @@ class Image11 : public ImageD3D
bool mRecoverFromStorage;
TextureStorage11 *mAssociatedStorage;
- int mAssociatedStorageLevel;
- int mAssociatedStorageLayerTarget;
+ gl::ImageIndex mAssociatedImageIndex;
unsigned int mRecoveredFromStorageCount;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
index f7c2b38e7e..3351df5ec1 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
@@ -40,7 +40,7 @@ class IndexBuffer11 : public IndexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(IndexBuffer11);
- rx::Renderer11 *const mRenderer;
+ Renderer11 *const mRenderer;
ID3D11Buffer *mBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
index d835e4fa68..ff90a6a69a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -12,6 +12,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
@@ -137,7 +138,16 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
{
gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetInputLayout(attributes, shaderInputLayout);
- ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout));
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+
+ ShaderExecutable *shader = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *shader11 = ShaderExecutable11::makeShaderExecutable11(shader);
D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
for (unsigned int j = 0; j < ilKey.elementCount; ++j)
@@ -145,7 +155,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
descs[j] = ilKey.elements[j].desc;
}
- HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout);
+ HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
index a4e84f91c2..6a3d3475ee 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -33,12 +33,38 @@ namespace rx
PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
: mRenderer(renderer),
+ mResourcesLoaded(false),
mBufferToTextureVS(NULL),
mBufferToTextureGS(NULL),
mParamsConstantBuffer(NULL),
mCopyRasterizerState(NULL),
mCopyDepthStencilState(NULL)
{
+}
+
+PixelTransfer11::~PixelTransfer11()
+{
+ for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++)
+ {
+ SafeRelease(shaderMapIt->second);
+ }
+
+ mBufferToTexturePSMap.clear();
+
+ SafeRelease(mBufferToTextureVS);
+ SafeRelease(mBufferToTextureGS);
+ SafeRelease(mParamsConstantBuffer);
+ SafeRelease(mCopyRasterizerState);
+ SafeRelease(mCopyDepthStencilState);
+}
+
+gl::Error PixelTransfer11::loadResources()
+{
+ if (mResourcesLoaded)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
HRESULT result = S_OK;
ID3D11Device *device = mRenderer->getDevice();
@@ -56,6 +82,10 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
result = device->CreateRasterizerState(&rasterDesc, &mCopyRasterizerState);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer rasterizer state, result: 0x%X.", result);
+ }
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
depthStencilDesc.DepthEnable = true;
@@ -75,9 +105,13 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
result = device->CreateDepthStencilState(&depthStencilDesc, &mCopyDepthStencilState);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer depth stencil state, result: 0x%X.", result);
+ }
D3D11_BUFFER_DESC constantBufferDesc = { 0 };
- constantBufferDesc.ByteWidth = rx::roundUp<UINT>(sizeof(CopyShaderParams), 32u);
+ constantBufferDesc.ByteWidth = roundUp<UINT>(sizeof(CopyShaderParams), 32u);
constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
@@ -86,34 +120,39 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
result = device->CreateBuffer(&constantBufferDesc, NULL, &mParamsConstantBuffer);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer constant buffer, result: 0x%X.", result);
+ }
d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer");
- StructZero(&mParamsData);
-
// init shaders
- if (mRenderer->isLevel9())
- return;
-
mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS");
- mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
+ if (!mBufferToTextureVS)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader.");
+ }
- buildShaderMap();
-}
+ if (!mRenderer->isLevel9())
+ {
+ mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
+ if (!mBufferToTextureGS)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
+ }
+ }
-PixelTransfer11::~PixelTransfer11()
-{
- for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++)
+ gl::Error error = buildShaderMap();
+ if (error.isError())
{
- SafeRelease(shaderMapIt->second);
+ return error;
}
- mBufferToTexturePSMap.clear();
+ StructZero(&mParamsData);
- SafeRelease(mBufferToTextureVS);
- SafeRelease(mBufferToTextureGS);
- SafeRelease(mParamsConstantBuffer);
- SafeRelease(mCopyRasterizerState);
- SafeRelease(mCopyDepthStencilState);
+ mResourcesLoaded = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat,
@@ -138,18 +177,21 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons
parametersOut->PositionScale[1] = -2.0f / static_cast<float>(destSize.height);
}
-bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
+gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
- gl::Extents destSize = destRenderTarget->getExtents();
-
- if (destArea.x < 0 || destArea.x + destArea.width > destSize.width ||
- destArea.y < 0 || destArea.y + destArea.height > destSize.height ||
- destArea.z < 0 || destArea.z + destArea.depth > destSize.depth )
+ gl::Error error = loadResources();
+ if (error.isError())
{
- return false;
+ return error;
}
+ gl::Extents destSize = destRenderTarget->getExtents();
+
+ ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width &&
+ destArea.y >= 0 && destArea.y + destArea.height <= destSize.height &&
+ destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth );
+
const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get();
ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
@@ -177,7 +219,6 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- ID3D11ShaderResourceView *nullSRV = NULL;
ID3D11Buffer *nullBuffer = NULL;
UINT zero = 0;
@@ -187,7 +228,7 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un
deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0);
deviceContext->GSSetShader(geometryShader, NULL, 0);
deviceContext->PSSetShader(pixelShader, NULL, 0);
- deviceContext->PSSetShaderResources(0, 1, &bufferSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV);
deviceContext->IASetInputLayout(NULL);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
@@ -220,21 +261,32 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un
deviceContext->Draw(numPixels, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
mRenderer->markAllStateDirty();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-void PixelTransfer11::buildShaderMap()
+gl::Error PixelTransfer11::buildShaderMap()
{
ID3D11Device *device = mRenderer->getDevice();
mBufferToTexturePSMap[GL_FLOAT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4F, "BufferToTexture RGBA ps");
mBufferToTexturePSMap[GL_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4I, "BufferToTexture RGBA-I ps");
mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps");
+
+ // Check that all the shaders were created successfully
+ for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++)
+ {
+ if (shaderMapIt->second == NULL)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture pixel shader.");
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
index ed1a3ae1d0..29552140bb 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
@@ -11,6 +11,8 @@
#ifndef LIBGLESV2_PIXELTRANSFER11_H_
#define LIBGLESV2_PIXELTRANSFER11_H_
+#include "libGLESv2/Error.h"
+
#include "common/platform.h"
#include <GLES2/gl2.h>
@@ -38,15 +40,13 @@ class PixelTransfer11
explicit PixelTransfer11(Renderer11 *renderer);
~PixelTransfer11();
- static bool supportsBufferToTextureCopy(GLenum internalFormat);
-
// unpack: the source buffer is stored in the unpack state, and buffer strides
// offset: the start of the data within the unpack buffer
// destRenderTarget: individual slice/layer of a target texture
// destinationFormat/sourcePixelsType: determines shaders + shader parameters
// destArea: the sub-section of destRenderTarget to copy to
- bool copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+ gl::Error copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
private:
@@ -65,11 +65,13 @@ class PixelTransfer11
static void setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat,
const gl::PixelUnpackState &unpack, unsigned int offset, CopyShaderParams *parametersOut);
- void buildShaderMap();
+ gl::Error loadResources();
+ gl::Error buildShaderMap();
ID3D11PixelShader *findBufferToTexturePS(GLenum internalFormat) const;
Renderer11 *mRenderer;
+ bool mResourcesLoaded;
std::map<GLenum, ID3D11PixelShader *> mBufferToTexturePSMap;
ID3D11VertexShader *mBufferToTextureVS;
ID3D11GeometryShader *mBufferToTextureGS;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
index 7109be3e28..17ab1f8ab3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
@@ -10,13 +10,14 @@
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
#include "libGLESv2/main.h"
+#include "common/utilities.h"
#include <GLES2/gl2ext.h>
namespace rx
{
-Query11::Query11(rx::Renderer11 *renderer, GLenum type)
+Query11::Query11(Renderer11 *renderer, GLenum type)
: QueryImpl(type),
mResult(0),
mQueryFinished(false),
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h
index 822f2542ee..f9ff467873 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h
@@ -18,7 +18,7 @@ class Renderer11;
class Query11 : public QueryImpl
{
public:
- Query11(rx::Renderer11 *renderer, GLenum type);
+ Query11(Renderer11 *renderer, GLenum type);
virtual ~Query11();
virtual gl::Error begin();
@@ -35,7 +35,7 @@ class Query11 : public QueryImpl
bool mQueryFinished;
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
ID3D11Query *mQuery;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
index 71b931f27e..ab4f60bd98 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -38,11 +38,14 @@ const unsigned int RenderStateCache::kMaxRasterizerStates = 4096;
const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096;
const unsigned int RenderStateCache::kMaxSamplerStates = 4096;
-RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0),
- mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
- mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
- mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
- mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
+RenderStateCache::RenderStateCache(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mDevice(NULL),
+ mCounter(0),
+ mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
+ mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
+ mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
+ mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
{
}
@@ -89,7 +92,7 @@ gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, co
bool mrt = false;
- const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender();
+ const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(mRenderer->getWorkarounds());
BlendStateKey key = { 0 };
key.blendState = blendState;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
index d5471a3061..dfd1d84265 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
@@ -28,7 +28,7 @@ class Renderer11;
class RenderStateCache
{
public:
- RenderStateCache();
+ RenderStateCache(Renderer11 *renderer);
virtual ~RenderStateCache();
void initialize(ID3D11Device *device);
@@ -42,6 +42,7 @@ class RenderStateCache
private:
DISALLOW_COPY_AND_ASSIGN(RenderStateCache);
+ Renderer11 *mRenderer;
unsigned long long mCounter;
// Blend state cache
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
index 3041f21faa..aff3453492 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
@@ -10,6 +10,7 @@
#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/main.h"
@@ -176,276 +177,228 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth
return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
}
-RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource,
- ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
+RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RenderTarget11*, target));
+ return static_cast<RenderTarget11*>(target);
+}
+
+void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
{
- mRenderer = Renderer11::makeRenderer11(renderer);
+ // Currently a no-op
+}
- mTexture = resource;
+TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
+ : mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mActualFormat(internalFormat),
+ mSamples(samples),
+ mSubresourceIndex(0),
+ mTexture(resource),
+ mRenderTarget(rtv),
+ mDepthStencil(NULL),
+ mShaderResource(srv)
+{
if (mTexture)
{
mTexture->AddRef();
}
- mRenderTarget = rtv;
if (mRenderTarget)
{
mRenderTarget->AddRef();
}
- mDepthStencil = NULL;
-
- mShaderResource = srv;
if (mShaderResource)
{
mShaderResource->AddRef();
}
- mSubresourceIndex = 0;
-
if (mRenderTarget && mTexture)
{
+ mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
+
D3D11_RENDER_TARGET_VIEW_DESC desc;
mRenderTarget->GetDesc(&desc);
- unsigned int mipLevels, samples;
- getTextureProperties(mTexture, &mipLevels, &samples);
-
- mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
- mWidth = width;
- mHeight = height;
- mDepth = depth;
- mSamples = samples;
-
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
- mInternalFormat = dxgiFormatInfo.internalFormat;
mActualFormat = dxgiFormatInfo.internalFormat;
}
}
-RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource,
- ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
+TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
+ : mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mActualFormat(internalFormat),
+ mSamples(samples),
+ mSubresourceIndex(0),
+ mTexture(resource),
+ mRenderTarget(NULL),
+ mDepthStencil(dsv),
+ mShaderResource(srv)
{
- mRenderer = Renderer11::makeRenderer11(renderer);
-
- mTexture = resource;
if (mTexture)
{
mTexture->AddRef();
}
- mRenderTarget = NULL;
-
- mDepthStencil = dsv;
if (mDepthStencil)
{
mDepthStencil->AddRef();
}
- mShaderResource = srv;
if (mShaderResource)
{
mShaderResource->AddRef();
}
- mSubresourceIndex = 0;
-
if (mDepthStencil && mTexture)
{
+ mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
+
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
mDepthStencil->GetDesc(&desc);
- unsigned int mipLevels, samples;
- getTextureProperties(mTexture, &mipLevels, &samples);
-
- mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
- mWidth = width;
- mHeight = height;
- mDepth = depth;
- mSamples = samples;
-
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
- mInternalFormat = dxgiFormatInfo.internalFormat;
mActualFormat = dxgiFormatInfo.internalFormat;
}
}
-RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
+TextureRenderTarget11::~TextureRenderTarget11()
{
- mRenderer = Renderer11::makeRenderer11(renderer);
- mTexture = NULL;
- mRenderTarget = NULL;
- mDepthStencil = NULL;
- mShaderResource = NULL;
+ SafeRelease(mTexture);
+ SafeRelease(mRenderTarget);
+ SafeRelease(mDepthStencil);
+ SafeRelease(mShaderResource);
+}
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
+ID3D11Resource *TextureRenderTarget11::getTexture() const
+{
+ return mTexture;
+}
- const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
- GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+ID3D11RenderTargetView *TextureRenderTarget11::getRenderTargetView() const
+{
+ return mRenderTarget;
+}
- if (width > 0 && height > 0)
- {
- // Create texture resource
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = 1;
- desc.ArraySize = 1;
- desc.Format = formatInfo.texFormat;
- desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- // If a rendertarget or depthstencil format exists for this texture format,
- // we'll flag it to allow binding that way. Shader resource views are a little
- // more complicated.
- bool bindRTV = false, bindDSV = false, bindSRV = false;
- bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
- bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
- if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
- {
- // Multisample targets flagged for binding as depth stencil cannot also be
- // flagged for binding as SRV, so make certain not to add the SRV flag for
- // these targets.
- bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
- }
-
- desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) |
- (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
- (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
-
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11Texture2D *texture = NULL;
- HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
- mTexture = texture;
-
- if (result == E_OUTOFMEMORY)
- {
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
-
- if (bindSRV)
- {
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = formatInfo.srvFormat;
- srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
- srvDesc.Texture2D.MostDetailedMip = 0;
- srvDesc.Texture2D.MipLevels = 1;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(mTexture);
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
- }
-
- if (bindDSV)
- {
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = formatInfo.dsvFormat;
- dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
- dsvDesc.Texture2D.MipSlice = 0;
- dsvDesc.Flags = 0;
- result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(mTexture);
- SafeRelease(mShaderResource);
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
- }
-
- if (bindRTV)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = formatInfo.rtvFormat;
- rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
- rtvDesc.Texture2D.MipSlice = 0;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(mTexture);
- SafeRelease(mShaderResource);
- SafeRelease(mDepthStencil);
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
-
- if (formatInfo.dataInitializerFunction != NULL)
- {
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
-
- const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
- context->ClearRenderTargetView(mRenderTarget, clearValues);
- }
- }
- }
+ID3D11DepthStencilView *TextureRenderTarget11::getDepthStencilView() const
+{
+ return mDepthStencil;
+}
+ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const
+{
+ return mShaderResource;
+}
- mWidth = width;
- mHeight = height;
- mDepth = 1;
- mInternalFormat = internalFormat;
- mSamples = supportedSamples;
- mActualFormat = dxgiFormatInfo.internalFormat;
- mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
+GLsizei TextureRenderTarget11::getWidth() const
+{
+ return mWidth;
}
-RenderTarget11::~RenderTarget11()
+GLsizei TextureRenderTarget11::getHeight() const
{
- SafeRelease(mTexture);
- SafeRelease(mRenderTarget);
- SafeRelease(mDepthStencil);
- SafeRelease(mShaderResource);
+ return mHeight;
}
-RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
+GLsizei TextureRenderTarget11::getDepth() const
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
- return static_cast<rx::RenderTarget11*>(target);
+ return mDepth;
}
-void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
+GLenum TextureRenderTarget11::getInternalFormat() const
{
- // Currently a no-op
+ return mInternalFormat;
}
-ID3D11Resource *RenderTarget11::getTexture() const
+GLenum TextureRenderTarget11::getActualFormat() const
{
- return mTexture;
+ return mActualFormat;
}
-ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
+GLsizei TextureRenderTarget11::getSamples() const
{
- return mRenderTarget;
+ return mSamples;
}
-ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
+unsigned int TextureRenderTarget11::getSubresourceIndex() const
{
- return mDepthStencil;
+ return mSubresourceIndex;
}
-ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
+
+SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth)
+ : mSwapChain(swapChain),
+ mDepth(depth)
{
- return mShaderResource;
+ ASSERT(mSwapChain);
}
-unsigned int RenderTarget11::getSubresourceIndex() const
+SurfaceRenderTarget11::~SurfaceRenderTarget11()
{
- return mSubresourceIndex;
+}
+
+GLsizei SurfaceRenderTarget11::getWidth() const
+{
+ return mSwapChain->getWidth();
+}
+
+GLsizei SurfaceRenderTarget11::getHeight() const
+{
+ return mSwapChain->getHeight();
+}
+
+GLsizei SurfaceRenderTarget11::getDepth() const
+{
+ return 1;
+}
+
+GLenum SurfaceRenderTarget11::getInternalFormat() const
+{
+ return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat());
+}
+
+GLenum SurfaceRenderTarget11::getActualFormat() const
+{
+ return d3d11::GetDXGIFormatInfo(d3d11::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat;
+}
+
+GLsizei SurfaceRenderTarget11::getSamples() const
+{
+ // Our EGL surfaces do not support multisampling.
+ return 0;
+}
+
+ID3D11Resource *SurfaceRenderTarget11::getTexture() const
+{
+ return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture());
+}
+
+ID3D11RenderTargetView *SurfaceRenderTarget11::getRenderTargetView() const
+{
+ return (mDepth ? NULL : mSwapChain->getRenderTarget());
+}
+
+ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const
+{
+ return (mDepth ? mSwapChain->getDepthStencil() : NULL);
+}
+
+ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const
+{
+ return (mDepth ? mSwapChain->getDepthStencilShaderResource() : mSwapChain->getRenderTargetShaderResource());
+}
+
+unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
+{
+ return 0;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
index 82182957af..c7babdda3f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
@@ -14,39 +14,95 @@
namespace rx
{
-class Renderer;
-class Renderer11;
+class SwapChain11;
class RenderTarget11 : public RenderTarget
{
public:
- // RenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them
- RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth);
- RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth);
- RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples);
- virtual ~RenderTarget11();
+ RenderTarget11() { }
+ virtual ~RenderTarget11() { }
static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget);
- virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height);
+ void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override;
- ID3D11Resource *getTexture() const;
- ID3D11RenderTargetView *getRenderTargetView() const;
- ID3D11DepthStencilView *getDepthStencilView() const;
- ID3D11ShaderResourceView *getShaderResourceView() const;
+ virtual ID3D11Resource *getTexture() const = 0;
+ virtual ID3D11RenderTargetView *getRenderTargetView() const = 0;
+ virtual ID3D11DepthStencilView *getDepthStencilView() const = 0;
+ virtual ID3D11ShaderResourceView *getShaderResourceView() const = 0;
- unsigned int getSubresourceIndex() const;
+ virtual unsigned int getSubresourceIndex() const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(RenderTarget11);
+};
+
+class TextureRenderTarget11 : public RenderTarget11
+{
+ public:
+ // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them
+ TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples);
+ TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples);
+ virtual ~TextureRenderTarget11();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ ID3D11Resource *getTexture() const override;
+ ID3D11RenderTargetView *getRenderTargetView() const override;
+ ID3D11DepthStencilView *getDepthStencilView() const override;
+ ID3D11ShaderResourceView *getShaderResourceView() const override;
+
+ unsigned int getSubresourceIndex() const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget11);
+
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ GLenum mActualFormat;
+ GLsizei mSamples;
unsigned int mSubresourceIndex;
ID3D11Resource *mTexture;
ID3D11RenderTargetView *mRenderTarget;
ID3D11DepthStencilView *mDepthStencil;
ID3D11ShaderResourceView *mShaderResource;
+};
+
+class SurfaceRenderTarget11 : public RenderTarget11
+{
+ public:
+ SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth);
+ virtual ~SurfaceRenderTarget11();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ ID3D11Resource *getTexture() const override;
+ ID3D11RenderTargetView *getRenderTargetView() const override;
+ ID3D11DepthStencilView *getDepthStencilView() const override;
+ ID3D11ShaderResourceView *getShaderResourceView() const override;
+
+ unsigned int getSubresourceIndex() const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget11);
- Renderer11 *mRenderer;
+ SwapChain11 *mSwapChain;
+ bool mDepth;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index b29b2ef910..e6d7f3025b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -6,12 +6,12 @@
// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
-#include "common/platform.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/State.h"
#include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
@@ -36,10 +36,12 @@
#include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
#include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h"
#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
#include "libEGL/Display.h"
#include "common/utilities.h"
+#include "common/tls.h"
#include <EGL/eglext.h>
@@ -59,6 +61,9 @@
namespace rx
{
+
+namespace
+{
static const DXGI_FORMAT RenderTargetFormats[] =
{
DXGI_FORMAT_B8G8R8A8_UNORM,
@@ -77,10 +82,22 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
};
-Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay)
- : Renderer(display),
+// Does *not* increment the resource ref count!!
+ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv)
+{
+ ID3D11Resource *resource = NULL;
+ ASSERT(srv);
+ srv->GetResource(&resource);
+ resource->Release();
+ return resource;
+}
+
+}
+
+Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes)
+ : RendererD3D(display),
mDc(hDc),
- mRequestedDisplay(requestedDisplay)
+ mStateCache(this)
{
mVertexDataManager = NULL;
mIndexDataManager = NULL;
@@ -112,6 +129,50 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint r
mAppliedGeometryShader = NULL;
mCurPointGeometryShader = NULL;
mAppliedPixelShader = NULL;
+
+ EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
+ EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0);
+ }
+ }
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0);
+ }
+ }
+
+#if !defined(ANGLE_ENABLE_D3D9)
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1);
+ }
+ }
+#endif
+
+ mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP
+ : D3D_DRIVER_TYPE_HARDWARE;
}
Renderer11::~Renderer11()
@@ -121,8 +182,8 @@ Renderer11::~Renderer11()
Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer));
- return static_cast<rx::Renderer11*>(renderer);
+ ASSERT(HAS_DYNAMIC_TYPE(Renderer11*, renderer));
+ return static_cast<Renderer11*>(renderer);
}
#ifndef __d3d11_1_h__
@@ -136,7 +197,7 @@ EGLint Renderer11::initialize()
return EGL_NOT_INITIALIZED;
}
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
@@ -157,33 +218,14 @@ EGLint Renderer11::initialize()
}
#endif
- D3D_FEATURE_LEVEL featureLevels[] =
- {
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
-#if !defined(ANGLE_ENABLE_D3D9)
- D3D_FEATURE_LEVEL_9_3,
- D3D_FEATURE_LEVEL_9_2,
- D3D_FEATURE_LEVEL_9_1,
-#endif
- };
-
- D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;
- if (mRequestedDisplay == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE)
- {
- driverType = D3D_DRIVER_TYPE_WARP;
- }
-
HRESULT result = S_OK;
-
#ifdef _DEBUG
result = D3D11CreateDevice(NULL,
- driverType,
+ mDriverType,
NULL,
D3D11_CREATE_DEVICE_DEBUG,
- featureLevels,
- ArraySize(featureLevels),
+ mAvailableFeatureLevels.data(),
+ mAvailableFeatureLevels.size(),
D3D11_SDK_VERSION,
&mDevice,
&mFeatureLevel,
@@ -198,11 +240,11 @@ EGLint Renderer11::initialize()
#endif
{
result = D3D11CreateDevice(NULL,
- driverType,
+ mDriverType,
NULL,
0,
- featureLevels,
- ArraySize(featureLevels),
+ mAvailableFeatureLevels.data(),
+ mAvailableFeatureLevels.size(),
D3D11_SDK_VERSION,
&mDevice,
&mFeatureLevel,
@@ -215,7 +257,18 @@ EGLint Renderer11::initialize()
}
}
-#if !ANGLE_SKIP_DXGI_1_2_CHECK && !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
+ if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
+ {
+ ID3D10Multithread *multithread;
+ result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread));
+ ASSERT(SUCCEEDED(result));
+ result = multithread->SetMultithreadProtected(true);
+ ASSERT(SUCCEEDED(result));
+ multithread->Release();
+ }
+#if !ANGLE_SKIP_DXGI_1_2_CHECK
// In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
// The easiest way to check is to query for a IDXGIDevice2.
bool requireDXGI1_2 = false;
@@ -244,13 +297,10 @@ EGLint Renderer11::initialize()
SafeRelease(dxgiDevice2);
}
#endif
+#endif
-#if !defined(ANGLE_PLATFORM_WINRT)
IDXGIDevice *dxgiDevice = NULL;
-#else
- IDXGIDevice1 *dxgiDevice = NULL;
-#endif
- result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
if (FAILED(result))
{
@@ -281,9 +331,9 @@ EGLint Renderer11::initialize()
}
// Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
-#if !defined(__MINGW32__) && defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
+#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
ID3D11InfoQueue *infoQueue;
- result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
+ result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
if (SUCCEEDED(result))
{
@@ -301,19 +351,6 @@ EGLint Renderer11::initialize()
}
#endif
-#if !defined(ANGLE_PLATFORM_WINRT)
- static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
- if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
- {
- ID3D10Multithread *multithread;
- result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread));
- ASSERT(SUCCEEDED(result));
- result = multithread->SetMultithreadProtected(true);
- ASSERT(SUCCEEDED(result));
- multithread->Release();
- }
-#endif
-
initializeDevice();
return EGL_SUCCESS;
@@ -394,7 +431,7 @@ void Renderer11::deleteConfigs(ConfigDesc *configDescList)
delete [] (configDescList);
}
-void Renderer11::sync(bool block)
+gl::Error Renderer11::sync(bool block)
{
if (block)
{
@@ -408,6 +445,10 @@ void Renderer11::sync(bool block)
result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result);
+ }
}
mDeviceContext->End(mSyncQuery);
@@ -416,13 +457,17 @@ void Renderer11::sync(bool block)
do
{
result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
+ }
// Keep polling, but allow other threads to do something useful first
Sleep(0);
if (testDeviceLost(true))
{
- return;
+ return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync.");
}
}
while (result == S_FALSE);
@@ -431,22 +476,26 @@ void Renderer11::sync(bool block)
{
mDeviceContext->Flush();
}
+
+ return gl::Error(GL_NO_ERROR);
}
-SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChain *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
- return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+ return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
}
gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
{
if (texture)
{
- TextureStorage *texStorage = texture->getNativeTexture();
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ ASSERT(textureD3D);
+
+ TextureStorage *texStorage = textureD3D->getNativeTexture();
if (texStorage)
{
TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
-
gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
texture->getSamplerState().swizzleGreen,
texture->getSamplerState().swizzleBlue,
@@ -461,16 +510,21 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
+gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam)
{
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ gl::SamplerState samplerStateInternal = samplerStateParam;
+ samplerStateInternal.baseLevel += textureD3D->getNativeTexture()->getTopLevel();
+
if (type == gl::SAMPLER_PIXEL)
{
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
- if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
+ gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
if (error.isError())
{
return error;
@@ -479,7 +533,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
ASSERT(dxSamplerState != NULL);
mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
- mCurPixelSamplerStates[index] = samplerState;
+ mCurPixelSamplerStates[index] = samplerStateInternal;
}
mForceSetPixelSamplerStates[index] = false;
@@ -488,10 +542,10 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
{
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
- if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
+ gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
if (error.isError())
{
return error;
@@ -500,7 +554,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
ASSERT(dxSamplerState != NULL);
mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
- mCurVertexSamplerStates[index] = samplerState;
+ mCurVertexSamplerStates[index] = samplerStateInternal;
}
mForceSetVertexSamplerStates[index] = false;
@@ -513,50 +567,36 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
{
ID3D11ShaderResourceView *textureSRV = NULL;
- bool forceSetTexture = false;
if (texture)
{
- TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
+ TextureD3D *textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorage *texStorage = textureImpl->getNativeTexture();
ASSERT(texStorage != NULL);
TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
- gl::SamplerState samplerState;
- texture->getSamplerStateWithNativeOffset(&samplerState);
- textureSRV = storage11->getSRV(samplerState);
+
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ gl::SamplerState samplerState = texture->getSamplerState();
+ samplerState.baseLevel += storage11->getTopLevel();
+
+ gl::Error error = storage11->getSRV(samplerState, &textureSRV);
+ if (error.isError())
+ {
+ return error;
+ }
// If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
// missing the shader resource view
ASSERT(textureSRV != NULL);
- forceSetTexture = textureImpl->hasDirtyImages();
textureImpl->resetDirty();
}
- if (type == gl::SAMPLER_PIXEL)
- {
- ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
-
- if (forceSetTexture || mCurPixelSRVs[index] != textureSRV)
- {
- mDeviceContext->PSSetShaderResources(index, 1, &textureSRV);
- }
-
- mCurPixelSRVs[index] = textureSRV;
- }
- else if (type == gl::SAMPLER_VERTEX)
- {
- ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
-
- if (forceSetTexture || mCurVertexSRVs[index] != textureSRV)
- {
- mDeviceContext->VSSetShaderResources(index, 1, &textureSRV);
- }
+ ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) ||
+ (type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits));
- mCurVertexSRVs[index] = textureSRV;
- }
- else UNREACHABLE();
+ setShaderResource(type, index, textureSRV);
return gl::Error(GL_NO_ERROR);
}
@@ -631,7 +671,7 @@ gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask)
{
if (mForceSetBlendState ||
@@ -831,7 +871,22 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
return count >= minCount;
}
-gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
+void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource)
+{
+ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
+ {
+ ID3D11ShaderResourceView *srv = currentSRVs[resourceIndex];
+
+ if (srv && GetSRVResource(srv) == resource)
+ {
+ setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
+ }
+ }
+}
+
+gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
// Get the color render buffer and serial
// Also extract the render target dimensions and view
@@ -842,7 +897,7 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
bool missingColorRenderTarget = true;
- const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender();
+ const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(getWorkarounds());
for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
@@ -863,17 +918,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer);
// Extract the render target dimensions and view
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
+ return error;
}
+ ASSERT(renderTarget);
framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
- if (!framebufferRTVs[colorAttachment])
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
- }
+ ASSERT(framebufferRTVs[colorAttachment]);
if (missingColorRenderTarget)
{
@@ -883,8 +937,12 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
missingColorRenderTarget = false;
}
- // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent
- // D3D11 warnings.
+#if !defined(NDEBUG)
+ // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
+ ID3D11Resource *renderTargetResource = renderTarget->getTexture();
+ unsetSRVsWithResource(gl::SAMPLER_VERTEX, renderTargetResource);
+ unsetSRVsWithResource(gl::SAMPLER_PIXEL, renderTargetResource);
+#endif
}
}
@@ -905,19 +963,17 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
ID3D11DepthStencilView* framebufferDSV = NULL;
if (depthStencil)
{
- RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil);
- if (!depthStencilRenderTarget)
+ RenderTarget11 *depthStencilRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
+ if (error.isError())
{
SafeRelease(framebufferRTVs);
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
+ return error;
}
+ ASSERT(depthStencilRenderTarget);
framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
- if (!framebufferDSV)
- {
- SafeRelease(framebufferRTVs);
- return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
- }
+ ASSERT(framebufferDSV);
// If there is no render buffer, the width, height and format values come from
// the depth stencil
@@ -964,17 +1020,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
- gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
+ gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
if (error.isError())
{
return error;
}
- return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
+ return mInputLayoutCache.applyVertexBuffers(attributes, state.getCurrentProgramBinary());
}
gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
@@ -1011,28 +1066,25 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen
return gl::Error(GL_NO_ERROR);
}
-void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
+void Renderer11::applyTransformFeedbackBuffers(const gl::State& state)
{
- ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
+ size_t numXFBBindings = state.getTransformFeedbackBufferIndexRange();
+ ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+
bool requiresUpdate = false;
- for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (size_t i = 0; i < numXFBBindings; i++)
{
- if (transformFeedbackBuffers[i])
+ gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
+ GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
+ ID3D11Buffer *d3dBuffer = NULL;
+ if (curXFBBuffer)
{
- Buffer11 *storage = Buffer11::makeBuffer11(transformFeedbackBuffers[i]->getImplementation());
- ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
-
- d3dBuffers[i] = buffer;
- d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1;
- }
- else
- {
- d3dBuffers[i] = NULL;
- d3dOffsets[i] = 0;
+ Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
+ d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
}
- if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i])
+ // TODO: mAppliedTFBuffers and friends should also be kept in a vector.
+ if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i])
{
requiresUpdate = true;
}
@@ -1040,12 +1092,29 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff
if (requiresUpdate)
{
- mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets);
- for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (size_t i = 0; i < numXFBBindings; ++i)
{
- mAppliedTFBuffers[i] = d3dBuffers[i];
- mAppliedTFOffsets[i] = offsets[i];
+ gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
+ GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
+
+ if (curXFBBuffer)
+ {
+ Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
+ ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+
+ mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer && mAppliedTFOffsets[i] != curXFBOffset) ?
+ static_cast<UINT>(curXFBOffset) : -1;
+ mAppliedTFBuffers[i] = d3dBuffer;
+ }
+ else
+ {
+ mAppliedTFBuffers[i] = NULL;
+ mCurrentD3DOffsets[i] = 0;
+ }
+ mAppliedTFOffsets[i] = curXFBOffset;
}
+
+ mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets);
}
}
@@ -1129,7 +1198,6 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons
return gl::Error(GL_NO_ERROR);
}
}
-
template<typename T>
static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data)
{
@@ -1213,10 +1281,17 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- gl::Buffer *indexBuffer = elementArrayBuffer;
- BufferImpl *storage = indexBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
// TODO: some level 9 hardware supports 32-bit indices; test and store support instead
@@ -1291,10 +1366,17 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- gl::Buffer *indexBuffer = elementArrayBuffer;
- BufferImpl *storage = indexBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
@@ -1376,9 +1458,23 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive)
{
- ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
- ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
- ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+
+ ShaderExecutable *vertexExe = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *pixelExe = NULL;
+ error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *geometryExe = programD3D->getGeometryExecutable();
ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
@@ -1433,16 +1529,14 @@ gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::V
if (dirtyUniforms)
{
- programBinary->dirtyAllUniforms();
+ programD3D->dirtyAllUniforms();
}
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
+gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
{
- const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms();
-
unsigned int totalRegisterCountVS = 0;
unsigned int totalRegisterCountPS = 0;
@@ -1466,7 +1560,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
}
}
- const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation());
+ const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(&program);
const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage());
const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
@@ -1598,7 +1692,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
{
gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer);
if (error.isError())
@@ -1626,14 +1720,12 @@ void Renderer11::markAllStateDirty()
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{
mForceSetVertexSamplerStates[vsamplerId] = true;
- mCurVertexSRVs[vsamplerId] = NULL;
}
ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size());
for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId)
{
mForceSetPixelSamplerStates[fsamplerId] = true;
- mCurPixelSRVs[fsamplerId] = NULL;
}
mForceSetBlendState = true;
@@ -1746,32 +1838,20 @@ bool Renderer11::testDeviceResettable()
return false;
}
- D3D_FEATURE_LEVEL featureLevels[] =
- {
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
-#if !defined(ANGLE_ENABLE_D3D9)
- D3D_FEATURE_LEVEL_9_3,
- D3D_FEATURE_LEVEL_9_2,
- D3D_FEATURE_LEVEL_9_1,
-#endif
- };
-
ID3D11Device* dummyDevice;
D3D_FEATURE_LEVEL dummyFeatureLevel;
ID3D11DeviceContext* dummyContext;
HRESULT result = D3D11CreateDevice(NULL,
- D3D_DRIVER_TYPE_HARDWARE,
+ mDriverType,
NULL,
#if defined(_DEBUG)
D3D11_CREATE_DEVICE_DEBUG,
#else
0,
#endif
- featureLevels,
- ArraySize(featureLevels),
+ mAvailableFeatureLevels.data(),
+ mAvailableFeatureLevels.size(),
D3D11_SDK_VERSION,
&dummyDevice,
&dummyFeatureLevel,
@@ -1939,119 +2019,37 @@ int Renderer11::getMaxSwapInterval() const
return 4;
}
-bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source);
- TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source);
- TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source);
- TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source);
- TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
- if (!storage11)
- {
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2061,59 +2059,48 @@ bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
- if (!storage11)
- {
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2123,59 +2110,48 @@ bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
- if (!storage11)
- {
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2185,61 +2161,48 @@ bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
- if (!storage11)
- {
- SafeRelease(source);
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- SafeRelease(source);
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2249,12 +2212,15 @@ bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectan
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
void Renderer11::unapplyRenderTargets()
@@ -2277,39 +2243,150 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView
}
}
-RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
+gl::Error Renderer11::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
{
SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
- RenderTarget11 *renderTarget = NULL;
+ *outRT = new SurfaceRenderTarget11(swapChain11, depth);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
+{
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format);
- if (depth)
+ const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
+ GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+
+ if (width > 0 && height > 0)
{
- // Note: depth stencil may be NULL for 0 sized surfaces
- renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(),
- swapChain11->getDepthStencilTexture(),
- swapChain11->getDepthStencilShaderResource(),
- swapChain11->getWidth(), swapChain11->getHeight(), 1);
+ // Create texture resource
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = formatInfo.texFormat;
+ desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ // If a rendertarget or depthstencil format exists for this texture format,
+ // we'll flag it to allow binding that way. Shader resource views are a little
+ // more complicated.
+ bool bindRTV = false, bindDSV = false, bindSRV = false;
+ bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
+ bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+ if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ // Multisample targets flagged for binding as depth stencil cannot also be
+ // flagged for binding as SRV, so make certain not to add the SRV flag for
+ // these targets.
+ bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
+ }
+
+ desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) |
+ (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
+ (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
+
+ // The format must be either an RTV or a DSV
+ ASSERT(bindRTV != bindDSV);
+
+ ID3D11Texture2D *texture = NULL;
+ HRESULT result = mDevice->CreateTexture2D(&desc, NULL, &texture);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result);
+ }
+
+ ID3D11ShaderResourceView *srv = NULL;
+ if (bindSRV)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = formatInfo.srvFormat;
+ srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+
+ result = mDevice->CreateShaderResourceView(texture, &srvDesc, &srv);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ SafeRelease(texture);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result);
+ }
+ }
+
+ if (bindDSV)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = formatInfo.dsvFormat;
+ dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ dsvDesc.Texture2D.MipSlice = 0;
+ dsvDesc.Flags = 0;
+
+ ID3D11DepthStencilView *dsv = NULL;
+ result = mDevice->CreateDepthStencilView(texture, &dsvDesc, &dsv);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ SafeRelease(texture);
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result);
+ }
+
+ *outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples);
+
+ SafeRelease(dsv);
+ }
+ else if (bindRTV)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = formatInfo.rtvFormat;
+ rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ rtvDesc.Texture2D.MipSlice = 0;
+
+ ID3D11RenderTargetView *rtv = NULL;
+ result = mDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ SafeRelease(texture);
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result);
+ }
+
+ if (formatInfo.dataInitializerFunction != NULL)
+ {
+ const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ mDeviceContext->ClearRenderTargetView(rtv, clearValues);
+ }
+
+ *outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples);
+
+ SafeRelease(rtv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ SafeRelease(texture);
+ SafeRelease(srv);
}
else
{
- // Note: render target may be NULL for 0 sized surfaces
- renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(),
- swapChain11->getOffscreenTexture(),
- swapChain11->getRenderTargetShaderResource(),
- swapChain11->getWidth(), swapChain11->getHeight(), 1);
+ *outRT = new TextureRenderTarget11(reinterpret_cast<ID3D11RenderTargetView*>(NULL), NULL, NULL, format, width, height, 1, supportedSamples);
}
- return renderTarget;
-}
-RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples)
-{
- RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples);
- return renderTarget;
+ return gl::Error(GL_NO_ERROR);
}
-ShaderImpl *Renderer11::createShader(GLenum type)
+ShaderImpl *Renderer11::createShader(const gl::Data &data, GLenum type)
{
- return new ShaderD3D(type, this);
+ return new ShaderD3D(data, type, this);
}
ProgramImpl *Renderer11::createProgram()
@@ -2322,22 +2399,23 @@ void Renderer11::releaseShaderCompiler()
ShaderD3D::releaseCompiler();
}
-ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers)
+gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable)
{
- ShaderExecutable11 *executable = NULL;
- HRESULT result;
-
switch (type)
{
- case rx::SHADER_VERTEX:
+ case SHADER_VERTEX:
{
ID3D11VertexShader *vertexShader = NULL;
ID3D11GeometryShader *streamOutShader = NULL;
- result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader);
+ HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result);
+ }
if (transformFeedbackVaryings.size() > 0)
{
@@ -2363,99 +2441,116 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length
result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(),
NULL, 0, 0, NULL, &streamOutShader);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create steam output shader, result: 0x%X.", result);
+ }
}
- if (vertexShader)
- {
- executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader);
- }
+ *outExecutable = new ShaderExecutable11(function, length, vertexShader, streamOutShader);
}
break;
- case rx::SHADER_PIXEL:
+ case SHADER_PIXEL:
{
ID3D11PixelShader *pixelShader = NULL;
- result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader);
+ HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader);
ASSERT(SUCCEEDED(result));
-
- if (pixelShader)
+ if (FAILED(result))
{
- executable = new ShaderExecutable11(function, length, pixelShader);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader, result: 0x%X.", result);
}
+
+ *outExecutable = new ShaderExecutable11(function, length, pixelShader);
}
break;
- case rx::SHADER_GEOMETRY:
+ case SHADER_GEOMETRY:
{
ID3D11GeometryShader *geometryShader = NULL;
- result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader);
+ HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader);
ASSERT(SUCCEEDED(result));
-
- if (geometryShader)
+ if (FAILED(result))
{
- executable = new ShaderExecutable11(function, length, geometryShader);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create geometry shader, result: 0x%X.", result);
}
+
+ *outExecutable = new ShaderExecutable11(function, length, geometryShader);
}
break;
default:
UNREACHABLE();
- break;
+ return gl::Error(GL_INVALID_OPERATION);
}
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround)
+gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable)
{
const char *profileType = NULL;
switch (type)
{
- case rx::SHADER_VERTEX:
+ case SHADER_VERTEX:
profileType = "vs";
break;
- case rx::SHADER_PIXEL:
+ case SHADER_PIXEL:
profileType = "ps";
break;
- case rx::SHADER_GEOMETRY:
+ case SHADER_GEOMETRY:
profileType = "gs";
break;
default:
UNREACHABLE();
- return NULL;
+ return gl::Error(GL_INVALID_OPERATION);
}
- const char *profileVersion = NULL;
+ unsigned int profileMajorVersion = 0;
+ unsigned int profileMinorVersion = 0;
+ const char *profileSuffix = NULL;
switch (mFeatureLevel)
{
case D3D_FEATURE_LEVEL_11_0:
- profileVersion = "5_0";
+ profileMajorVersion = 5;
+ profileMinorVersion = 0;
break;
case D3D_FEATURE_LEVEL_10_1:
- profileVersion = "4_1";
+ profileMajorVersion = 4;
+ profileMinorVersion = 1;
break;
case D3D_FEATURE_LEVEL_10_0:
- profileVersion = "4_0";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
break;
case D3D_FEATURE_LEVEL_9_3:
- profileVersion = "4_0_level_9_3";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
+ profileSuffix = "_level_9_3";
break;
case D3D_FEATURE_LEVEL_9_2:
- profileVersion = "4_0_level_9_2";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
+ profileSuffix = "_level_9_2";
break;
case D3D_FEATURE_LEVEL_9_1:
- profileVersion = "4_0_level_9_1";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
+ profileSuffix = "_level_9_1";
break;
+ break;
default:
UNREACHABLE();
- return NULL;
+ return gl::Error(GL_INVALID_OPERATION);
}
- char profile[32];
- snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion);
+ std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
+ if (profileSuffix)
+ profile += profileSuffix;
- UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0;
+ UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
if (gl::perfActive())
{
@@ -2464,44 +2559,51 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
#endif
flags |= D3DCOMPILE_DEBUG;
-
- std::string sourcePath = getTempPath();
- std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
- writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
// Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
// Try the default flags first and if compilation fails, try some alternatives.
- const UINT extraFlags[] =
- {
- flags,
- flags | D3DCOMPILE_SKIP_VALIDATION,
- flags | D3DCOMPILE_SKIP_OPTIMIZATION
- };
+ std::vector<CompileConfig> configs;
+ configs.push_back(CompileConfig(flags, "default" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization"));
- const static char *extraFlagNames[] =
- {
- "default",
- "skip validation",
- "skip optimization"
- };
+ D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} };
- int attempts = ArraySize(extraFlags);
+ ID3DBlob *binary = NULL;
+ std::string debugInfo;
+ gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, &debugInfo);
+ if (error.isError())
+ {
+ return error;
+ }
- ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
+ // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL
+ // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK.
if (!binary)
{
- return NULL;
+ *outExectuable = NULL;
+ return gl::Error(GL_NO_ERROR);
}
- ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type,
- transformFeedbackVaryings, separatedOutputBuffers);
+ error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
+ transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
+
SafeRelease(binary);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!debugInfo.empty())
+ {
+ (*outExectuable)->appendDebugInfo(debugInfo);
+ }
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
+UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
{
return new UniformStorage11(this, storageSize);
}
@@ -2531,9 +2633,14 @@ QueryImpl *Renderer11::createQuery(GLenum type)
return new Query11(this, type);
}
-FenceImpl *Renderer11::createFence()
+FenceNVImpl *Renderer11::createFenceNV()
{
- return new Fence11(this);
+ return new FenceNV11(this);
+}
+
+FenceSyncImpl *Renderer11::createFenceSync()
+{
+ return new FenceSync11(this);
}
TransformFeedbackImpl* Renderer11::createTransformFeedback()
@@ -2576,82 +2683,77 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
return true;
}
-bool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
+gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
ASSERT(supportsFastCopyBufferToTexture(destinationFormat));
return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
}
-bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource)
+gl::Error Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut)
+
{
- ASSERT(colorbuffer != NULL);
+ ASSERT(colorbuffer);
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
{
- *subresourceIndex = renderTarget->getSubresourceIndex();
+ return error;
+ }
- ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView();
- if (colorBufferRTV)
- {
- ID3D11Resource *textureResource = NULL;
- colorBufferRTV->GetResource(&textureResource);
+ ID3D11Resource *renderTargetResource = renderTarget->getTexture();
+ ASSERT(renderTargetResource);
- if (textureResource)
- {
- HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource);
- SafeRelease(textureResource);
+ *subresourceIndexOut = renderTarget->getSubresourceIndex();
+ *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource);
- if (SUCCEEDED(result))
- {
- return true;
- }
- else
- {
- ERR("Failed to extract the ID3D11Texture2D from the render target resource, "
- "HRESULT: 0x%X.", result);
- }
- }
- }
+ if (!(*texture2DOut))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget");
}
- return false;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter)
+gl::Error Renderer11::blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter)
{
if (blitRenderTarget)
{
gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer();
+ ASSERT(readBuffer);
- if (!readBuffer)
+ RenderTarget *readRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the read buffer from the read framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
+ ASSERT(readRenderTarget);
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
if (drawTarget->isEnabledColorAttachment(colorAttachment))
{
gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
+ ASSERT(drawBuffer);
- if (!drawBuffer)
+ RenderTarget *drawRenderTarget = NULL;
+ error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the draw buffer from the draw framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawRenderTarget);
- RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
-
- if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
- blitRenderTarget, false, false))
+ error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget,
+ false, false);
+ if (error.isError())
{
- return false;
+ return error;
}
}
}
@@ -2660,78 +2762,88 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read
if (blitDepth || blitStencil)
{
gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer();
- gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
+ ASSERT(readBuffer);
- if (!readBuffer)
+ RenderTarget *readRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(readRenderTarget);
- if (!drawBuffer)
+ gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
+ ASSERT(drawBuffer);
+
+ RenderTarget *drawRenderTarget = NULL;
+ error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawRenderTarget);
- RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
- RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
- ASSERT(readRenderTarget && drawRenderTarget);
-
- if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
- false, blitDepth, blitStencil))
+ error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false,
+ blitDepth, blitStencil);
+ if (error.isError())
{
- return false;
+ return error;
}
}
invalidateFramebufferSwizzles(drawTarget);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+gl::Error Renderer11::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
{
ID3D11Texture2D *colorBufferTexture = NULL;
unsigned int subresourceIndex = 0;
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
+ ASSERT(colorbuffer);
- if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+ gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture);
+ if (error.isError())
{
- gl::Rectangle area;
- area.x = x;
- area.y = y;
- area.width = width;
- area.height = height;
+ return error;
+ }
- gl::Buffer *packBuffer = pack.pixelBuffer.get();
- if (packBuffer != NULL)
- {
- rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
- PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
+ gl::Rectangle area;
+ area.x = x;
+ area.y = y;
+ area.width = width;
+ area.height = height;
- gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
- if (error.isError())
- {
- return error;
- }
+ gl::Buffer *packBuffer = pack.pixelBuffer.get();
+ if (packBuffer != NULL)
+ {
+ Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
+ PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
- packBuffer->getIndexRangeCache()->clear();
- }
- else
+ error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
+ if (error.isError())
{
- gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
- if (error.isError())
- {
- return error;
- }
+ SafeRelease(colorBufferTexture);
+ return error;
}
- SafeRelease(colorBufferTexture);
+ packBuffer->getIndexRangeCache()->clear();
+ }
+ else
+ {
+ error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
+ if (error.isError())
+ {
+ SafeRelease(colorBufferTexture);
+ return error;
+ }
}
+ SafeRelease(colorBufferTexture);
+
return gl::Error(GL_NO_ERROR);
}
@@ -2740,11 +2852,11 @@ Image *Renderer11::createImage()
return new Image11();
}
-void Renderer11::generateMipmap(Image *dest, Image *src)
+gl::Error Renderer11::generateMipmap(Image *dest, Image *src)
{
Image11 *dest11 = Image11::makeImage11(dest);
Image11 *src11 = Image11::makeImage11(src);
- Image11::generateMipmap(dest11, src11);
+ return Image11::generateMipmap(dest11, src11);
}
TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
@@ -2788,6 +2900,19 @@ TextureImpl *Renderer11::createTexture(GLenum target)
return NULL;
}
+RenderbufferImpl *Renderer11::createRenderbuffer()
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ return renderbuffer;
+}
+
+RenderbufferImpl *Renderer11::createRenderbuffer(SwapChain *swapChain, bool depth)
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ renderbuffer->setStorage(swapChain, depth);
+ return renderbuffer;
+}
+
gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
{
@@ -2882,22 +3007,25 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub
SafeRelease(srcTex);
PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
- packPixels(stagingTex, packParams, pixels);
+ gl::Error error = packPixels(stagingTex, packParams, pixels);
SafeRelease(stagingTex);
- return gl::Error(GL_NO_ERROR);
+ return error;
}
-void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut)
+gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut)
{
D3D11_TEXTURE2D_DESC textureDesc;
readTexture->GetDesc(&textureDesc);
D3D11_MAPPED_SUBRESOURCE mapping;
HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping);
- UNUSED_ASSERTION_VARIABLE(hr);
- ASSERT(SUCCEEDED(hr));
+ if (FAILED(hr))
+ {
+ ASSERT(hr == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr);
+ }
uint8_t *source;
int inputPitch;
@@ -2968,24 +3096,23 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams
}
mDeviceContext->Unmap(readTexture, 0);
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
- RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
- bool colorBlit, bool depthBlit, bool stencilBlit)
+gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
+ RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
+ bool colorBlit, bool depthBlit, bool stencilBlit)
{
// Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
// it should never be the case that both color and depth/stencil need to be blitted at
// at the same time.
ASSERT(colorBlit != (depthBlit || stencilBlit));
- bool result = true;
-
RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
if (!drawRenderTarget)
{
- ERR("Failed to retrieve the draw render target from the draw framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer.");
}
ID3D11Resource *drawTexture = drawRenderTarget11->getTexture();
@@ -2996,8 +3123,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
if (!readRenderTarget)
{
- ERR("Failed to retrieve the read render target from the read framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer.");
}
ID3D11Resource *readTexture = NULL;
@@ -3019,7 +3145,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
if (FAILED(hresult))
{
SafeRelease(readTexture);
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader resource view to resolve multisampled framebuffer.");
}
}
}
@@ -3036,8 +3162,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
{
SafeRelease(readTexture);
SafeRelease(readSRV);
- ERR("Failed to retrieve the read render target view from the read render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target.");
}
gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
@@ -3063,6 +3188,8 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat());
bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit);
+ gl::Error result(GL_NO_ERROR);
+
if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() &&
!stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
(!(depthBlit || stencilBlit) || wholeBufferCopy))
@@ -3109,7 +3236,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0,
readTexture, readSubresource, pSrcBox);
- result = true;
+ result = gl::Error(GL_NO_ERROR);
}
else
{
@@ -3190,7 +3317,8 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta
ASSERT(attachment->isTexture());
gl::Texture *texture = attachment->getTexture();
- TextureStorage *texStorage = texture->getNativeTexture();
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ TextureStorage *texStorage = textureD3D->getNativeTexture();
if (texStorage)
{
TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
@@ -3204,7 +3332,7 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta
}
}
-void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer)
+void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer)
{
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
@@ -3248,7 +3376,7 @@ bool Renderer11::getLUID(LUID *adapterLuid) const
return true;
}
-rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
+VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
{
return d3d11::GetVertexFormatInfo(vertexFormat).conversionType;
}
@@ -3263,4 +3391,30 @@ void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureC
d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions);
}
+Workarounds Renderer11::generateWorkarounds() const
+{
+ return d3d11::GenerateWorkarounds();
+}
+
+void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
+{
+ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
+
+ if (currentSRVs[resourceSlot] != srv)
+ {
+ if (shaderType == gl::SAMPLER_VERTEX)
+ {
+ mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
+ }
+ else
+ {
+ mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
+ }
+
+ currentSRVs[resourceSlot] = srv;
+ }
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index 2a53fa1672..d44bd2fd30 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -13,12 +13,14 @@
#include "libGLESv2/angletypes.h"
#include "common/mathutil.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
#include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h"
#include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h"
+#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/RenderTarget.h"
+#include "libEGL/AttributeMap.h"
+
namespace gl
{
class FramebufferAttachment;
@@ -33,6 +35,7 @@ class StreamingIndexBufferInterface;
class Blit11;
class Clear11;
class PixelTransfer11;
+class RenderTarget11;
struct PackPixelsParams;
enum
@@ -41,10 +44,10 @@ enum
MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
};
-class Renderer11 : public Renderer
+class Renderer11 : public RendererD3D
{
public:
- Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay);
+ Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes);
virtual ~Renderer11();
static Renderer11 *makeRenderer11(Renderer *renderer);
@@ -55,19 +58,19 @@ class Renderer11 : public Renderer
virtual int generateConfigs(ConfigDesc **configDescList);
virtual void deleteConfigs(ConfigDesc *configDescList);
- virtual void sync(bool block);
+ virtual gl::Error sync(bool block);
- virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
virtual gl::Error generateSwizzle(gl::Texture *texture);
- virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask);
+ gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
@@ -76,32 +79,32 @@ class Renderer11 : public Renderer
bool ignoreViewport);
virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer);
+ gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
- virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary);
- virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances);
+
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
- virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
+ virtual void applyTransformFeedbackBuffers(const gl::State &state);
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
- virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+ gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
virtual void markAllStateDirty();
// lost device
- void notifyDeviceLost();
- virtual bool isDeviceLost();
- virtual bool testDeviceLost(bool notify);
- virtual bool testDeviceResettable();
+ void notifyDeviceLost() override;
+ bool isDeviceLost() override;
+ bool testDeviceLost(bool notify) override;
+ bool testDeviceResettable() override;
- virtual DWORD getAdapterVendor() const;
- virtual std::string getRendererDescription() const;
- virtual GUID getAdapterIdentifier() const;
+ DWORD getAdapterVendor() const override;
+ std::string getRendererDescription() const override;
+ GUID getAdapterIdentifier() const override;
virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const;
@@ -115,47 +118,43 @@ class Renderer11 : public Renderer
virtual int getMaxSwapInterval() const;
// Pixel operations
- virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source);
-
- virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
- virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+ virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter);
+ gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) override;
- virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
// RenderTarget creation
- virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
- virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples);
+ virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
// Shader creation
- virtual ShaderImpl *createShader(GLenum type);
+ virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
virtual ProgramImpl *createProgram();
// Shader operations
- virtual void releaseShaderCompiler();
- virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers);
- virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround);
+ void releaseShaderCompiler() override;
+ virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable);
+ virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable);
virtual UniformStorage *createUniformStorage(size_t storageSize);
// Image operations
virtual Image *createImage();
- virtual void generateMipmap(Image *dest, Image *source);
+ gl::Error generateMipmap(Image *dest, Image *source) override;
virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
@@ -165,6 +164,10 @@ class Renderer11 : public Renderer
// Texture creation
virtual TextureImpl *createTexture(GLenum target);
+ // Renderbuffer creation
+ virtual RenderbufferImpl *createRenderbuffer();
+ virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
+
// Buffer creation
virtual BufferImpl *createBuffer();
virtual VertexBuffer *createVertexBuffer();
@@ -175,7 +178,8 @@ class Renderer11 : public Renderer
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type);
- virtual FenceImpl *createFence();
+ virtual FenceNVImpl *createFenceNV();
+ virtual FenceSyncImpl *createFenceSync();
// Transform Feedback creation
virtual TransformFeedbackImpl* createTransformFeedback();
@@ -183,48 +187,54 @@ class Renderer11 : public Renderer
// D3D11-renderer specific methods
ID3D11Device *getDevice() { return mDevice; }
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
- IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+ DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; }
Blit11 *getBlitter() { return mBlit; }
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
- virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+
+ gl::Error getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut);
- bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
void unapplyRenderTargets();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
- void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
+ gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
virtual bool getLUID(LUID *adapterLuid) const;
- virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
+ virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
+ gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
+ GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
+
+ void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv);
+
private:
DISALLOW_COPY_AND_ASSIGN(Renderer11);
- virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const;
+ void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override;
+ Workarounds generateWorkarounds() const override;
gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
- gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
-
- bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
- RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
- bool colorBlit, bool depthBlit, bool stencilBlit);
+ gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
+ RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
+ bool colorBlit, bool depthBlit, bool stencilBlit);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
+ void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource);
static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel);
- static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer);
+ static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer);
HMODULE mD3d11Module;
HMODULE mDxgiModule;
EGLNativeDisplayType mDc;
- EGLint mRequestedDisplay;
+ std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
+ D3D_DRIVER_TYPE mDriverType;
HLSLCompiler mCompiler;
@@ -243,7 +253,7 @@ class Renderer11 : public Renderer
unsigned int mAppliedStencilbufferSerial;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
- rx::RenderTarget::Desc mRenderTargetDesc;
+ RenderTarget::Desc mRenderTargetDesc;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
@@ -292,8 +302,14 @@ class Renderer11 : public Renderer
unsigned int mAppliedIBOffset;
// Currently applied transform feedback buffers
- ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
+ ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current D3D buffers
+ // in use for streamout
+ GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current GL-specified
+ // buffer offsets to transform feedback
+ // buffers
+ UINT mCurrentD3DOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the D3D buffer offsets,
+ // which may differ from GLs, due
+ // to different append behavior
// Currently applied shaders
ID3D11VertexShader *mAppliedVertexShader;
@@ -339,7 +355,7 @@ class Renderer11 : public Renderer
IDXGIAdapter *mDxgiAdapter;
DXGI_ADAPTER_DESC mAdapterDescription;
char mDescription[128];
- IDXGIFactory *mDxgiFactory;
+ DXGIFactory *mDxgiFactory;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
index 4b29be055d..52c8a81633 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
@@ -6,7 +6,6 @@
// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
-#include "common/platform.h"
#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
@@ -16,12 +15,16 @@
#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h"
#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h"
+#include "common/features.h"
+#include "common/NativeWindow.h"
+
namespace rx
{
-SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
- : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+ : mRenderer(renderer),
+ SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
{
mSwapChain = NULL;
mBackBufferTexture = NULL;
@@ -39,8 +42,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDL
mPassThroughPS = NULL;
mWidth = -1;
mHeight = -1;
- mViewportWidth = -1;
- mViewportHeight = -1;
+ mRotateL = false;
+ mRotateR = false;
mSwapInterval = 0;
mAppCreatedShareHandle = mShareHandle != NULL;
mPassThroughResourcesInit = false;
@@ -91,11 +94,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
ASSERT(device != NULL);
// D3D11 does not allow zero size textures
- ASSERT(backbufferWidth >= 1);
- ASSERT(backbufferHeight >= 1);
+ ASSERT(backbufferWidth != 0);
+ ASSERT(backbufferHeight != 0);
// Preserve the render target content
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
if (previousOffscreenTexture)
{
@@ -137,8 +140,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
mOffscreenTexture->GetDesc(&offscreenTextureDesc);
- if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
- offscreenTextureDesc.Height != (UINT)backbufferHeight ||
+ if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) ||
+ offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) ||
offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
offscreenTextureDesc.MipLevels != 1 ||
offscreenTextureDesc.ArraySize != 1)
@@ -150,11 +153,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
}
else
{
- const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
+ const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
- offscreenTextureDesc.Width = backbufferWidth;
- offscreenTextureDesc.Height = backbufferHeight;
+ offscreenTextureDesc.Width = abs(backbufferWidth);
+ offscreenTextureDesc.Height = abs(backbufferHeight);
offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
offscreenTextureDesc.MipLevels = 1;
offscreenTextureDesc.ArraySize = 1;
@@ -234,8 +237,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
if (mDepthBufferFormat != GL_NONE)
{
D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
- depthStencilTextureDesc.Width = backbufferWidth;
- depthStencilTextureDesc.Height = backbufferHeight;
+ depthStencilTextureDesc.Width = abs(backbufferWidth);
+ depthStencilTextureDesc.Height = abs(backbufferHeight);
depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
depthStencilTextureDesc.MipLevels = 1;
depthStencilTextureDesc.ArraySize = 1;
@@ -286,12 +289,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
mWidth = backbufferWidth;
mHeight = backbufferHeight;
-#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
- mViewportWidth = backbufferWidth;
- mViewportHeight = backbufferHeight;
-#endif
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
if (previousOffscreenTexture != NULL)
{
D3D11_BOX sourceBox = {0};
@@ -310,7 +309,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
if (mSwapChain)
{
- swapRect(0, 0, mWidth, mHeight, SWAP_NORMAL);
+ swapRect(0, 0, mWidth, mHeight);
}
}
#endif
@@ -327,8 +326,16 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_BAD_ACCESS;
}
+ // Windows Phone works around the rotation limitation by using negative values for the swap chain size
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape
+ mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape
+ backbufferWidth = abs(backbufferWidth);
+ backbufferHeight = abs(backbufferHeight);
+#endif
+
// EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
- if (backbufferWidth < 1 || backbufferHeight < 1)
+ if (backbufferWidth == 0 || backbufferHeight == 0)
{
return EGL_SUCCESS;
}
@@ -336,19 +343,15 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
// Can only call resize if we have already created our swap buffer and resources
ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone
SafeRelease(mBackBufferTexture);
SafeRelease(mBackBufferRTView);
// Resize swap chain
- HRESULT result;
-#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP // Windows phone swap chain is never resized, only the texture is
-#if !defined(ANGLE_PLATFORM_WINRT)
- const int bufferCount = 1;
-#else
- const int bufferCount = 2;
-#endif
+ DXGI_SWAP_CHAIN_DESC desc;
+ mSwapChain->GetDesc(&desc);
const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
- result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
+ HRESULT result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
if (FAILED(result))
{
@@ -364,7 +367,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_BAD_ALLOC;
}
}
-#endif
result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
ASSERT(SUCCEEDED(result));
@@ -379,6 +381,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
{
d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
}
+#endif
return resetOffscreenTexture(backbufferWidth, backbufferHeight);
}
@@ -412,62 +415,14 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
return EGL_SUCCESS;
}
- if (mWindow)
+ if (mNativeWindow.getNativeWindow())
{
const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
- IDXGIFactory *factory = mRenderer->getDxgiFactory();
-
-#if !defined(ANGLE_PLATFORM_WINRT)
- DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
- swapChainDesc.BufferDesc.Width = backbufferWidth;
- swapChainDesc.BufferDesc.Height = backbufferHeight;
- swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
- swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
- swapChainDesc.BufferDesc.Format = backbufferFormatInfo.texFormat;
- swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
- swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.BufferCount = 1;
- swapChainDesc.OutputWindow = mWindow;
- swapChainDesc.Windowed = TRUE;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
- swapChainDesc.Flags = 0;
-
- HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
-#else
- IDXGIFactory2 *factory2;
- HRESULT result = factory->QueryInterface(IID_PPV_ARGS(&factory2));
- ASSERT(SUCCEEDED(result));
-
- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
- swapChainDesc.Width = 0;
- swapChainDesc.Height = 0;
- swapChainDesc.Format = backbufferFormatInfo.texFormat;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.Stereo = FALSE;
- swapChainDesc.Flags = 0;
-#if WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
- swapChainDesc.Scaling = DXGI_SCALING_NONE;
- swapChainDesc.BufferCount = 2;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
-#elif WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- swapChainDesc.BufferCount = 1;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
-#endif
+ HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(),
+ backbufferFormatInfo.texFormat,
+ backbufferWidth, backbufferHeight, &mSwapChain);
- IDXGISwapChain1 *swapChain;
- result = factory2->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
- mSwapChain = swapChain;
- HRESULT hr = swapChain->GetDesc1(&swapChainDesc);
- ASSERT(SUCCEEDED(hr));
- mViewportWidth = swapChainDesc.Width;
- mViewportHeight = swapChainDesc.Height;
-#endif
if (FAILED(result))
{
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
@@ -537,7 +492,7 @@ void SwapChain11::initPassThroughResources()
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;
samplerDesc.MinLOD = 0;
- samplerDesc.MaxLOD = FLT_MAX;
+ samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
ASSERT(SUCCEEDED(result));
@@ -563,7 +518,7 @@ void SwapChain11::initPassThroughResources()
}
// parameters should be validated/clamped by caller
-EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags)
+EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
@@ -573,16 +528,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- // Set vertices
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
- if (FAILED(result))
- {
- return EGL_BAD_ACCESS;
- }
-
- d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
-
// Create a quad in homogeneous coordinates
float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
@@ -594,8 +539,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
float u2 = (x + width) / float(mWidth);
float v2 = (y + height) / float(mHeight);
- const int rotateL = flags & SWAP_ROTATE_90;
- const int rotateR = flags & SWAP_ROTATE_270;
+ const bool rotateL = mRotateL;
+ const bool rotateR = mRotateR;
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
@@ -628,22 +583,23 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
// Set the viewport
D3D11_VIEWPORT viewport;
- viewport.TopLeftX = 0;
- viewport.TopLeftY = 0;
- viewport.Width = mViewportWidth;
- viewport.Height = mViewportHeight;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR);
+ viewport.Width = FLOAT(invertViewport ? mHeight : mWidth);
+ viewport.Height = FLOAT(invertViewport ? mWidth : mHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView);
deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
// Draw
deviceContext->Draw(4, 0);
-#ifdef ANGLE_FORCE_VSYNC_OFF
+#if ANGLE_VSYNC == ANGLE_DISABLED
result = mSwapChain->Present(0, 0);
#else
result = mSwapChain->Present(mSwapInterval, 0);
@@ -667,8 +623,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
}
// Unbind
- static ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
mRenderer->markAllStateDirty();
@@ -708,8 +663,8 @@ ID3D11Texture2D *SwapChain11::getDepthStencilTexture()
SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain));
- return static_cast<rx::SwapChain11*>(swapChain);
+ ASSERT(HAS_DYNAMIC_TYPE(SwapChain11*, swapChain));
+ return static_cast<SwapChain11*>(swapChain);
}
void SwapChain11::recreate()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
index b30b78568a..77509edcd3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
@@ -19,13 +19,13 @@ class Renderer11;
class SwapChain11 : public SwapChain
{
public:
- SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+ SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags);
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
virtual ID3D11Texture2D *getOffscreenTexture();
@@ -52,13 +52,13 @@ class SwapChain11 : public SwapChain
Renderer11 *mRenderer;
EGLint mHeight;
EGLint mWidth;
- EGLint mViewportWidth;
- EGLint mViewportHeight;
+ bool mRotateL;
+ bool mRotateR;
bool mAppCreatedShareHandle;
unsigned int mSwapInterval;
bool mPassThroughResourcesInit;
- IDXGISwapChain *mSwapChain;
+ DXGISwapChain *mSwapChain;
ID3D11Texture2D *mBackBufferTexture;
ID3D11RenderTargetView *mBackBufferRTView;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
index 91e7147da6..74af27e8b3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -8,6 +8,9 @@
// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
+
+#include <tuple>
+
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
@@ -15,6 +18,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
#include "libGLESv2/main.h"
#include "libGLESv2/ImageIndex.h"
@@ -52,46 +56,16 @@ TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
{
}
-bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const
-{
- return baseLevel == rhs.baseLevel &&
- mipLevels == rhs.mipLevels &&
- swizzle == rhs.swizzle;
-}
-
-TextureStorage11::SRVCache::~SRVCache()
+bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const
{
- for (size_t i = 0; i < cache.size(); i++)
- {
- SafeRelease(cache[i].srv);
- }
+ return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle);
}
-ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const
-{
- for (size_t i = 0; i < cache.size(); i++)
- {
- if (cache[i].key == key)
- {
- return cache[i].srv;
- }
- }
-
- return NULL;
-}
-
-ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv)
-{
- SRVPair pair = {key, srv};
- cache.push_back(pair);
-
- return srv;
-}
-
-TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
+TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags)
: mBindFlags(bindFlags),
mTopLevel(0),
mMipLevels(0),
+ mInternalFormat(GL_NONE),
mTextureFormat(DXGI_FORMAT_UNKNOWN),
mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
@@ -114,6 +88,12 @@ TextureStorage11::~TextureStorage11()
{
SafeRelease(mLevelSRVs[level]);
}
+
+ for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++)
+ {
+ SafeRelease(i->second);
+ }
+ mSrvCache.clear();
}
TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
@@ -183,17 +163,16 @@ int TextureStorage11::getLevelDepth(int mipLevel) const
return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
}
-UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
+UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
{
- UINT index = 0;
- if (getResource())
- {
- index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels);
- }
- return index;
+ UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel);
+ UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
+ UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ return subresource;
}
-ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
+gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV)
{
bool swizzleRequired = samplerState.swizzleRequired();
bool mipmapping = gl::IsMipmapFiltered(samplerState);
@@ -206,38 +185,71 @@ ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &sampl
{
verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
}
-
- SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
- ID3D11ShaderResourceView *srv = srvCache.find(key);
- if(srv)
+ SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
+ SRVCache::const_iterator iter = mSrvCache.find(key);
+ if (iter != mSrvCache.end())
{
- return srv;
+ *outSRV = iter->second;
}
+ else
+ {
+ ID3D11Resource *texture = NULL;
+ if (swizzleRequired)
+ {
+ gl::Error error = getSwizzleTexture(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
- DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
- ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource();
+ ID3D11ShaderResourceView *srv = NULL;
+ DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
+ gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mSrvCache.insert(std::make_pair(key, srv));
+ *outSRV = srv;
+ }
- srv = createSRV(samplerState.baseLevel, mipLevels, format, texture);
-
- return srvCache.add(key, srv);
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel)
+gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ if (!mLevelSRVs[mipLevel])
{
- if (!mLevelSRVs[mipLevel])
+ ID3D11Resource *resource = NULL;
+ gl::Error error = getResource(&resource);
+ if (error.isError())
{
- mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource());
+ return error;
}
- return mLevelSRVs[mipLevel];
- }
- else
- {
- return NULL;
+ error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ *outSRV = mLevelSRVs[mipLevel];
+
+ return gl::Error(GL_NO_ERROR);
}
gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -249,14 +261,25 @@ gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGr
if (mSwizzleCache[level] != swizzleTarget)
{
// Need to re-render the swizzle for this level
- ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level);
- ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level);
+ ID3D11ShaderResourceView *sourceSRV = NULL;
+ gl::Error error = getSRVLevel(level, &sourceSRV);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11RenderTargetView *destRTV = NULL;
+ error = getSwizzleRenderTarget(level, &destRTV);
+ if (error.isError())
+ {
+ return error;
+ }
gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
Blit11 *blitter = mRenderer->getBlitter();
- gl::Error error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
+ error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
if (error.isError())
{
return error;
@@ -287,104 +310,120 @@ void TextureStorage11::invalidateSwizzleCache()
}
}
-bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
- int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
+ const gl::ImageIndex &index, const gl::Box &copyArea)
{
- if (srcTexture)
- {
- invalidateSwizzleCacheLevel(level);
+ ASSERT(srcTexture);
- gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
- gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth);
+ GLint level = index.mipIndex;
- bool fullCopy = copyArea.x == 0 &&
- copyArea.y == 0 &&
- copyArea.z == 0 &&
- copyArea.width == texSize.width &&
- copyArea.height == texSize.height &&
- copyArea.depth == texSize.depth;
+ invalidateSwizzleCacheLevel(level);
- ID3D11Resource *dstTexture = getResource();
- unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
+ gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
- ASSERT(dstTexture);
+ bool fullCopy = copyArea.x == 0 &&
+ copyArea.y == 0 &&
+ copyArea.z == 0 &&
+ copyArea.width == texSize.width &&
+ copyArea.height == texSize.height &&
+ copyArea.depth == texSize.depth;
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
- {
- // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
- Blit11 *blitter = mRenderer->getBlitter();
+ ID3D11Resource *dstTexture = NULL;
+ gl::Error error = getResource(&dstTexture);
+ if (error.isError())
+ {
+ return error;
+ }
- return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
- dstTexture, dstSubresource, copyArea, texSize,
- NULL);
- }
- else
- {
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+ unsigned int dstSubresource = getSubresourceIndex(index);
- D3D11_BOX srcBox;
- srcBox.left = copyArea.x;
- srcBox.top = copyArea.y;
- srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth);
- srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight);
- srcBox.front = copyArea.z;
- srcBox.back = copyArea.z + copyArea.depth;
+ ASSERT(dstTexture);
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+ if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
+ {
+ // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
+ Blit11 *blitter = mRenderer->getBlitter();
- context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
- srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
- return true;
- }
+ return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
+ dstTexture, dstSubresource, copyArea, texSize,
+ NULL);
}
+ else
+ {
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- return false;
+ D3D11_BOX srcBox;
+ srcBox.left = copyArea.x;
+ srcBox.top = copyArea.y;
+ srcBox.right = copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatInfo.blockWidth);
+ srcBox.bottom = copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatInfo.blockHeight);
+ srcBox.front = copyArea.z;
+ srcBox.back = copyArea.z + copyArea.depth;
+
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
+ srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
+ return gl::Error(GL_NO_ERROR);
+ }
}
-bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
- int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
+ const gl::ImageIndex &index, const gl::Box &region)
{
- if (dstTexture)
+ ASSERT(dstTexture);
+
+ ID3D11Resource *srcTexture = NULL;
+ gl::Error error = getResource(&srcTexture);
+ if (error.isError())
{
- ID3D11Resource *srcTexture = getResource();
- unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
+ return error;
+ }
- ASSERT(srcTexture);
+ ASSERT(srcTexture);
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ unsigned int srcSubresource = getSubresourceIndex(index);
- context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset,
- srcTexture, srcSubresource, NULL);
- return true;
- }
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z,
+ srcTexture, srcSubresource, NULL);
- return false;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
+gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- if (source && dest)
+ ASSERT(sourceIndex.layerIndex == destIndex.layerIndex);
+
+ invalidateSwizzleCacheLevel(destIndex.mipIndex);
+
+ RenderTarget *source = NULL;
+ gl::Error error = getRenderTarget(sourceIndex, &source);
+ if (error.isError())
{
- ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
- ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
+ return error;
+ }
- if (sourceSRV && destRTV)
- {
- gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
- gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
+ RenderTarget *dest = NULL;
+ error = getRenderTarget(destIndex, &dest);
+ if (error.isError())
+ {
+ return error;
+ }
- gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
- gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+ ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
+ ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView();
- Blit11 *blitter = mRenderer->getBlitter();
+ gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
+ gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
- blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
- gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
- }
- }
+ gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
+ gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+
+ Blit11 *blitter = mRenderer->getBlitter();
+ return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
+ gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
}
void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -396,7 +435,112 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree
}
}
-TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
+gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ ID3D11Resource *sourceResouce = NULL;
+ gl::Error error = getResource(&sourceResouce);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage);
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource, sourceResouce);
+
+ dest11->invalidateSwizzleCache();
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
+{
+ ID3D11Resource *resource = NULL;
+ gl::Error error = getResource(&resource);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(resource);
+
+ UINT destSubresource = getSubresourceIndex(index);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat());
+
+ bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth));
+ ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
+
+ // TODO(jmadill): Handle compressed formats
+ // Compressed formats have different load syntax, so we'll have to handle them with slightly
+ // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
+ // with compressed formats in the calling logic.
+ ASSERT(!internalFormatInfo.compressed);
+
+ int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
+ int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
+ int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
+ UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment);
+ UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+
+ const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat());
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
+
+ size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
+
+ UINT bufferRowPitch = outputPixelSize * width;
+ UINT bufferDepthPitch = bufferRowPitch * height;
+
+ MemoryBuffer conversionBuffer;
+ if (!conversionBuffer.resize(bufferDepthPitch * depth))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
+ }
+
+ // TODO: fast path
+ LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
+ loadFunction(width, height, depth,
+ pixelData, srcRowPitch, srcDepthPitch,
+ conversionBuffer.data(), bufferRowPitch, bufferDepthPitch);
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ if (!fullUpdate)
+ {
+ ASSERT(destBox);
+
+ D3D11_BOX destD3DBox;
+ destD3DBox.left = destBox->x;
+ destD3DBox.right = destBox->x + destBox->width;
+ destD3DBox.top = destBox->y;
+ destD3DBox.bottom = destBox->y + destBox->height;
+ destD3DBox.front = 0;
+ destD3DBox.back = 1;
+
+ immediateContext->UpdateSubresource(resource, destSubresource,
+ &destD3DBox, conversionBuffer.data(),
+ bufferRowPitch, bufferDepthPitch);
+ }
+ else
+ {
+ immediateContext->UpdateSubresource(resource, destSubresource,
+ NULL, conversionBuffer.data(),
+ bufferRowPitch, bufferDepthPitch);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
: TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
mTexture(swapchain->getOffscreenTexture()),
mSwizzleTexture(NULL)
@@ -418,6 +562,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
mTextureHeight = texDesc.Height;
mTextureDepth = 1;
+ mInternalFormat = swapchain->GetBackBufferInternalFormat();
+
ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srv->GetDesc(&srvDesc);
@@ -439,7 +585,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
initializeSerials(1, 1);
}
-TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
mTexture(NULL),
mSwizzleTexture(NULL)
@@ -451,6 +597,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform
mSwizzleRenderTargets[i] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -460,51 +608,11 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width; // Compressed texture size constraints?
- desc.Height = height;
- desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = 1;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = 1;
- }
- }
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = 1;
initializeSerials(getLevelCount(), 1);
}
@@ -521,7 +629,11 @@ TextureStorage11_2D::~TextureStorage11_2D()
if (imageAssociationCorrect)
{
// We must let the Images recover their data before we delete it from the TextureStorage.
- mAssociatedImages[i]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ // TODO: Find a way to report this back to the context
+ }
}
}
}
@@ -542,8 +654,10 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage
return static_cast<TextureStorage11_2D*>(storage);
}
-void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -552,8 +666,10 @@ void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTar
}
}
-bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -566,8 +682,10 @@ bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Ima
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -582,8 +700,10 @@ void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11*
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -599,137 +719,168 @@ void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Ima
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2D::getResource() const
+gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth; // Compressed texture size constraints?
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels;
+ desc.ArraySize = 1;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(!index.hasLayer());
int level = index.mipIndex;
+ ASSERT(level >= 0 && level < getLevelCount());
- if (level >= 0 && level < getLevelCount())
+ if (!mRenderTarget[level])
{
- if (!mRenderTarget[level])
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
{
- ID3D11ShaderResourceView *srv = getSRVLevel(level);
- if (!srv)
- {
- return NULL;
- }
-
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- ID3D11Device *device = mRenderer->getDevice();
+ return error;
+ }
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = mTopLevel + level;
+ ID3D11ShaderResourceView *srv = NULL;
+ error = getSRVLevel(level, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
- ID3D11RenderTargetView *rtv;
- HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + level;
- mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11RenderTargetView *rtv;
+ HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- }
- else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- ID3D11Device *device = mRenderer->getDevice();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = mDepthStencilFormat;
- dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
- dsvDesc.Texture2D.MipSlice = mTopLevel + level;
- dsvDesc.Flags = 0;
+ mRenderTarget[level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
- ID3D11DepthStencilView *dsv;
- HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mDepthStencilFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Texture2D.MipSlice = mTopLevel + level;
+ dsvDesc.Flags = 0;
- mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11DepthStencilView *dsv;
+ HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
- // RenderTarget will take ownership of these resources
- SafeRelease(dsv);
- }
- else
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
}
- }
- return mRenderTarget[level];
- }
- else
- {
- return NULL;
+ mRenderTarget[level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(dsv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[level];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
- srvDesc.Texture2D.MipLevels = mipLevels;
-
- ID3D11ShaderResourceView *SRV = NULL;
+ srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels;
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11_2D::generateMipmaps()
+gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture)
{
- // Base level must already be defined
-
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
-
- gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ ASSERT(outTexture);
- generateMipmapLayer(source, dest);
- }
-}
-
-ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
-{
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -749,52 +900,52 @@ ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
- }
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
+ }
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
mTexture = NULL;
@@ -803,13 +954,15 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
mSwizzleRenderTargets[level] = NULL;
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
mAssociatedImages[face][level] = NULL;
mRenderTarget[face][level] = NULL;
}
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -819,56 +972,23 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- // adjust size if needed for compressed textures
- int height = size;
- d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
+ // adjust size if needed for compressed textures
+ int height = size;
+ d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = size;
- desc.Height = size;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = 6;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = 1;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mTextureDepth = 1;
- initializeSerials(getLevelCount() * 6, 6);
+ initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
-
TextureStorage11_Cube::~TextureStorage11_Cube()
{
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
if (mAssociatedImages[face][level] != NULL)
{
@@ -890,7 +1010,7 @@ TextureStorage11_Cube::~TextureStorage11_Cube()
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
SafeRelease(mSwizzleRenderTargets[level]);
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
SafeDelete(mRenderTarget[face][level]);
}
@@ -903,25 +1023,31 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS
return static_cast<TextureStorage11_Cube*>(storage);
}
-void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
mAssociatedImages[layerTarget][level] = image;
}
}
}
-bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage);
@@ -934,14 +1060,17 @@ bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, I
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
@@ -954,14 +1083,17 @@ void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image1
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
// No need to let the old Image recover its data, if it is also the incoming Image.
if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage)
@@ -974,114 +1106,165 @@ void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, I
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_Cube::getResource() const
+gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = CUBE_FACE_COUNT;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
int faceIndex = index.layerIndex;
int level = index.mipIndex;
- if (level >= 0 && level < getLevelCount())
- {
- if (!mRenderTarget[faceIndex][level])
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ASSERT(level >= 0 && level < getLevelCount());
+ ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT);
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = mShaderResourceFormat;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
- srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
- srvDesc.Texture2DArray.MipLevels = 1;
- srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- srvDesc.Texture2DArray.ArraySize = 1;
+ if (!mRenderTarget[faceIndex][level])
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- ID3D11ShaderResourceView *srv;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ srvDesc.Texture2DArray.ArraySize = 1;
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
- rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- rtvDesc.Texture2DArray.ArraySize = 1;
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ rtvDesc.Texture2DArray.ArraySize = 1;
- mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
- else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = mDepthStencilFormat;
- dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
- dsvDesc.Flags = 0;
- dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
- dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- dsvDesc.Texture2DArray.ArraySize = 1;
-
- ID3D11DepthStencilView *dsv;
- result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
- mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
- // RenderTarget will take ownership of these resources
- SafeRelease(dsv);
- SafeRelease(srv);
- }
- else
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ SafeRelease(srv);
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mDepthStencilFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Flags = 0;
+ dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ dsvDesc.Texture2DArray.ArraySize = 1;
+
+ ID3D11DepthStencilView *dsv;
+ result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
+
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
}
- }
- return mRenderTarget[faceIndex][level];
- }
- else
- {
- return NULL;
+ mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(dsv);
+ SafeRelease(srv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[faceIndex][level];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
@@ -1093,7 +1276,7 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi
srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.FirstArraySlice = 0;
- srvDesc.Texture2DArray.ArraySize = 6;
+ srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
}
else
{
@@ -1102,43 +1285,22 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi
srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
}
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11_Cube::generateMipmaps()
+gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture)
{
- // Base level must already be defined
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
-
- gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ ASSERT(outTexture);
- generateMipmapLayer(source, dest);
- }
- }
-}
-
-ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
-{
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -1147,7 +1309,7 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
desc.Width = mTextureWidth;
desc.Height = mTextureHeight;
desc.MipLevels = mMipLevels;
- desc.ArraySize = 6;
+ desc.ArraySize = CUBE_FACE_COUNT;
desc.Format = mSwizzleTextureFormat;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
@@ -1158,55 +1320,54 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = 0;
- rtvDesc.Texture2DArray.ArraySize = 6;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
+TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
@@ -1220,6 +1381,8 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform
mSwizzleRenderTargets[i] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -1229,49 +1392,13 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // If the width, height or depth are not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0 && depth > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE3D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.Depth = depth;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.Format = mTextureFormat;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = desc.Depth;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
initializeSerials(getLevelCount() * depth, depth);
}
@@ -1315,8 +1442,10 @@ TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage
return static_cast<TextureStorage11_3D*>(storage);
}
-void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1325,8 +1454,10 @@ void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTar
}
}
-bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -1339,8 +1470,10 @@ bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Ima
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1355,8 +1488,10 @@ void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11*
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+
ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1372,148 +1507,188 @@ void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Ima
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_3D::getResource() const
+gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // If the width, height or depth are not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.Depth = mTextureDepth;
+ desc.MipLevels = mMipLevels;
+ desc.Format = mTextureFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
srvDesc.Texture3D.MostDetailedMip = baseLevel;
srvDesc.Texture3D.MipLevels = mipLevels;
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
int mipLevel = index.mipIndex;
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
- if (mipLevel >= 0 && mipLevel < getLevelCount())
- {
- ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
+ ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
- if (!index.hasLayer())
+ if (!index.hasLayer())
+ {
+ if (!mLevelRenderTargets[mipLevel])
{
- if (!mLevelRenderTargets[mipLevel])
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
{
- ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
- if (!srv)
- {
- return NULL;
- }
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
-
- ID3D11RenderTargetView *rtv;
- HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ID3D11ShaderResourceView *srv = NULL;
+ error = getSRVLevel(mipLevel, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
- mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
+ ID3D11Device *device = mRenderer->getDevice();
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- }
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = -1;
- return mLevelRenderTargets[mipLevel];
- }
- else
- {
- int layer = index.layerIndex;
+ ID3D11RenderTargetView *rtv;
+ HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- LevelLayerKey key(mipLevel, layer);
- if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
-
- // TODO, what kind of SRV is expected here?
- ID3D11ShaderResourceView *srv = NULL;
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = layer;
- rtvDesc.Texture3D.WSize = 1;
+ mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(outRT);
+ *outRT = mLevelRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ int layer = index.layerIndex;
- mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+ LevelLayerKey key(mipLevel, layer);
+ if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- SafeRelease(srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
}
- return mLevelLayerRenderTargets[key];
- }
- }
+ // TODO, what kind of SRV is expected here?
+ ID3D11ShaderResourceView *srv = NULL;
- return NULL;
-}
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = layer;
+ rtvDesc.Texture3D.WSize = 1;
-void TextureStorage11_3D::generateMipmaps()
-{
- // Base level must already be defined
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
+ ASSERT(SUCCEEDED(result));
- gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level);
+ mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
- generateMipmapLayer(source, dest);
+ ASSERT(outRT);
+ *outRT = mLevelLayerRenderTargets[key];
+ return gl::Error(GL_NO_ERROR);
}
}
-ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
+gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture)
{
+ ASSERT(outTexture);
+
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -1531,55 +1706,54 @@ ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = -1;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
+TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
@@ -1591,6 +1765,8 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in
mSwizzleRenderTargets[level] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -1600,51 +1776,13 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the width, height or depth is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0 && depth > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = depth;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = desc.ArraySize;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
initializeSerials(getLevelCount() * depth, depth);
}
@@ -1685,8 +1823,11 @@ TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray
return static_cast<TextureStorage11_2DArray*>(storage);
}
-void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < getLevelCount());
if (0 <= level && level < getLevelCount())
@@ -1696,8 +1837,11 @@ void TextureStorage11_2DArray::associateImage(Image11* image, int level, int lay
}
}
-bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -1707,8 +1851,11 @@ bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
@@ -1721,8 +1868,11 @@ void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Ima
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
@@ -1739,18 +1889,62 @@ void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[key]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2DArray::getResource() const
+gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the width, height or depth is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = mTextureDepth;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
@@ -1760,112 +1954,94 @@ ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.ArraySize = mTextureDepth;
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(index.hasLayer());
int mipLevel = index.mipIndex;
int layer = index.layerIndex;
- if (mipLevel >= 0 && mipLevel < getLevelCount())
- {
- LevelLayerKey key(mipLevel, layer);
- if (mRenderTargets.find(key) == mRenderTargets.end())
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = mShaderResourceFormat;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
- srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
- srvDesc.Texture2DArray.MipLevels = 1;
- srvDesc.Texture2DArray.FirstArraySlice = layer;
- srvDesc.Texture2DArray.ArraySize = 1;
+ LevelLayerKey key(mipLevel, layer);
+ if (mRenderTargets.find(key) == mRenderTargets.end())
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- ID3D11ShaderResourceView *srv;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = layer;
+ srvDesc.Texture2DArray.ArraySize = 1;
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = layer;
- rtvDesc.Texture2DArray.ArraySize = 1;
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = layer;
+ rtvDesc.Texture2DArray.ArraySize = 1;
- mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- SafeRelease(srv);
- }
- else
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
- }
-
- return mRenderTargets[key];
- }
- else
- {
- return NULL;
- }
-}
-void TextureStorage11_2DArray::generateMipmaps()
-{
- // Base level must already be defined
+ mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
- for (int level = 0; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
- for (unsigned int layer = 0; layer < mTextureDepth; layer++)
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ SafeRelease(srv);
+ }
+ else
{
- gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer);
- gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
-
- generateMipmapLayer(source, dest);
+ UNREACHABLE();
}
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets[key];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
+gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture)
{
if (!mSwizzleTexture)
{
@@ -1886,52 +2062,51 @@ ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = 0;
- rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
index 9d63b2699d..930300a63d 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
@@ -25,7 +25,6 @@ namespace rx
{
class RenderTarget;
class RenderTarget11;
-class Renderer;
class Renderer11;
class SwapChain11;
class Image11;
@@ -41,47 +40,49 @@ class TextureStorage11 : public TextureStorage
UINT getBindFlags() const;
- virtual ID3D11Resource *getResource() const = 0;
- virtual ID3D11ShaderResourceView *getSRV(const gl::SamplerState &samplerState);
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+ virtual gl::Error getResource(ID3D11Resource **outResource) = 0;
+ virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
- virtual void generateMipmaps() = 0;
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
virtual int getLevelCount() const;
- UINT getSubresourceIndex(int mipLevel, int layerTarget) const;
+ UINT getSubresourceIndex(const gl::ImageIndex &index) const;
gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
void invalidateSwizzleCacheLevel(int mipLevel);
void invalidateSwizzleCache();
- bool updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, int level,
- int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource,
+ const gl::ImageIndex &index, const gl::Box &copyArea);
- bool copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, int level,
- int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
+ const gl::ImageIndex &index, const gl::Box &region);
- virtual void associateImage(Image11* image, int level, int layerTarget) = 0;
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage) = 0;
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) = 0;
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0;
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index) = 0;
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) = 0;
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) = 0;
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) = 0;
+
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
+ virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
protected:
- TextureStorage11(Renderer *renderer, UINT bindFlags);
- void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest);
+ TextureStorage11(Renderer11 *renderer, UINT bindFlags);
int getLevelWidth(int mipLevel) const;
int getLevelHeight(int mipLevel) const;
int getLevelDepth(int mipLevel) const;
- virtual ID3D11Resource *getSwizzleTexture() = 0;
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel) = 0;
- ID3D11ShaderResourceView *getSRVLevel(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0;
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0;
+ gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) = 0;
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const = 0;
void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
@@ -89,6 +90,7 @@ class TextureStorage11 : public TextureStorage
int mTopLevel;
unsigned int mMipLevels;
+ GLenum mInternalFormat;
DXGI_FORMAT mTextureFormat;
DXGI_FORMAT mShaderResourceFormat;
DXGI_FORMAT mRenderTargetFormat;
@@ -115,69 +117,53 @@ class TextureStorage11 : public TextureStorage
};
SwizzleCacheValue mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage11);
+
+ const UINT mBindFlags;
+
struct SRVKey
{
SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false);
- bool operator==(const SRVKey &rhs) const;
+ bool operator<(const SRVKey &rhs) const;
int baseLevel;
int mipLevels;
bool swizzle;
};
+ typedef std::map<SRVKey, ID3D11ShaderResourceView *> SRVCache;
- struct SRVPair
- {
- SRVKey key;
- ID3D11ShaderResourceView *srv;
- };
-
- struct SRVCache
- {
- ~SRVCache();
-
- ID3D11ShaderResourceView *find(const SRVKey &key) const;
- ID3D11ShaderResourceView *add(const SRVKey &key, ID3D11ShaderResourceView *srv);
-
- std::vector<SRVPair> cache;
- };
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage11);
-
- const UINT mBindFlags;
-
- SRVCache srvCache;
+ SRVCache mSrvCache;
ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
class TextureStorage11_2D : public TextureStorage11
{
public:
- TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain);
- TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
+ TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain);
+ TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual ~TextureStorage11_2D();
static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
ID3D11Texture2D *mTexture;
RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
@@ -191,68 +177,68 @@ class TextureStorage11_2D : public TextureStorage11
class TextureStorage11_Cube : public TextureStorage11
{
public:
- TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
+ TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
virtual ~TextureStorage11_Cube();
static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
+
+ static const size_t CUBE_FACE_COUNT = 6;
ID3D11Texture2D *mTexture;
- RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ RenderTarget11 *mRenderTarget[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
ID3D11Texture2D *mSwizzleTexture;
ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
- Image11 *mAssociatedImages[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ Image11 *mAssociatedImages[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
class TextureStorage11_3D : public TextureStorage11
{
public:
- TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
+ TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual ~TextureStorage11_3D();
static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
+ virtual gl::Error getResource(ID3D11Resource **outResource);
// Handles both layer and non-layer RTs
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
typedef std::pair<int, int> LevelLayerKey;
typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap;
@@ -270,30 +256,29 @@ class TextureStorage11_3D : public TextureStorage11
class TextureStorage11_2DArray : public TextureStorage11
{
public:
- TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
+ TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual ~TextureStorage11_2DArray();
static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
typedef std::pair<int, int> LevelLayerKey;
typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
index 590cb9f05a..70bc3bb26f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
@@ -19,7 +19,7 @@ class Renderer11;
class VertexArray11 : public VertexArrayImpl
{
public:
- VertexArray11(rx::Renderer11 *renderer)
+ VertexArray11(Renderer11 *renderer)
: VertexArrayImpl(),
mRenderer(renderer)
{
@@ -34,7 +34,7 @@ class VertexArray11 : public VertexArrayImpl
private:
DISALLOW_COPY_AND_ASSIGN(VertexArray11);
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
index 9bc5b1d2d1..a9d6fa2ca4 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -16,7 +16,7 @@
namespace rx
{
-VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
+VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
{
mBuffer = NULL;
mBufferSize = 0;
@@ -91,8 +91,13 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
{
if (buffer)
{
- Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation());
- input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
+ BufferD3D *storage = BufferD3D::makeFromBuffer(buffer);
+ gl::Error error = storage->getData(&input);
+ if (error.isError())
+ {
+ return error;
+ }
+ input += static_cast<int>(attrib.offset);
}
else
{
@@ -132,7 +137,7 @@ gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GL
else
{
// Round up to divisor, if possible
- elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
+ elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
gl::VertexFormat vertexFormat(attrib);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
index 0e10da1df8..a9bbac98fa 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
@@ -18,7 +18,7 @@ class Renderer11;
class VertexBuffer11 : public VertexBuffer
{
public:
- explicit VertexBuffer11(rx::Renderer11 *const renderer);
+ explicit VertexBuffer11(Renderer11 *const renderer);
virtual ~VertexBuffer11();
virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
@@ -40,7 +40,7 @@ class VertexBuffer11 : public VertexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
- rx::Renderer11 *const mRenderer;
+ Renderer11 *const mRenderer;
ID3D11Buffer *mBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
index c07828757d..90a879e170 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
@@ -795,7 +795,7 @@ static D3D11ES3FormatMap BuildD3D11FormatMap()
// From GL_EXT_texture_storage
// | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
- InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
+ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
index 2af97e73f0..121aa3bbad 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -10,6 +10,7 @@
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Framebuffer.h"
@@ -95,9 +96,6 @@
#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT
# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32
#endif
-#ifndef D3D11_VS_OUTPUT_REGISTER_COUNT
-# define D3D11_VS_OUTPUT_REGISTER_COUNT 32
-#endif
namespace rx
{
@@ -357,7 +355,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -377,7 +375,7 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
@@ -399,7 +397,7 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -421,7 +419,7 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -441,7 +439,7 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -466,7 +464,7 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -486,7 +484,7 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
@@ -506,7 +504,7 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
@@ -526,7 +524,7 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
@@ -546,7 +544,7 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
@@ -566,7 +564,7 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
@@ -586,7 +584,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
@@ -612,7 +610,7 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -636,7 +634,7 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -655,7 +653,7 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
@@ -677,7 +675,7 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
@@ -704,7 +702,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
@@ -733,7 +731,7 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
@@ -754,7 +752,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
@@ -778,7 +776,7 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
@@ -805,7 +803,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
@@ -826,7 +824,7 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
@@ -847,7 +845,7 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
@@ -868,7 +866,7 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
@@ -889,7 +887,7 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
@@ -914,7 +912,7 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
@@ -935,7 +933,7 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
@@ -951,11 +949,11 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
}
}
-static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel)
+static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -971,14 +969,14 @@ static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL fea
}
}
-static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel)
+static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
- case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) /
+ case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
GetMaximumStreamOutputBuffers(featureLevel);
@@ -1087,9 +1085,9 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
// Transform feedback limits
- caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel);
+ caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponents(featureLevel);
caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
- caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel);
+ caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateComponents(featureLevel);
// GL extension support
extensions->setTextureExtensionSupport(*textureCapsMap);
@@ -1198,17 +1196,31 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo
HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
{
-#if !defined(__MINGW32__) && defined(_DEBUG)
+#if defined(_DEBUG) && !defined(__MINGW32__)
return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
#else
return S_OK;
#endif
}
-RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT)
+{
+ RenderTarget *renderTarget = NULL;
+ gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ *outRT = RenderTarget11::makeRenderTarget11(renderTarget);
+ return gl::Error(GL_NO_ERROR);
+}
+
+Workarounds GenerateWorkarounds()
{
- RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
- return RenderTarget11::makeRenderTarget11(renderTarget);
+ Workarounds workarounds;
+ workarounds.mrtPerfWorkaround = true;
+ workarounds.setDataFasterThanImageUpload = true;
+ return workarounds;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
index 4c05eb9256..9df9c95763 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
@@ -12,6 +12,7 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
#include <vector>
@@ -23,6 +24,7 @@ class FramebufferAttachment;
namespace rx
{
class RenderTarget11;
+struct Workarounds;
namespace gl_d3d11
{
@@ -176,7 +178,9 @@ inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBu
context->Unmap(constantBuffer, 0);
}
-RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT);
+
+Workarounds GenerateWorkarounds();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
index f061a32c52..2ca7a9cf8a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
@@ -46,10 +46,16 @@ const size_t g_shaderSize[] =
namespace rx
{
-Blit9::Blit9(rx::Renderer9 *renderer)
- : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL)
+
+Blit9::Blit9(Renderer9 *renderer)
+ : mRenderer(renderer),
+ mGeometryLoaded(false),
+ mQuadVertexBuffer(NULL),
+ mQuadVertexDeclaration(NULL),
+ mSavedStateBlock(NULL),
+ mSavedRenderTarget(NULL),
+ mSavedDepthStencil(NULL)
{
- initGeometry();
memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
}
@@ -65,8 +71,13 @@ Blit9::~Blit9()
}
}
-void Blit9::initGeometry()
+gl::Error Blit9::initialize()
{
+ if (mGeometryLoaded)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
static const float quad[] =
{
-1, -1,
@@ -82,7 +93,7 @@ void Blit9::initGeometry()
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal blit vertex shader, result: 0x%X.", result);
}
void *lockPtr = NULL;
@@ -91,7 +102,8 @@ void Blit9::initGeometry()
if (FAILED(result) || lockPtr == NULL)
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY);
+ SafeRelease(mQuadVertexBuffer);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex shader, result: 0x%X.", result);
}
memcpy(lockPtr, quad, sizeof(quad));
@@ -108,14 +120,18 @@ void Blit9::initGeometry()
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY);
+ SafeRelease(mQuadVertexBuffer);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex declaration, result: 0x%X.", result);
}
+
+ mGeometryLoaded = true;
+ return gl::Error(GL_NO_ERROR);
}
template <class D3DShaderType>
-bool Blit9::setShader(ShaderId source, const char *profile,
- D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length),
- HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
+gl::Error Blit9::setShader(ShaderId source, const char *profile,
+ gl::Error (Renderer9::*createShader)(const DWORD *, size_t length, D3DShaderType **outShader),
+ HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
{
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -130,35 +146,32 @@ bool Blit9::setShader(ShaderId source, const char *profile,
const BYTE* shaderCode = g_shaderCode[source];
size_t shaderSize = g_shaderSize[source];
- shader = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
- if (!shader)
+ gl::Error error = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize, &shader);
+ if (error.isError())
{
- ERR("Failed to create shader for blit operation");
- return false;
+ return error;
}
mCompiledShaders[source] = shader;
}
HRESULT hr = (device->*setShader)(shader);
-
if (FAILED(hr))
{
- ERR("Failed to set shader for blit operation");
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to set shader for blit operation, result: 0x%X.", hr);
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit9::setVertexShader(ShaderId shader)
+gl::Error Blit9::setVertexShader(ShaderId shader)
{
- return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
+ return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
}
-bool Blit9::setPixelShader(ShaderId shader)
+gl::Error Blit9::setPixelShader(ShaderId shader)
{
- return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
+ return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
}
RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const
@@ -175,12 +188,19 @@ RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const
return rect;
}
-bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
+gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
{
- IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source));
- if (!texture)
+ gl::Error error = initialize();
+ if (error.isError())
{
- return false;
+ return error;
+ }
+
+ IDirect3DTexture9 *texture = NULL;
+ error = copySurfaceToTexture(source, getSurfaceRect(source), &texture);
+ if (error.isError())
+ {
+ return error;
}
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -205,87 +225,90 @@ bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
restoreState();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
{
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *source = NULL;
- gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
-
- if (colorbuffer)
+ gl::Error error = initialize();
+ if (error.isError())
{
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
+ return error;
}
- if (renderTarget)
- {
- source = renderTarget->getSurface();
- }
+ gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+ ASSERT(colorbuffer);
- if (!source)
+ RenderTarget9 *renderTarget9 = NULL;
+ error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(renderTarget9);
- TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
- IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
- bool result = false;
+ IDirect3DSurface9 *source = renderTarget9->getSurface();
+ ASSERT(source);
- if (destSurface)
+ IDirect3DSurface9 *destSurface = NULL;
+ TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
+ error = storage9->getSurfaceLevel(level, true, &destSurface);
+ if (error.isError())
{
- result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
- SafeRelease(destSurface);
+ return error;
}
+ ASSERT(destSurface);
+
+ gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ SafeRelease(destSurface);
SafeRelease(source);
+
return result;
}
-bool Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
{
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *source = NULL;
- gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
-
- if (colorbuffer)
+ gl::Error error = initialize();
+ if (error.isError())
{
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
+ return error;
}
- if (renderTarget)
- {
- source = renderTarget->getSurface();
- }
+ gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+ ASSERT(colorbuffer);
- if (!source)
+ RenderTarget9 *renderTarget9 = NULL;
+ error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(renderTarget9);
- TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
- IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
- bool result = false;
+ IDirect3DSurface9 *source = renderTarget9->getSurface();
+ ASSERT(source);
- if (destSurface)
+ IDirect3DSurface9 *destSurface = NULL;
+ TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
+ error = storage9->getCubeMapSurface(target, level, true, &destSurface);
+ if (error.isError())
{
- result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
- SafeRelease(destSurface);
+ return error;
}
+ ASSERT(destSurface);
+
+ gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ SafeRelease(destSurface);
SafeRelease(source);
+
return result;
}
-bool Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
{
- if (!dest)
- {
- return false;
- }
+ ASSERT(source != NULL && dest != NULL);
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -303,22 +326,30 @@ bool Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destF
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit between textures, StretchRect result: 0x%X.", result);
}
+
+ return gl::Error(GL_NO_ERROR);
}
else
{
return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
}
- return true;
}
-bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
{
- IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
- if (!texture)
+ gl::Error error = initialize();
+ if (error.isError())
{
- return false;
+ return error;
+ }
+
+ IDirect3DTexture9 *texture = NULL;
+ error = copySurfaceToTexture(source, sourceRect, &texture);
+ if (error.isError())
+ {
+ return error;
}
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -331,7 +362,9 @@ bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLe
setViewport(sourceRect, xoffset, yoffset);
setCommonBlitState();
- if (setFormatConvertShaders(destFormat))
+
+ error = setFormatConvertShaders(destFormat);
+ if (!error.isError())
{
render();
}
@@ -340,12 +373,16 @@ bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLe
restoreState();
- return true;
+ return error;
}
-bool Blit9::setFormatConvertShaders(GLenum destFormat)
+gl::Error Blit9::setFormatConvertShaders(GLenum destFormat)
{
- bool okay = setVertexShader(SHADER_VS_STANDARD);
+ gl::Error error = setVertexShader(SHADER_VS_STANDARD);
+ if (error.isError())
+ {
+ return error;
+ }
switch (destFormat)
{
@@ -356,18 +393,18 @@ bool Blit9::setFormatConvertShaders(GLenum destFormat)
case GL_RG_EXT:
case GL_RED_EXT:
case GL_ALPHA:
- okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
+ error = setPixelShader(SHADER_PS_COMPONENTMASK);
break;
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
- okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
+ error = setPixelShader(SHADER_PS_LUMINANCE);
break;
}
- if (!okay)
+ if (error.isError())
{
- return false;
+ return error;
}
enum { X = 0, Y = 1, Z = 2, W = 3 };
@@ -463,15 +500,12 @@ bool Blit9::setFormatConvertShaders(GLenum destFormat)
mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
+gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture)
{
- if (!surface)
- {
- return NULL;
- }
+ ASSERT(surface);
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -485,7 +519,7 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for blit, result: 0x%X.", result);
}
IDirect3DSurface9 *textureSurface;
@@ -495,7 +529,7 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(texture);
- return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query surface of internal blit texture, result: 0x%X.", result);
}
mRenderer->endScene();
@@ -507,10 +541,11 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(texture);
- return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy between internal blit textures, result: 0x%X.", result);
}
- return texture;
+ *outTexture = texture;
+ return gl::Error(GL_NO_ERROR);
}
void Blit9::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
index 46a3ee1cf3..5c7a76ce05 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_BLIT9_H_
#include "common/angleutils.h"
+#include "libGLESv2/Error.h"
#include <GLES2/gl2.h>
@@ -29,32 +30,33 @@ class Blit9
explicit Blit9(Renderer9 *renderer);
~Blit9();
+ gl::Error initialize();
+
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
- bool copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- bool copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+ gl::Error copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+ gl::Error copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
// source is interpreted as RGBA and destFormat specifies the desired result format. For example, if destFormat = GL_RGB, the alpha channel will be forced to 0.
- bool formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+ gl::Error formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
// 2x2 box filter sample from source to dest.
// Requires that source is RGB(A) and dest has the same format as source.
- bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+ gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
private:
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
+ bool mGeometryLoaded;
IDirect3DVertexBuffer9 *mQuadVertexBuffer;
IDirect3DVertexDeclaration9 *mQuadVertexDeclaration;
- void initGeometry();
-
- bool setFormatConvertShaders(GLenum destFormat);
+ gl::Error setFormatConvertShaders(GLenum destFormat);
- bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
- IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect);
+ gl::Error copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+ gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture);
void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset);
void setCommonBlitState();
RECT getSurfaceRect(IDirect3DSurface9 *surface) const;
@@ -74,12 +76,12 @@ class Blit9
IUnknown *mCompiledShaders[SHADER_COUNT];
template <class D3DShaderType>
- bool setShader(ShaderId source, const char *profile,
- D3DShaderType *(Renderer9::*createShader)(const DWORD *, size_t length),
- HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*));
+ gl::Error setShader(ShaderId source, const char *profile,
+ gl::Error (Renderer9::*createShader)(const DWORD *, size_t length, D3DShaderType **outShader),
+ HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*));
- bool setVertexShader(ShaderId shader);
- bool setPixelShader(ShaderId shader);
+ gl::Error setVertexShader(ShaderId shader);
+ gl::Error setPixelShader(ShaderId shader);
void render();
void saveState();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
index c02db515a2..430fe81e50 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
@@ -13,7 +13,7 @@
namespace rx
{
-Buffer9::Buffer9(rx::Renderer9 *renderer)
+Buffer9::Buffer9(Renderer9 *renderer)
: BufferD3D(),
mRenderer(renderer),
mSize(0)
@@ -41,7 +41,7 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage)
}
mSize = size;
- if (data)
+ if (data && size > 0)
{
memcpy(mMemory.data(), data, size);
}
@@ -56,9 +56,10 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage)
return gl::Error(GL_NO_ERROR);
}
-void *Buffer9::getData()
+gl::Error Buffer9::getData(const uint8_t **outData)
{
- return mMemory.data();
+ *outData = mMemory.data();
+ return gl::Error(GL_NO_ERROR);
}
gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset)
@@ -72,7 +73,7 @@ gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset)
}
mSize = std::max(mSize, offset + size);
- if (data)
+ if (data && size > 0)
{
memcpy(mMemory.data() + offset, data, size);
}
@@ -113,7 +114,7 @@ void Buffer9::markTransformFeedbackUsage()
UNREACHABLE();
}
-Renderer* Buffer9::getRenderer()
+RendererD3D *Buffer9::getRenderer()
{
return mRenderer;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
index e78182f905..c80b009738 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
@@ -20,7 +20,7 @@ class Renderer9;
class Buffer9 : public BufferD3D
{
public:
- Buffer9(rx::Renderer9 *renderer);
+ Buffer9(Renderer9 *renderer);
virtual ~Buffer9();
static Buffer9 *makeBuffer9(BufferImpl *buffer);
@@ -28,11 +28,11 @@ class Buffer9 : public BufferD3D
// BufferD3D implementation
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const { return false; }
- virtual Renderer* getRenderer();
+ RendererD3D *getRenderer() override;
// BufferImpl implementation
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
- virtual void *getData();
+ gl::Error getData(const uint8_t **outData) override;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
@@ -42,7 +42,7 @@ class Buffer9 : public BufferD3D
private:
DISALLOW_COPY_AND_ASSIGN(Buffer9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
MemoryBuffer mMemory;
size_t mSize;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
index e352a5f50a..66263fe110 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-// Fence9.cpp: Defines the rx::Fence9 class.
+// Fence9.cpp: Defines the rx::FenceNV9 class.
#include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
@@ -14,39 +14,41 @@
namespace rx
{
-Fence9::Fence9(rx::Renderer9 *renderer)
+FenceNV9::FenceNV9(Renderer9 *renderer)
+ : FenceNVImpl(),
+ mRenderer(renderer),
+ mQuery(NULL)
{
- mRenderer = renderer;
- mQuery = NULL;
}
-Fence9::~Fence9()
+FenceNV9::~FenceNV9()
{
SafeRelease(mQuery);
}
-bool Fence9::isSet() const
-{
- return mQuery != NULL;
-}
-
-void Fence9::set()
+gl::Error FenceNV9::set()
{
if (!mQuery)
{
- mQuery = mRenderer->allocateEventQuery();
- if (!mQuery)
+ gl::Error error = mRenderer->allocateEventQuery(&mQuery);
+ if (error.isError())
{
- return gl::error(GL_OUT_OF_MEMORY);
+ return error;
}
}
HRESULT result = mQuery->Issue(D3DISSUE_END);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ SafeRelease(mQuery);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to end event query, result: 0x%X.", result);
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence9::test(bool flushCommandBuffer)
+gl::Error FenceNV9::test(bool flushCommandBuffer, GLboolean *outFinished)
{
ASSERT(mQuery);
@@ -56,17 +58,34 @@ bool Fence9::test(bool flushCommandBuffer)
if (d3d9::isDeviceLostError(result))
{
mRenderer->notifyDeviceLost();
- return gl::error(GL_OUT_OF_MEMORY, true);
+ return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query.");
+ }
+ else if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result);
}
ASSERT(result == S_OK || result == S_FALSE);
-
- return (result == S_OK);
+ *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE);
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence9::hasError() const
+gl::Error FenceNV9::finishFence(GLboolean *outFinished)
{
- return mRenderer->isDeviceLost();
+ ASSERT(outFinished);
+
+ while (*outFinished != GL_TRUE)
+ {
+ gl::Error error = test(true, outFinished);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ Sleep(0);
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
index e923a2178c..d7873d5264 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-// Fence9.h: Defines the rx::Fence9 class which implements rx::FenceImpl.
+// Fence9.h: Defines the rx::FenceNV9 class which implements rx::FenceNVImpl.
#ifndef LIBGLESV2_RENDERER_FENCE9_H_
#define LIBGLESV2_RENDERER_FENCE9_H_
@@ -15,21 +15,20 @@ namespace rx
{
class Renderer9;
-class Fence9 : public FenceImpl
+class FenceNV9 : public FenceNVImpl
{
public:
- explicit Fence9(rx::Renderer9 *renderer);
- virtual ~Fence9();
+ explicit FenceNV9(Renderer9 *renderer);
+ virtual ~FenceNV9();
- bool isSet() const;
- void set();
- bool test(bool flushCommandBuffer);
- bool hasError() const;
+ gl::Error set();
+ gl::Error test(bool flushCommandBuffer, GLboolean *outFinished);
+ gl::Error finishFence(GLboolean *outFinished);
private:
- DISALLOW_COPY_AND_ASSIGN(Fence9);
+ DISALLOW_COPY_AND_ASSIGN(FenceNV9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
IDirect3DQuery9 *mQuery;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
index 18383fba78..2a06d12942 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
@@ -17,7 +17,7 @@
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Renderbuffer.h"
-
+#include "common/utilities.h"
namespace rx
{
@@ -36,15 +36,23 @@ Image9::~Image9()
SafeRelease(mSurface);
}
-void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
+gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
{
D3DSURFACE_DESC destDesc;
HRESULT result = destSurface->GetDesc(&destDesc);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the source surface description for mipmap generation, result: 0x%X.", result);
+ }
D3DSURFACE_DESC sourceDesc;
result = sourceSurface->GetDesc(&sourceDesc);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the destination surface description for mipmap generation, result: 0x%X.", result);
+ }
ASSERT(sourceDesc.Format == destDesc.Format);
ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
@@ -56,74 +64,111 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour
D3DLOCKED_RECT sourceLocked = {0};
result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface for mipmap generation, result: 0x%X.", result);
+ }
D3DLOCKED_RECT destLocked = {0};
result = destSurface->LockRect(&destLocked, NULL, 0);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ sourceSurface->UnlockRect();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the destination surface for mipmap generation, result: 0x%X.", result);
+ }
const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(sourceLocked.pBits);
uint8_t *destData = reinterpret_cast<uint8_t*>(destLocked.pBits);
- if (sourceData && destData)
- {
- d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
- destData, destLocked.Pitch, 0);
- }
+ ASSERT(sourceData && destData);
+
+ d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
+ destData, destLocked.Pitch, 0);
destSurface->UnlockRect();
sourceSurface->UnlockRect();
+
+ return gl::Error(GL_NO_ERROR);
}
Image9 *Image9::makeImage9(Image *img)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img));
- return static_cast<rx::Image9*>(img);
+ ASSERT(HAS_DYNAMIC_TYPE(Image9*, img));
+ return static_cast<Image9*>(img);
}
-void Image9::generateMipmap(Image9 *dest, Image9 *source)
+gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source)
{
- IDirect3DSurface9 *sourceSurface = source->getSurface();
- if (sourceSurface == NULL)
- return gl::error(GL_OUT_OF_MEMORY);
+ IDirect3DSurface9 *sourceSurface = NULL;
+ gl::Error error = source->getSurface(&sourceSurface);
+ if (error.isError())
+ {
+ return error;
+ }
- IDirect3DSurface9 *destSurface = dest->getSurface();
- generateMip(destSurface, sourceSurface);
+ IDirect3DSurface9 *destSurface = NULL;
+ error = dest->getSurface(&destSurface);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = generateMip(destSurface, sourceSurface);
+ if (error.isError())
+ {
+ return error;
+ }
dest->markDirty();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
+gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
{
D3DLOCKED_RECT sourceLock = {0};
D3DLOCKED_RECT destLock = {0};
- source->LockRect(&sourceLock, NULL, 0);
- dest->LockRect(&destLock, NULL, 0);
+ HRESULT result;
+
+ result = source->LockRect(&sourceLock, NULL, 0);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result);
+ }
- if (sourceLock.pBits && destLock.pBits)
+ result = dest->LockRect(&destLock, NULL, 0);
+ if (FAILED(result))
{
- D3DSURFACE_DESC desc;
- source->GetDesc(&desc);
+ source->UnlockRect();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result);
+ }
- const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
- unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
+ ASSERT(sourceLock.pBits && destLock.pBits);
- unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
- ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
- bytes <= static_cast<unsigned int>(destLock.Pitch));
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
- for(unsigned int i = 0; i < rows; i++)
- {
- memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
- }
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+ unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
- source->UnlockRect();
- dest->UnlockRect();
+ unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
+ ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
+ bytes <= static_cast<unsigned int>(destLock.Pitch));
+
+ for(unsigned int i = 0; i < rows; i++)
+ {
+ memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
}
- else UNREACHABLE();
+
+ source->UnlockRect();
+ dest->UnlockRect();
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
+bool Image9::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
{
// 3D textures are not supported by the D3D9 backend.
ASSERT(depth <= 1);
@@ -160,11 +205,11 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform
return false;
}
-void Image9::createSurface()
+gl::Error Image9::createSurface()
{
- if(mSurface)
+ if (mSurface)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
IDirect3DTexture9 *newTexture = NULL;
@@ -187,8 +232,7 @@ void Image9::createSurface()
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- ERR("Creating image surface failed.");
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create image surface, result: 0x%X.", result);
}
newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
@@ -206,35 +250,51 @@ void Image9::createSurface()
D3DLOCKED_RECT lockedRect;
result = newSurface->LockRect(&lockedRect, &entireRect, 0);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result);
+ }
d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits),
lockedRect.Pitch, 0);
result = newSurface->UnlockRect();
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock image surface, result: 0x%X.", result);
+ }
}
}
mSurface = newSurface;
mDirty = false;
mD3DPool = poolToUse;
+
+ return gl::Error(GL_NO_ERROR);
}
-HRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect)
+gl::Error Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT &rect)
{
- createSurface();
-
- HRESULT result = D3DERR_INVALIDCALL;
+ gl::Error error = createSurface();
+ if (error.isError())
+ {
+ return error;
+ }
if (mSurface)
{
- result = mSurface->LockRect(lockedRect, rect, 0);
+ HRESULT result = mSurface->LockRect(lockedRect, &rect, 0);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result);
+ }
mDirty = true;
}
- return result;
+ return gl::Error(GL_NO_ERROR);
}
void Image9::unlock()
@@ -263,26 +323,43 @@ bool Image9::isDirty() const
return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty;
}
-IDirect3DSurface9 *Image9::getSurface()
+gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface)
{
- createSurface();
+ gl::Error error = createSurface();
+ if (error.isError())
+ {
+ return error;
+ }
- return mSurface;
+ *outSurface = mSurface;
+ return gl::Error(GL_NO_ERROR);
}
-void Image9::setManagedSurface2D(TextureStorage *storage, int level)
+gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level)
{
+ IDirect3DSurface9 *surface = NULL;
TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
- setManagedSurface(storage9->getSurfaceLevel(level, false));
+ gl::Error error = storage9->getSurfaceLevel(level, false, &surface);
+ if (error.isError())
+ {
+ return error;
+ }
+ return setManagedSurface(surface);
}
-void Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level)
+gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level)
{
+ IDirect3DSurface9 *surface = NULL;
TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
- setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
+ gl::Error error = storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface);
+ if (error.isError())
+ {
+ return error;
+ }
+ return setManagedSurface(surface);
}
-void Image9::setManagedSurface(IDirect3DSurface9 *surface)
+gl::Error Image9::setManagedSurface(IDirect3DSurface9 *surface)
{
D3DSURFACE_DESC desc;
surface->GetDesc(&desc);
@@ -292,97 +369,119 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface)
{
if (mSurface)
{
- copyLockableSurfaces(surface, mSurface);
+ gl::Error error = copyLockableSurfaces(surface, mSurface);
SafeRelease(mSurface);
+ if (error.isError())
+ {
+ return error;
+ }
}
mSurface = surface;
mD3DPool = desc.Pool;
}
-}
-bool Image9::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
- ASSERT(getSurface() != NULL);
- TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
- return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
+ return gl::Error(GL_NO_ERROR);
}
-bool Image9::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region)
{
- ASSERT(getSurface() != NULL);
- TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
- return copyToSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
-}
+ gl::Error error = createSurface();
+ if (error.isError())
+ {
+ return error;
+ }
-bool Image9::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
-{
- // 3D textures are not supported by the D3D9 backend.
- UNREACHABLE();
- return false;
-}
+ IDirect3DSurface9 *destSurface = NULL;
-bool Image9::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height)
-{
- // 2D array textures are not supported by the D3D9 backend.
- UNREACHABLE();
- return false;
+ if (index.type == GL_TEXTURE_2D)
+ {
+ TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
+ gl::Error error = storage9->getSurfaceLevel(index.mipIndex, true, &destSurface);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ ASSERT(gl::IsCubemapTextureTarget(index.type));
+ TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
+ gl::Error error = storage9->getCubeMapSurface(index.type, index.mipIndex, true, &destSurface);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ error = copyToSurface(destSurface, region.x, region.y, region.width, region.height);
+ SafeRelease(destSurface);
+ return error;
}
-bool Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
ASSERT(width > 0 && height > 0);
+ ASSERT(destSurface);
- if (!destSurface)
- return false;
+ IDirect3DSurface9 *sourceSurface = NULL;
+ gl::Error error = getSurface(&sourceSurface);
+ if (error.isError())
+ {
+ return error;
+ }
- IDirect3DSurface9 *sourceSurface = getSurface();
+ ASSERT(sourceSurface && sourceSurface != destSurface);
- if (sourceSurface && sourceSurface != destSurface)
- {
- RECT rect;
- rect.left = xoffset;
- rect.top = yoffset;
- rect.right = xoffset + width;
- rect.bottom = yoffset + height;
+ RECT rect;
+ rect.left = xoffset;
+ rect.top = yoffset;
+ rect.right = xoffset + width;
+ rect.bottom = yoffset + height;
- POINT point = {rect.left, rect.top};
+ POINT point = {rect.left, rect.top};
- IDirect3DDevice9 *device = mRenderer->getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
- if (mD3DPool == D3DPOOL_MANAGED)
- {
- D3DSURFACE_DESC desc;
- sourceSurface->GetDesc(&desc);
+ if (mD3DPool == D3DPOOL_MANAGED)
+ {
+ D3DSURFACE_DESC desc;
+ sourceSurface->GetDesc(&desc);
- IDirect3DSurface9 *surf = 0;
- HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+ IDirect3DSurface9 *surf = 0;
+ HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal CreateOffscreenPlainSurface call failed, result: 0x%X.", result);
+ }
- if (SUCCEEDED(result))
- {
- copyLockableSurfaces(surf, sourceSurface);
- result = device->UpdateSurface(surf, &rect, destSurface, &point);
- ASSERT(SUCCEEDED(result));
- SafeRelease(surf);
- }
+ copyLockableSurfaces(surf, sourceSurface);
+ result = device->UpdateSurface(surf, &rect, destSurface, &point);
+ SafeRelease(surf);
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result);
}
- else
+ }
+ else
+ {
+ // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
+ HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
- HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result);
}
}
- SafeRelease(destSurface);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle.
-void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input)
+gl::Error Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input)
{
// 3D textures are not supported by the D3D9 backend.
ASSERT(zoffset == 0 && depth == 1);
@@ -400,10 +499,10 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
};
D3DLOCKED_RECT locked;
- HRESULT result = lock(&locked, &lockRect);
- if (FAILED(result))
+ gl::Error error = lock(&locked, lockRect);
+ if (error.isError())
{
- return;
+ return error;
}
d3dFormatInfo.loadFunction(width, height, depth,
@@ -411,10 +510,12 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input)
+gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input)
{
// 3D textures are not supported by the D3D9 backend.
ASSERT(zoffset == 0 && depth == 1);
@@ -437,10 +538,10 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
};
D3DLOCKED_RECT locked;
- HRESULT result = lock(&locked, &lockRect);
- if (FAILED(result))
+ gl::Error error = lock(&locked, lockRect);
+ if (error.isError())
{
- return;
+ return error;
}
d3d9FormatInfo.loadFunction(width, height, depth,
@@ -448,33 +549,22 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock();
+
+ return gl::Error(GL_NO_ERROR);
}
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
-void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
{
+ ASSERT(source);
+
// ES3.0 only behaviour to copy into a 3d texture
ASSERT(zoffset == 0);
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *surface = NULL;
- gl::FramebufferAttachment *colorbuffer = source->getColorbuffer(0);
-
- if (colorbuffer)
- {
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
- }
-
- if (renderTarget)
- {
- surface = renderTarget->getSurface();
- }
+ RenderTarget9 *renderTarget = RenderTarget9::makeRenderTarget9(source);
- if (!surface)
- {
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY);
- }
+ IDirect3DSurface9 *surface = renderTarget->getSurface();
+ ASSERT(surface);
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -486,212 +576,200 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
if (FAILED(result))
{
- ERR("Could not create matching destination surface.");
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Could not create matching destination surface, result: 0x%X.", result);
}
result = device->GetRenderTargetData(surface, renderTargetData);
if (FAILED(result))
{
- ERR("GetRenderTargetData unexpectedly failed.");
SafeRelease(renderTargetData);
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "GetRenderTargetData unexpectedly failed, result: 0x%X.", result);
}
- RECT sourceRect = {x, y, x + width, y + height};
- RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
+ int width = sourceArea.width;
+ int height = sourceArea.height;
+
+ RECT sourceRect = { sourceArea.x, sourceArea.y, sourceArea.x + width, sourceArea.y + height };
+ RECT destRect = { xoffset, yoffset, xoffset + width, yoffset + height };
D3DLOCKED_RECT sourceLock = {0};
result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
if (FAILED(result))
{
- ERR("Failed to lock the source surface (rectangle might be invalid).");
SafeRelease(renderTargetData);
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface (rectangle might be invalid), result: 0x%X.", result);
}
D3DLOCKED_RECT destLock = {0};
- result = lock(&destLock, &destRect);
-
- if (FAILED(result))
+ gl::Error error = lock(&destLock, destRect);
+ if (error.isError())
{
- ERR("Failed to lock the destination surface (rectangle might be invalid).");
renderTargetData->UnlockRect();
SafeRelease(renderTargetData);
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return error;
}
- if (destLock.pBits && sourceLock.pBits)
- {
- unsigned char *source = (unsigned char*)sourceLock.pBits;
- unsigned char *dest = (unsigned char*)destLock.pBits;
+ ASSERT(destLock.pBits && sourceLock.pBits);
- switch (description.Format)
+ unsigned char *sourcePixels = (unsigned char*)sourceLock.pBits;
+ unsigned char *destPixels = (unsigned char*)destLock.pBits;
+
+ switch (description.Format)
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ switch (getD3DFormat())
{
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
- switch(getD3DFormat())
+ for (int y = 0; y < height; y++)
{
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A8R8G8B8:
- for(int y = 0; y < height; y++)
+ memcpy(destPixels, sourcePixels, 4 * width);
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- memcpy(dest, source, 4 * width);
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ destPixels[x] = sourcePixels[x * 4 + 2];
}
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- dest[x] = source[x * 4 + 2];
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_A8L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- dest[x * 2 + 0] = source[x * 4 + 2];
- dest[x * 2 + 1] = source[x * 4 + 3];
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ destPixels[x * 2 + 0] = sourcePixels[x * 4 + 2];
+ destPixels[x * 2 + 1] = sourcePixels[x * 4 + 3];
}
- break;
- default:
- UNREACHABLE();
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
}
break;
- case D3DFMT_R5G6B5:
- switch(getD3DFormat())
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_R5G6B5:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for (int y = 0; y < height; y++)
{
- case D3DFMT_X8R8G8B8:
- for(int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned short rgb = ((unsigned short*)source)[x];
- unsigned char red = (rgb & 0xF800) >> 8;
- unsigned char green = (rgb & 0x07E0) >> 3;
- unsigned char blue = (rgb & 0x001F) << 3;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 6);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = 0xFF;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned short rgb = ((unsigned short*)sourcePixels)[x];
+ unsigned char red = (rgb & 0xF800) >> 8;
+ unsigned char green = (rgb & 0x07E0) >> 3;
+ unsigned char blue = (rgb & 0x001F) << 3;
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 6);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = 0xFF;
}
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0xF8;
- dest[x] = red | (red >> 5);
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned char red = sourcePixels[x * 2 + 1] & 0xF8;
+ destPixels[x] = red | (red >> 5);
}
- break;
- default:
- UNREACHABLE();
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
}
break;
- case D3DFMT_A1R5G5B5:
- switch(getD3DFormat())
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_A1R5G5B5:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for (int y = 0; y < height; y++)
{
- case D3DFMT_X8R8G8B8:
- for(int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned short argb = ((unsigned short*)source)[x];
- unsigned char red = (argb & 0x7C00) >> 7;
- unsigned char green = (argb & 0x03E0) >> 2;
- unsigned char blue = (argb & 0x001F) << 3;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 5);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = 0xFF;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned short argb = ((unsigned short*)sourcePixels)[x];
+ unsigned char red = (argb & 0x7C00) >> 7;
+ unsigned char green = (argb & 0x03E0) >> 2;
+ unsigned char blue = (argb & 0x001F) << 3;
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 5);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = 0xFF;
}
- break;
- case D3DFMT_A8R8G8B8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned short argb = ((unsigned short*)source)[x];
- unsigned char red = (argb & 0x7C00) >> 7;
- unsigned char green = (argb & 0x03E0) >> 2;
- unsigned char blue = (argb & 0x001F) << 3;
- unsigned char alpha = (signed short)argb >> 15;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 5);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = alpha;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned short argb = ((unsigned short*)sourcePixels)[x];
+ unsigned char red = (argb & 0x7C00) >> 7;
+ unsigned char green = (argb & 0x03E0) >> 2;
+ unsigned char blue = (argb & 0x001F) << 3;
+ unsigned char alpha = (signed short)argb >> 15;
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 5);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = alpha;
}
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0x7C;
- dest[x] = (red << 1) | (red >> 4);
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
+ destPixels[x] = (red << 1) | (red >> 4);
}
- break;
- case D3DFMT_A8L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0x7C;
- dest[x * 2 + 0] = (red << 1) | (red >> 4);
- dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
+ destPixels[x * 2 + 0] = (red << 1) | (red >> 4);
+ destPixels[x * 2 + 1] = (signed char)sourcePixels[x * 2 + 1] >> 7;
}
- break;
- default:
- UNREACHABLE();
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
}
break;
default:
UNREACHABLE();
}
+ break;
+ default:
+ UNREACHABLE();
}
unlock();
@@ -701,6 +779,14 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
SafeRelease(surface);
mDirty = true;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage)
+{
+ // Currently unreachable, due to only being used in a D3D11-only workaround
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h
index 08d8ee3545..8cc2258859 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h
@@ -20,7 +20,6 @@ class Framebuffer;
namespace rx
{
-class Renderer;
class Renderer9;
class Image9 : public ImageD3D
@@ -31,41 +30,41 @@ class Image9 : public ImageD3D
static Image9 *makeImage9(Image *img);
- static void generateMipmap(Image9 *dest, Image9 *source);
- static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
- static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
+ static gl::Error generateMipmap(Image9 *dest, Image9 *source);
+ static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
+ static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
- virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
+ bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override;
D3DFORMAT getD3DFormat() const;
virtual bool isDirty() const;
- IDirect3DSurface9 *getSurface();
- virtual void setManagedSurface2D(TextureStorage *storage, int level);
- virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level);
- virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
- virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height);
+ virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level);
+ virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level);
+ virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
- virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input);
- virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input);
+ virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input);
+ virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input);
- virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset,GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ const gl::ImageIndex &sourceIndex, TextureStorage *source);
private:
DISALLOW_COPY_AND_ASSIGN(Image9);
- void createSurface();
- void setManagedSurface(IDirect3DSurface9 *surface);
- bool copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+ gl::Error getSurface(IDirect3DSurface9 **outSurface);
- HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
+ gl::Error createSurface();
+ gl::Error setManagedSurface(IDirect3DSurface9 *surface);
+ gl::Error copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+ gl::Error lock(D3DLOCKED_RECT *lockedRect, const RECT &rect);
void unlock();
-
+
Renderer9 *mRenderer;
D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
index d0970d6ac5..2375fcf4b0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
@@ -40,7 +40,7 @@ class IndexBuffer9 : public IndexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(IndexBuffer9);
- rx::Renderer9 *const mRenderer;
+ Renderer9 *const mRenderer;
IDirect3DIndexBuffer9 *mIndexBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
index 815fc01a9b..a3cab578be 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
@@ -15,7 +15,7 @@
namespace rx
{
-Query9::Query9(rx::Renderer9 *renderer, GLenum type)
+Query9::Query9(Renderer9 *renderer, GLenum type)
: QueryImpl(type),
mResult(GL_FALSE),
mQueryFinished(false),
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h
index 513e0ba6fd..36851c6c6c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h
@@ -18,7 +18,7 @@ class Renderer9;
class Query9 : public QueryImpl
{
public:
- Query9(rx::Renderer9 *renderer, GLenum type);
+ Query9(Renderer9 *renderer, GLenum type);
virtual ~Query9();
virtual gl::Error begin();
@@ -34,7 +34,7 @@ class Query9 : public QueryImpl
GLuint mResult;
bool mQueryFinished;
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
IDirect3DQuery9 *mQuery;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
index 13321ac8cd..53d1f752fa 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
@@ -10,115 +10,83 @@
#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
#include "libGLESv2/main.h"
namespace rx
{
+RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RenderTarget9*, target));
+ return static_cast<RenderTarget9*>(target);
+}
+
+void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ // Currently a no-op
+}
+
// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given.
-RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
+TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei samples)
+ : mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mActualFormat(internalFormat),
+ mSamples(samples),
+ mRenderTarget(surface)
{
- mRenderer = Renderer9::makeRenderer9(renderer);
- mRenderTarget = surface;
+ ASSERT(mDepth == 1);
if (mRenderTarget)
{
D3DSURFACE_DESC description;
mRenderTarget->GetDesc(&description);
- mWidth = description.Width;
- mHeight = description.Height;
- mDepth = 1;
-
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format);
- mInternalFormat = d3dFormatInfo.internalFormat;
mActualFormat = d3dFormatInfo.internalFormat;
- mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType);
}
}
-RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
+TextureRenderTarget9::~TextureRenderTarget9()
{
- mRenderer = Renderer9::makeRenderer9(renderer);
- mRenderTarget = NULL;
-
- const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
- const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat);
-
- const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
- GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+ SafeRelease(mRenderTarget);
+}
- HRESULT result = D3DERR_INVALIDCALL;
+GLsizei TextureRenderTarget9::getWidth() const
+{
+ return mWidth;
+}
- if (width > 0 && height > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
-
- bool requiresInitialization = false;
-
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
- if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
- {
- result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
- gl_d3d9::GetMultisampleType(supportedSamples),
- 0, FALSE, &mRenderTarget, NULL);
- }
- else
- {
- requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
- result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
- gl_d3d9::GetMultisampleType(supportedSamples),
- 0, FALSE, &mRenderTarget, NULL);
- }
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- gl::error(GL_OUT_OF_MEMORY);
-
- return;
- }
-
- ASSERT(SUCCEEDED(result));
-
- if (requiresInitialization)
- {
- // This format requires that the data be initialized before the render target can be used
- // Unfortunately this requires a Get call on the d3d device but it is far better than having
- // to mark the render target as lockable and copy data to the gpu.
- IDirect3DSurface9 *prevRenderTarget = NULL;
- device->GetRenderTarget(0, &prevRenderTarget);
- device->SetRenderTarget(0, mRenderTarget);
- device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
- device->SetRenderTarget(0, prevRenderTarget);
- }
- }
+GLsizei TextureRenderTarget9::getHeight() const
+{
+ return mHeight;
+}
- mWidth = width;
- mHeight = height;
- mDepth = 1;
- mInternalFormat = internalFormat;
- mSamples = supportedSamples;
- mActualFormat = d3dFormatInfo.internalFormat;
+GLsizei TextureRenderTarget9::getDepth() const
+{
+ return mDepth;
}
-RenderTarget9::~RenderTarget9()
+GLenum TextureRenderTarget9::getInternalFormat() const
{
- SafeRelease(mRenderTarget);
+ return mInternalFormat;
}
-RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
+GLenum TextureRenderTarget9::getActualFormat() const
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target));
- return static_cast<rx::RenderTarget9*>(target);
+ return mActualFormat;
}
-void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
+GLsizei TextureRenderTarget9::getSamples() const
{
- // Currently a no-op
+ return mSamples;
}
-IDirect3DSurface9 *RenderTarget9::getSurface()
+IDirect3DSurface9 *TextureRenderTarget9::getSurface()
{
// Caller is responsible for releasing the returned surface reference.
// TODO: remove the AddRef to match RenderTarget11
@@ -130,4 +98,51 @@ IDirect3DSurface9 *RenderTarget9::getSurface()
return mRenderTarget;
}
+
+SurfaceRenderTarget9::SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth)
+ : mSwapChain(swapChain),
+ mDepth(depth)
+{
+}
+
+SurfaceRenderTarget9::~SurfaceRenderTarget9()
+{
+}
+
+GLsizei SurfaceRenderTarget9::getWidth() const
+{
+ return mSwapChain->getWidth();
+}
+
+GLsizei SurfaceRenderTarget9::getHeight() const
+{
+ return mSwapChain->getHeight();
+}
+
+GLsizei SurfaceRenderTarget9::getDepth() const
+{
+ return 1;
+}
+
+GLenum SurfaceRenderTarget9::getInternalFormat() const
+{
+ return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat());
+}
+
+GLenum SurfaceRenderTarget9::getActualFormat() const
+{
+ return d3d9::GetD3DFormatInfo(d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat;
+}
+
+GLsizei SurfaceRenderTarget9::getSamples() const
+{
+ // Our EGL surfaces do not support multisampling.
+ return 0;
+}
+
+IDirect3DSurface9 *SurfaceRenderTarget9::getSurface()
+{
+ return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget());
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
index 68d7adb49e..4585697f4c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
@@ -14,28 +14,74 @@
namespace rx
{
-class Renderer;
class Renderer9;
+class SwapChain9;
class RenderTarget9 : public RenderTarget
{
public:
- RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface);
- RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples);
- virtual ~RenderTarget9();
+ RenderTarget9() { }
+ virtual ~RenderTarget9() { }
static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget);
- virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height);
+ void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override;
- IDirect3DSurface9 *getSurface();
+ virtual IDirect3DSurface9 *getSurface() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(RenderTarget9);
+};
+
+class TextureRenderTarget9 : public RenderTarget9
+{
+ public:
+ TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei samples);
+ virtual ~TextureRenderTarget9();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ IDirect3DSurface9 *getSurface() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget9);
+
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ GLenum mActualFormat;
+ GLsizei mSamples;
IDirect3DSurface9 *mRenderTarget;
+};
+
+class SurfaceRenderTarget9 : public RenderTarget9
+{
+ public:
+ SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth);
+ virtual ~SurfaceRenderTarget9();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ IDirect3DSurface9 *getSurface() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget9);
- Renderer9 *mRenderer;
+ SwapChain9 *mSwapChain;
+ bool mDepth;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index d63f9b8582..601cd24b10 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -26,6 +26,7 @@
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Texture.h"
@@ -33,10 +34,12 @@
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/State.h"
#include "libGLESv2/angletypes.h"
#include "libEGL/Display.h"
+#include "common/features.h"
#include "common/utilities.h"
#include <sstream>
@@ -44,14 +47,6 @@
// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
#define REF_RAST 0
-// The "Debug This Pixel..." feature in PIX often fails when using the
-// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
-// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file.
-#if !defined(ANGLE_ENABLE_D3D9EX)
-// Enables use of the IDirect3D9Ex interface, when available
-#define ANGLE_ENABLE_D3D9EX 1
-#endif // !defined(ANGLE_ENABLE_D3D9EX)
-
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
@@ -96,8 +91,8 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
};
-Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay)
- : Renderer(display),
+Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes)
+ : RendererD3D(display),
mDc(hDc)
{
mD3d9Module = NULL;
@@ -177,8 +172,8 @@ void Renderer9::release()
Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer));
- return static_cast<rx::Renderer9*>(renderer);
+ ASSERT(HAS_DYNAMIC_TYPE(Renderer9*, renderer));
+ return static_cast<Renderer9*>(renderer);
}
EGLint Renderer9::initialize()
@@ -202,7 +197,7 @@ EGLint Renderer9::initialize()
// Use Direct3D9Ex if available. Among other things, this version is less
// inclined to report a lost context, for example when the user switches
// desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
- if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
+ if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
{
ASSERT(mD3d9Ex);
mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
@@ -386,10 +381,13 @@ void Renderer9::initializeDevice()
mSceneStarted = false;
- ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager);
+ ASSERT(!mBlit);
mBlit = new Blit9(this);
- mVertexDataManager = new rx::VertexDataManager(this);
- mIndexDataManager = new rx::IndexDataManager(this);
+ mBlit->initialize();
+
+ ASSERT(!mVertexDataManager && !mIndexDataManager);
+ mVertexDataManager = new VertexDataManager(this);
+ mIndexDataManager = new IndexDataManager(this);
}
D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
@@ -481,68 +479,92 @@ void Renderer9::endScene()
}
}
-void Renderer9::sync(bool block)
+gl::Error Renderer9::sync(bool block)
{
- HRESULT result;
+ IDirect3DQuery9* query = NULL;
+ gl::Error error = allocateEventQuery(&query);
+ if (error.isError())
+ {
+ return error;
+ }
- IDirect3DQuery9* query = allocateEventQuery();
- if (!query)
+ HRESULT result = query->Issue(D3DISSUE_END);
+ if (FAILED(result))
{
- return;
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result);
}
- result = query->Issue(D3DISSUE_END);
- ASSERT(SUCCEEDED(result));
+ // Grab the query data once in blocking and non-blocking case
+ result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
+ if (FAILED(result))
+ {
+ if (d3d9::isDeviceLostError(result))
+ {
+ notifyDeviceLost();
+ }
+
+ freeEventQuery(query);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
+ }
- do
+ // If blocking, loop until the query completes
+ while (block && result == S_FALSE)
{
+ // Keep polling, but allow other threads to do something useful first
+ Sleep(0);
+
result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
- if(block && result == S_FALSE)
+ // explicitly check for device loss
+ // some drivers seem to return S_FALSE even if the device is lost
+ // instead of D3DERR_DEVICELOST like they should
+ if (result == S_FALSE && testDeviceLost(false))
{
- // Keep polling, but allow other threads to do something useful first
- Sleep(0);
- // explicitly check for device loss
- // some drivers seem to return S_FALSE even if the device is lost
- // instead of D3DERR_DEVICELOST like they should
- if (testDeviceLost(false))
+ result = D3DERR_DEVICELOST;
+ }
+
+ if (FAILED(result))
+ {
+ if (d3d9::isDeviceLostError(result))
{
- result = D3DERR_DEVICELOST;
+ notifyDeviceLost();
}
+
+ freeEventQuery(query);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
}
+
}
- while(block && result == S_FALSE);
freeEventQuery(query);
- if (d3d9::isDeviceLostError(result))
- {
- notifyDeviceLost();
- }
+ return gl::Error(GL_NO_ERROR);
}
-SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChain *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
- return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+ return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
}
-IDirect3DQuery9* Renderer9::allocateEventQuery()
+gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery)
{
- IDirect3DQuery9 *query = NULL;
-
if (mEventQueryPool.empty())
{
- HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, outQuery);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate event query, result: 0x%X.", result);
+ }
}
else
{
- query = mEventQueryPool.back();
+ *outQuery = mEventQueryPool.back();
mEventQueryPool.pop_back();
}
- return query;
+ return gl::Error(GL_NO_ERROR);
}
void Renderer9::freeEventQuery(IDirect3DQuery9* query)
@@ -557,14 +579,14 @@ void Renderer9::freeEventQuery(IDirect3DQuery9* query)
}
}
-IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length)
+gl::Error Renderer9::createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader)
{
- return mVertexShaderCache.create(function, length);
+ return mVertexShaderCache.create(function, length, outShader);
}
-IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length)
+gl::Error Renderer9::createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader)
{
- return mPixelShaderCache.create(function, length);
+ return mPixelShaderCache.create(function, length, outShader);
}
HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer)
@@ -604,9 +626,16 @@ QueryImpl *Renderer9::createQuery(GLenum type)
return new Query9(this, type);
}
-FenceImpl *Renderer9::createFence()
+FenceNVImpl *Renderer9::createFenceNV()
+{
+ return new FenceNV9(this);
+}
+
+FenceSyncImpl *Renderer9::createFenceSync()
{
- return new Fence9(this);
+ // Renderer9 doesn't support ES 3.0 and its sync objects.
+ UNREACHABLE();
+ return NULL;
}
TransformFeedbackImpl* Renderer9::createTransformFeedback()
@@ -620,12 +649,12 @@ bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const
return false;
}
-bool Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
+gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
// Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3.
UNREACHABLE();
- return false;
+ return gl::Error(GL_INVALID_OPERATION);
}
gl::Error Renderer9::generateSwizzle(gl::Texture *texture)
@@ -635,7 +664,7 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture)
return gl::Error(GL_INVALID_OPERATION);
}
-gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
+gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState)
{
std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
@@ -645,6 +674,10 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::
int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
int d3dSampler = index + d3dSamplerOffset;
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ DWORD baseLevel = samplerState.baseLevel + textureD3D->getNativeTexture()->getTopLevel();
+
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
@@ -653,7 +686,7 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::
gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.baseLevel);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel);
if (getRendererExtensions().textureFilterAnisotropic)
{
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
@@ -684,7 +717,12 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te
if (texStorage)
{
TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage);
- d3dTexture = storage9->getBaseTexture();
+
+ gl::Error error = storage9->getBaseTexture(&d3dTexture);
+ if (error.isError())
+ {
+ return error;
+ }
}
// If we get NULL back from getBaseTexture here, something went wrong
// in the texture class and we're unexpectedly missing the d3d texture
@@ -751,7 +789,7 @@ gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask)
{
bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0;
@@ -1097,13 +1135,9 @@ bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
}
-gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer)
+gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer)
{
- if (!depthbuffer)
- {
- ERR("Unexpected null depthbuffer for depth-only FBO.");
- return NULL;
- }
+ ASSERT(depthbuffer);
GLsizei width = depthbuffer->getWidth();
GLsizei height = depthbuffer->getHeight();
@@ -1116,11 +1150,19 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme
mNullColorbufferCache[i].height == height)
{
mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU;
- return mNullColorbufferCache[i].buffer;
+ *outColorBuffer = mNullColorbufferCache[i].buffer;
+ return gl::Error(GL_NO_ERROR);
}
}
- gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
+ gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0);
+ gl::Error error = nullRenderbuffer->setStorage(width, height, GL_NONE, 0);
+ if (error.isError())
+ {
+ SafeDelete(nullRenderbuffer);
+ return error;
+ }
+
gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer);
// add nullbuffer to the cache
@@ -1139,40 +1181,40 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme
oldest->width = width;
oldest->height = height;
- return nullbuffer;
+ *outColorBuffer = nullbuffer;
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
+gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
// if there is no color attachment we must synthesize a NULL colorattachment
// to keep the D3D runtime happy. This should only be possible if depth texturing.
gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(0);
if (!attachment)
{
- attachment = getNullColorbuffer(framebuffer->getDepthbuffer());
- }
- if (!attachment)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Unable to locate renderbuffer for FBO.");
+ gl::Error error = getNullColorbuffer(framebuffer->getDepthbuffer(), &attachment);
+ if (error.isError())
+ {
+ return error;
+ }
}
+ ASSERT(attachment);
bool renderTargetChanged = false;
unsigned int renderTargetSerial = GetAttachmentSerial(attachment);
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
// Apply the render target on the device
- IDirect3DSurface9 *renderTargetSurface = NULL;
-
- RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment);
- if (renderTarget)
+ RenderTarget9 *renderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- renderTargetSurface = renderTarget->getSurface();
+ return error;
}
+ ASSERT(renderTarget);
- if (!renderTargetSurface)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
- }
+ IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface();
+ ASSERT(renderTargetSurface);
mDevice->SetRenderTarget(0, renderTargetSurface);
SafeRelease(renderTargetSurface);
@@ -1204,18 +1246,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
// Apply the depth stencil on the device
if (depthStencil)
{
- IDirect3DSurface9 *depthStencilSurface = NULL;
- rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil);
-
- if (depthStencilRenderTarget)
+ RenderTarget9 *depthStencilRenderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
+ if (error.isError())
{
- depthStencilSurface = depthStencilRenderTarget->getSurface();
+ return error;
}
+ ASSERT(depthStencilRenderTarget);
- if (!depthStencilSurface)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil pointer unexpectedly null.");
- }
+ IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface();
+ ASSERT(depthStencilSurface);
mDevice->SetDepthStencilSurface(depthStencilSurface);
SafeRelease(depthStencilSurface);
@@ -1260,17 +1300,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
- gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
+ gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
if (error.isError())
{
return error;
}
- return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw);
+ return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getCurrentProgramBinary(), instances, &mRepeatDraw);
}
// Applies the indices and element array bindings to the Direct3D 9 device
@@ -1296,7 +1335,7 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element
return gl::Error(GL_NO_ERROR);
}
-void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
+void Renderer9::applyTransformFeedbackBuffers(const gl::State& state)
{
UNREACHABLE();
}
@@ -1373,10 +1412,15 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- gl::Buffer *indexBuffer = elementArrayBuffer;
- BufferImpl *storage = indexBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+ indices = bufferData + offset;
}
unsigned int startIndex = 0;
@@ -1570,9 +1614,17 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid
if (elementArrayBuffer)
{
- BufferImpl *storage = elementArrayBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
switch (type)
@@ -1662,8 +1714,21 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
ASSERT(!transformFeedbackActive);
ASSERT(!rasterizerDiscard);
- ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
- ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+
+ ShaderExecutable *vertexExe = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *pixelExe = NULL;
+ error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
+ if (error.isError())
+ {
+ return error;
+ }
IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL);
@@ -1688,7 +1753,7 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
unsigned int programSerial = programBinary->getSerial();
if (programSerial != mAppliedProgramSerial)
{
- programBinary->dirtyAllUniforms();
+ programD3D->dirtyAllUniforms();
mDxUniformsDirty = true;
mAppliedProgramSerial = programSerial;
}
@@ -1696,10 +1761,8 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyUniforms(const gl::ProgramBinary &programBinary)
+gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
{
- const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms();
-
for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
gl::LinkedUniform *targetUniform = uniformArray[uniformIndex];
@@ -1797,7 +1860,7 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v
applyUniformnfv(targetUniform, (GLfloat*)vector);
}
-gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
{
if (clearParams.colorClearType != GL_FLOAT)
{
@@ -2219,7 +2282,7 @@ bool Renderer9::isRemovedDeviceResettable() const
{
bool success = false;
-#ifdef ANGLE_ENABLE_D3D9EX
+#if ANGLE_D3D9EX == ANGLE_ENABLED
IDirect3D9Ex *d3d9Ex = NULL;
typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
@@ -2330,82 +2393,6 @@ int Renderer9::getMaxSwapInterval() const
return mMaxSwapInterval;
}
-bool Renderer9::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source)
-{
- bool result = false;
-
- if (source && dest)
- {
- TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source);
- TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest);
-
- int levels = source9->getLevelCount();
- for (int i = 0; i < levels; ++i)
- {
- IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false);
- IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false);
-
- result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
-
- SafeRelease(srcSurf);
- SafeRelease(dstSurf);
-
- if (!result)
- {
- return false;
- }
- }
- }
-
- return result;
-}
-
-bool Renderer9::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source)
-{
- bool result = false;
-
- if (source && dest)
- {
- TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source);
- TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest);
- int levels = source9->getLevelCount();
- for (int f = 0; f < 6; f++)
- {
- for (int i = 0; i < levels; i++)
- {
- IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
- IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
-
- result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
-
- SafeRelease(srcSurf);
- SafeRelease(dstSurf);
-
- if (!result)
- {
- return false;
- }
- }
- }
- }
-
- return result;
-}
-
-bool Renderer9::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source)
-{
- // 3D textures are not available in the D3D9 backend.
- UNREACHABLE();
- return false;
-}
-
-bool Renderer9::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source)
-{
- // 2D array textures are not supported by the D3D9 backend.
- UNREACHABLE();
- return false;
-}
-
D3DPOOL Renderer9::getBufferPool(DWORD usage) const
{
if (mD3d9Ex != NULL)
@@ -2423,8 +2410,8 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const
return D3DPOOL_DEFAULT;
}
-bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
{
RECT rect;
rect.left = sourceRect.x;
@@ -2435,8 +2422,8 @@ bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &s
return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level);
}
-bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
{
RECT rect;
rect.left = sourceRect.x;
@@ -2447,24 +2434,26 @@ bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle
return mBlit->copyCube(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level);
}
-bool Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
// 3D textures are not available in the D3D9 backend.
UNREACHABLE();
- return false;
+ return gl::Error(GL_INVALID_OPERATION);
}
-bool Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
// 2D array textures are not available in the D3D9 backend.
UNREACHABLE();
- return false;
+ return gl::Error(GL_INVALID_OPERATION);
}
-bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter)
+gl::Error Renderer9::blitRect(const gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter)
{
ASSERT(filter == GL_NEAREST);
@@ -2473,35 +2462,33 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
if (blitRenderTarget)
{
gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0);
- gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
- RenderTarget9 *readRenderTarget = NULL;
- RenderTarget9 *drawRenderTarget = NULL;
- IDirect3DSurface9* readSurface = NULL;
- IDirect3DSurface9* drawSurface = NULL;
+ ASSERT(readBuffer);
- if (readBuffer)
- {
- readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer);
- }
- if (drawBuffer)
+ RenderTarget9 *readRenderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
{
- drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer);
+ return error;
}
+ ASSERT(readRenderTarget);
- if (readRenderTarget)
- {
- readSurface = readRenderTarget->getSurface();
- }
- if (drawRenderTarget)
- {
- drawSurface = drawRenderTarget->getSurface();
- }
+ gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
+ ASSERT(drawBuffer);
- if (!readSurface || !drawSurface)
+ RenderTarget9 *drawRenderTarget = NULL;
+ error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawRenderTarget);
+
+ // The getSurface calls do an AddRef so save them until after no errors are possible
+ IDirect3DSurface9* readSurface = readRenderTarget->getSurface();
+ ASSERT(readSurface);
+
+ IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface();
+ ASSERT(drawSurface);
gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
@@ -2594,43 +2581,40 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
if (FAILED(result))
{
- ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
if (blitDepth || blitStencil)
{
gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer();
- gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
- RenderTarget9 *readDepthStencil = NULL;
- RenderTarget9 *drawDepthStencil = NULL;
- IDirect3DSurface9* readSurface = NULL;
- IDirect3DSurface9* drawSurface = NULL;
+ ASSERT(readBuffer);
- if (readBuffer)
- {
- readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer);
- }
- if (drawBuffer)
+ RenderTarget9 *readDepthStencil = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil);
+ if (error.isError())
{
- drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer);
+ return error;
}
+ ASSERT(readDepthStencil);
- if (readDepthStencil)
- {
- readSurface = readDepthStencil->getSurface();
- }
- if (drawDepthStencil)
- {
- drawSurface = drawDepthStencil->getSurface();
- }
+ gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
+ ASSERT(drawBuffer);
- if (!readSurface || !drawSurface)
+ RenderTarget9 *drawDepthStencil = NULL;
+ error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawDepthStencil);
+
+ // The getSurface calls do an AddRef so save them until after no errors are possible
+ IDirect3DSurface9* readSurface = readDepthStencil->getSurface();
+ ASSERT(readDepthStencil);
+
+ IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface();
+ ASSERT(drawDepthStencil);
HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
@@ -2639,38 +2623,31 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
if (FAILED(result))
{
- ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+gl::Error Renderer9::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
{
ASSERT(pack.pixelBuffer.get() == NULL);
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *surface = NULL;
gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+ ASSERT(colorbuffer);
- if (colorbuffer)
- {
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
- }
-
- if (renderTarget)
+ RenderTarget9 *renderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
{
- surface = renderTarget->getSurface();
+ return error;
}
+ ASSERT(renderTarget);
- if (!surface)
- {
- // context must be lost
- return gl::Error(GL_NO_ERROR);
- }
+ IDirect3DSurface9 *surface = renderTarget->getSurface();
+ ASSERT(surface);
D3DSURFACE_DESC desc;
surface->GetDesc(&desc);
@@ -2825,33 +2802,67 @@ gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y,
return gl::Error(GL_NO_ERROR);
}
-RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth)
+gl::Error Renderer9::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
{
SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
- IDirect3DSurface9 *surface = NULL;
- if (depth)
- {
- surface = swapChain9->getDepthStencil();
- }
- else
+ *outRT = new SurfaceRenderTarget9(swapChain9, depth);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
+{
+ const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
+
+ const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
+ GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+
+ IDirect3DSurface9 *renderTarget = NULL;
+ if (width > 0 && height > 0)
{
- surface = swapChain9->getRenderTarget();
- }
+ bool requiresInitialization = false;
+ HRESULT result = D3DERR_INVALIDCALL;
+
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ {
+ result = mDevice->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
+ gl_d3d9::GetMultisampleType(supportedSamples),
+ 0, FALSE, &renderTarget, NULL);
+ }
+ else
+ {
+ requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
+ result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
+ gl_d3d9::GetMultisampleType(supportedSamples),
+ 0, FALSE, &renderTarget, NULL);
+ }
- RenderTarget9 *renderTarget = new RenderTarget9(this, surface);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target, result: 0x%X.", result);
+ }
- return renderTarget;
-}
+ if (requiresInitialization)
+ {
+ // This format requires that the data be initialized before the render target can be used
+ // Unfortunately this requires a Get call on the d3d device but it is far better than having
+ // to mark the render target as lockable and copy data to the gpu.
+ IDirect3DSurface9 *prevRenderTarget = NULL;
+ mDevice->GetRenderTarget(0, &prevRenderTarget);
+ mDevice->SetRenderTarget(0, renderTarget);
+ mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
+ mDevice->SetRenderTarget(0, prevRenderTarget);
+ }
+ }
-RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples)
-{
- RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples);
- return renderTarget;
+ *outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples);
+ return gl::Error(GL_NO_ERROR);
}
-ShaderImpl *Renderer9::createShader(GLenum type)
+ShaderImpl *Renderer9::createShader(const gl::Data &data, GLenum type)
{
- return new ShaderD3D(type, this);
+ return new ShaderD3D(data, type, this);
}
ProgramImpl *Renderer9::createProgram()
@@ -2864,64 +2875,69 @@ void Renderer9::releaseShaderCompiler()
ShaderD3D::releaseCompiler();
}
-ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers)
+gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable)
{
// Transform feedback is not supported in ES2 or D3D9
ASSERT(transformFeedbackVaryings.size() == 0);
- ShaderExecutable9 *executable = NULL;
-
switch (type)
{
- case rx::SHADER_VERTEX:
+ case SHADER_VERTEX:
{
- IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length);
- if (vshader)
+ IDirect3DVertexShader9 *vshader = NULL;
+ gl::Error error = createVertexShader((DWORD*)function, length, &vshader);
+ if (error.isError())
{
- executable = new ShaderExecutable9(function, length, vshader);
+ return error;
}
+ *outExecutable = new ShaderExecutable9(function, length, vshader);
}
break;
- case rx::SHADER_PIXEL:
+ case SHADER_PIXEL:
{
- IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length);
- if (pshader)
+ IDirect3DPixelShader9 *pshader = NULL;
+ gl::Error error = createPixelShader((DWORD*)function, length, &pshader);
+ if (error.isError())
{
- executable = new ShaderExecutable9(function, length, pshader);
+ return error;
}
+ *outExecutable = new ShaderExecutable9(function, length, pshader);
}
break;
default:
UNREACHABLE();
- break;
+ return gl::Error(GL_INVALID_OPERATION);
}
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround)
+gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable)
{
// Transform feedback is not supported in ES2 or D3D9
ASSERT(transformFeedbackVaryings.size() == 0);
- const char *profile = NULL;
-
+ const char *profileType = NULL;
switch (type)
{
- case rx::SHADER_VERTEX:
- profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0";
+ case SHADER_VERTEX:
+ profileType = "vs";
break;
- case rx::SHADER_PIXEL:
- profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0";
+ case SHADER_PIXEL:
+ profileType = "ps";
break;
default:
UNREACHABLE();
- return NULL;
+ return gl::Error(GL_INVALID_OPERATION);
}
+ unsigned int profileMajorVersion = (getMajorShaderModel() >= 3) ? 3 : 2;
+ unsigned int profileMinorVersion = 0;
+ std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
@@ -2942,49 +2958,54 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
#endif
flags |= D3DCOMPILE_DEBUG;
-
- std::string sourcePath = getTempPath();
- std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
- writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
// Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
// Try the default flags first and if compilation fails, try some alternatives.
- const UINT extraFlags[] =
+ std::vector<CompileConfig> configs;
+ configs.push_back(CompileConfig(flags, "default" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control"));
+
+ ID3DBlob *binary = NULL;
+ std::string debugInfo;
+ gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary, &debugInfo);
+ if (error.isError())
{
- flags,
- flags | D3DCOMPILE_AVOID_FLOW_CONTROL,
- flags | D3DCOMPILE_PREFER_FLOW_CONTROL
- };
+ return error;
+ }
- const static char *extraFlagNames[] =
+ // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL
+ // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK.
+ if (!binary)
{
- "default",
- "avoid flow control",
- "prefer flow control"
- };
+ *outExectuable = NULL;
+ return gl::Error(GL_NO_ERROR);
+ }
- int attempts = ArraySize(extraFlags);
+ error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
+ transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
- ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
- if (!binary)
+ SafeRelease(binary);
+ if (error.isError())
{
- return NULL;
+ return error;
}
- ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
- transformFeedbackVaryings, separatedOutputBuffers);
- SafeRelease(binary);
+ if (!debugInfo.empty())
+ {
+ (*outExectuable)->appendDebugInfo(debugInfo);
+ }
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-rx::UniformStorage *Renderer9::createUniformStorage(size_t storageSize)
+UniformStorage *Renderer9::createUniformStorage(size_t storageSize)
{
return new UniformStorage(storageSize);
}
-bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
+gl::Error Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
{
return mBlit->boxFilter(source, dest);
}
@@ -3006,41 +3027,40 @@ D3DPOOL Renderer9::getTexturePool(DWORD usage) const
return D3DPOOL_DEFAULT;
}
-bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
+gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
{
- if (source && dest)
- {
- HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
+ ASSERT(source && dest);
- if (fromManaged)
- {
- D3DSURFACE_DESC desc;
- source->GetDesc(&desc);
+ HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
- IDirect3DSurface9 *surf = 0;
- result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+ if (fromManaged)
+ {
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
- if (SUCCEEDED(result))
- {
- Image9::copyLockableSurfaces(surf, source);
- result = mDevice->UpdateSurface(surf, NULL, dest, NULL);
- SafeRelease(surf);
- }
- }
- else
- {
- endScene();
- result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
- }
+ IDirect3DSurface9 *surf = 0;
+ result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
- if (FAILED(result))
+ if (SUCCEEDED(result))
{
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return false;
+ Image9::copyLockableSurfaces(surf, source);
+ result = mDevice->UpdateSurface(surf, NULL, dest, NULL);
+ SafeRelease(surf);
}
}
+ else
+ {
+ endScene();
+ result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
+ }
- return true;
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit internal texture, result: 0x%X.", result);
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
Image *Renderer9::createImage()
@@ -3048,11 +3068,11 @@ Image *Renderer9::createImage()
return new Image9();
}
-void Renderer9::generateMipmap(Image *dest, Image *src)
+gl::Error Renderer9::generateMipmap(Image *dest, Image *src)
{
Image9 *src9 = Image9::makeImage9(src);
Image9 *dst9 = Image9::makeImage9(dest);
- Image9::generateMipmap(dst9, src9);
+ return Image9::generateMipmap(dst9, src9);
}
TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain)
@@ -3099,6 +3119,19 @@ TextureImpl *Renderer9::createTexture(GLenum target)
return NULL;
}
+RenderbufferImpl *Renderer9::createRenderbuffer()
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ return renderbuffer;
+}
+
+RenderbufferImpl *Renderer9::createRenderbuffer(SwapChain *swapChain, bool depth)
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ renderbuffer->setStorage(swapChain, depth);
+ return renderbuffer;
+}
+
bool Renderer9::getLUID(LUID *adapterLuid) const
{
adapterLuid->HighPart = 0;
@@ -3113,7 +3146,7 @@ bool Renderer9::getLUID(LUID *adapterLuid) const
return false;
}
-rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
+VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
{
return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType;
}
@@ -3128,4 +3161,9 @@ void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCa
d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, outExtensions);
}
+Workarounds Renderer9::generateWorkarounds() const
+{
+ return d3d9::GenerateWorkarounds();
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index dd5f30268a..10d2fb11e8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -11,10 +11,10 @@
#include "common/angleutils.h"
#include "common/mathutil.h"
-#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
#include "libGLESv2/renderer/d3d/d3d9/ShaderCache.h"
#include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/RenderTarget.h"
namespace gl
@@ -22,6 +22,11 @@ namespace gl
class FramebufferAttachment;
}
+namespace egl
+{
+class AttributeMap;
+}
+
namespace rx
{
class VertexDataManager;
@@ -31,10 +36,10 @@ class StaticIndexBufferInterface;
struct TranslatedAttribute;
class Blit9;
-class Renderer9 : public Renderer
+class Renderer9 : public RendererD3D
{
public:
- Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay);
+ Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes);
virtual ~Renderer9();
static Renderer9 *makeRenderer9(Renderer *renderer);
@@ -48,27 +53,27 @@ class Renderer9 : public Renderer
void startScene();
void endScene();
- virtual void sync(bool block);
+ virtual gl::Error sync(bool block);
- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
- IDirect3DQuery9* allocateEventQuery();
+ gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery);
void freeEventQuery(IDirect3DQuery9* query);
// resource creation
- IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length);
- IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length);
+ gl::Error createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader);
+ gl::Error createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader);
HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer);
virtual gl::Error generateSwizzle(gl::Texture *texture);
- virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask);
+ gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
@@ -76,35 +81,35 @@ class Renderer9 : public Renderer
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
bool ignoreViewport);
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer);
+ gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
- virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary);
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
- virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances);
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
- virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
+ virtual void applyTransformFeedbackBuffers(const gl::State& state);
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
- virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+ gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
virtual void markAllStateDirty();
// lost device
- void notifyDeviceLost();
- virtual bool isDeviceLost();
- virtual bool testDeviceLost(bool notify);
- virtual bool testDeviceResettable();
+ void notifyDeviceLost() override;
+ bool isDeviceLost() override;
+ bool testDeviceLost(bool notify) override;
+ bool testDeviceResettable() override;
+
+ DWORD getAdapterVendor() const override;
+ std::string getRendererDescription() const override;
+ GUID getAdapterIdentifier() const override;
IDirect3DDevice9 *getDevice() { return mDevice; }
- virtual DWORD getAdapterVendor() const;
- virtual std::string getRendererDescription() const;
- virtual GUID getAdapterIdentifier() const;
virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const;
@@ -119,47 +124,45 @@ class Renderer9 : public Renderer
virtual int getMaxSwapInterval() const;
// Pixel operations
- virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source);
-
- virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
- virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+ virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter);
+ gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter) override;
- virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
// RenderTarget creation
- virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
- virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples);
+ virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
// Shader creation
- virtual ShaderImpl *createShader(GLenum type);
+ virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
virtual ProgramImpl *createProgram();
// Shader operations
- virtual void releaseShaderCompiler();
- virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers);
- virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround);
+ void releaseShaderCompiler() override;
+ virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable);
+ virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable);
virtual UniformStorage *createUniformStorage(size_t storageSize);
// Image operations
virtual Image *createImage();
- virtual void generateMipmap(Image *dest, Image *source);
+ gl::Error generateMipmap(Image *dest, Image *source) override;
virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
@@ -169,6 +172,10 @@ class Renderer9 : public Renderer
// Texture creation
virtual TextureImpl *createTexture(GLenum target);
+ // Renderbuffer creation
+ virtual RenderbufferImpl *createRenderbuffer();
+ virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
+
// Buffer creation
virtual BufferImpl *createBuffer();
virtual VertexBuffer *createVertexBuffer();
@@ -179,29 +186,33 @@ class Renderer9 : public Renderer
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type);
- virtual FenceImpl *createFence();
+ virtual FenceNVImpl *createFenceNV();
+ virtual FenceSyncImpl *createFenceSync();
// Transform Feedback creation
virtual TransformFeedbackImpl* createTransformFeedback();
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
- virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
// D3D9-renderer specific methods
- bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+ gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
D3DPOOL getTexturePool(DWORD usage) const;
virtual bool getLUID(LUID *adapterLuid) const;
- virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
+ virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
+ gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
+
private:
DISALLOW_COPY_AND_ASSIGN(Renderer9);
- virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const;
+ void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override;
+ Workarounds generateWorkarounds() const override;
void release();
@@ -214,8 +225,7 @@ class Renderer9 : public Renderer
gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB);
- bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
- gl::FramebufferAttachment *getNullColorbuffer(gl::FramebufferAttachment *depthbuffer);
+ gl::Error getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer);
D3DPOOL getBufferPool(DWORD usage) const;
@@ -263,7 +273,7 @@ class Renderer9 : public Renderer
unsigned int mAppliedStencilbufferSerial;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
- rx::RenderTarget::Desc mRenderTargetDesc;
+ RenderTarget::Desc mRenderTargetDesc;
unsigned int mCurStencilSize;
unsigned int mCurDepthSize;
@@ -310,8 +320,8 @@ class Renderer9 : public Renderer
IDirect3DPixelShader9 *mAppliedPixelShader;
unsigned int mAppliedProgramSerial;
- rx::dx_VertexConstants mVertexConstants;
- rx::dx_PixelConstants mPixelConstants;
+ dx_VertexConstants mVertexConstants;
+ dx_PixelConstants mPixelConstants;
bool mDxUniformsDirty;
// A pool of event queries that are currently unused.
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
index 2ad3022839..6d7d2d648f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
@@ -10,6 +10,8 @@
#ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_
#define LIBGLESV2_RENDERER_SHADER_CACHE_H_
+#include "libGLESv2/Error.h"
+
#include "common/debug.h"
#include <cstddef>
@@ -37,21 +39,22 @@ class ShaderCache
mDevice = device;
}
- ShaderObject *create(const DWORD *function, size_t length)
+ gl::Error create(const DWORD *function, size_t length, ShaderObject **outShaderObject)
{
std::string key(reinterpret_cast<const char*>(function), length);
typename Map::iterator it = mMap.find(key);
if (it != mMap.end())
{
it->second->AddRef();
- return it->second;
+ *outShaderObject = it->second;
+ return gl::Error(GL_NO_ERROR);
}
ShaderObject *shader;
HRESULT result = createShader(function, &shader);
if (FAILED(result))
{
- return NULL;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader, result: 0x%X.", result);
}
// Random eviction policy.
@@ -64,7 +67,8 @@ class ShaderCache
shader->AddRef();
mMap[key] = shader;
- return shader;
+ *outShaderObject = shader;
+ return gl::Error(GL_NO_ERROR);
}
void clear()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
index 0aeaabb1ca..95eb1a4371 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
@@ -11,12 +11,15 @@
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "common/features.h"
+
namespace rx
{
-SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
- : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+ : mRenderer(renderer),
+ SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
{
mSwapChain = NULL;
mBackBuffer = NULL;
@@ -41,7 +44,7 @@ void SwapChain9::release()
SafeRelease(mRenderTarget);
SafeRelease(mOffscreenTexture);
- if (mWindow)
+ if (mNativeWindow.getNativeWindow())
{
mShareHandle = NULL;
}
@@ -49,7 +52,7 @@ void SwapChain9::release()
static DWORD convertInterval(EGLint interval)
{
-#ifdef ANGLE_FORCE_VSYNC_OFF
+#if ANGLE_VSYNC == ANGLE_DISABLED
return D3DPRESENT_INTERVAL_IMMEDIATE;
#else
switch(interval)
@@ -95,7 +98,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
SafeRelease(mDepthStencil);
HANDLE *pShareHandle = NULL;
- if (!mWindow && mRenderer->getShareHandleSupport())
+ if (!mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport())
{
pShareHandle = &mShareHandle;
}
@@ -152,7 +155,8 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat);
- if (mWindow)
+ EGLNativeWindowType window = mNativeWindow.getNativeWindow();
+ if (window)
{
D3DPRESENT_PARAMETERS presentParameters = {0};
presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat;
@@ -160,7 +164,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat;
presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0;
- presentParameters.hDeviceWindow = mWindow;
+ presentParameters.hDeviceWindow = window;
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
presentParameters.PresentationInterval = convertInterval(swapInterval);
@@ -203,7 +207,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
ASSERT(SUCCEEDED(result));
- InvalidateRect(mWindow, NULL, FALSE);
+ InvalidateRect(window, NULL, FALSE);
}
if (mDepthBufferFormat != GL_NONE)
@@ -238,7 +242,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
}
// parameters should be validated/clamped by caller
-EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint)
+EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
@@ -379,8 +383,8 @@ IDirect3DTexture9 *SwapChain9::getOffscreenTexture()
SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain));
- return static_cast<rx::SwapChain9*>(swapChain);
+ ASSERT(HAS_DYNAMIC_TYPE(SwapChain9*, swapChain));
+ return static_cast<SwapChain9*>(swapChain);
}
void SwapChain9::recreate()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
index 4d756f80d1..cb33bfbc0c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
@@ -19,19 +19,22 @@ class Renderer9;
class SwapChain9 : public SwapChain
{
public:
- SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+ SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain9();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint);
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
virtual IDirect3DTexture9 *getOffscreenTexture();
+ EGLint getWidth() const { return mWidth; }
+ EGLint getHeight() const { return mHeight; }
+
static SwapChain9 *makeSwapChain9(SwapChain *swapChain);
private:
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
index f44e33db18..0ff4fd3b0f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -20,8 +20,13 @@
namespace rx
{
-TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage)
+TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage)
: mTopLevel(0),
+ mMipLevels(0),
+ mTextureWidth(0),
+ mTextureHeight(0),
+ mInternalFormat(GL_NONE),
+ mTextureFormat(D3DFMT_UNKNOWN),
mRenderer(Renderer9::makeRenderer9(renderer)),
mD3DUsage(usage),
mD3DPool(mRenderer->getTexturePool(usage))
@@ -84,44 +89,52 @@ int TextureStorage9::getTopLevel() const
int TextureStorage9::getLevelCount() const
{
- return getBaseTexture() ? (getBaseTexture()->GetLevelCount() - getTopLevel()) : 0;
+ return mMipLevels - mTopLevel;
}
-TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain)
+gl::Error TextureStorage9::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
+{
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain)
: TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
{
IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
mTexture = surfaceTexture;
+ mMipLevels = surfaceTexture->GetLevelCount();
+
+ mInternalFormat = swapchain->GetBackBufferInternalFormat();
+
+ D3DSURFACE_DESC surfaceDesc;
+ surfaceTexture->GetLevelDesc(0, &surfaceDesc);
+ mTextureWidth = surfaceDesc.Width;
+ mTextureHeight = surfaceDesc.Height;
+ mTextureFormat = surfaceDesc.Format;
+
mRenderTarget = NULL;
- initializeRenderTarget();
initializeSerials(1, 1);
}
-TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
: TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
{
mTexture = NULL;
mRenderTarget = NULL;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
- const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
- d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
- UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
- HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
+ mInternalFormat = internalformat;
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- gl::error(GL_OUT_OF_MEMORY);
- }
- }
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
+
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mMipLevels = mTopLevel + levels;
- initializeRenderTarget();
initializeSerials(getLevelCount(), 1);
}
@@ -139,104 +152,168 @@ TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *s
// Increments refcount on surface.
// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty)
+gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface)
{
- IDirect3DSurface9 *surface = NULL;
+ IDirect3DBaseTexture9 *baseTexture = NULL;
+ gl::Error error = getBaseTexture(&baseTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DTexture9 *texture = static_cast<IDirect3DTexture9*>(baseTexture);
- if (mTexture)
+ HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface);
+
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- HRESULT result = mTexture->GetSurfaceLevel(level + mTopLevel, &surface);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result);
+ }
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level + mTopLevel != 0 && isManaged() && dirty)
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level + mTopLevel != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(NULL);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTarget **outRT)
+{
+ if (!mRenderTarget && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+ gl::Error error = getSurfaceLevel(0, false, &surface);
+ if (error.isError())
{
- mTexture->AddDirtyRect(NULL);
+ return error;
}
+
+ mRenderTarget = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0);
}
- return surface;
+ ASSERT(outRT);
+ *outRT = mRenderTarget;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/)
+gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- return mRenderTarget;
+ IDirect3DSurface9 *upper = NULL;
+ gl::Error error = getSurfaceLevel(sourceIndex.mipIndex, false, &upper);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DSurface9 *lower = NULL;
+ error = getSurfaceLevel(destIndex.mipIndex, true, &lower);
+ if (error.isError())
+ {
+ SafeRelease(upper);
+ return error;
+ }
+
+ ASSERT(upper && lower);
+ error = mRenderer->boxFilter(upper, lower);
+
+ SafeRelease(upper);
+ SafeRelease(lower);
+
+ return error;
}
-void TextureStorage9_2D::generateMipmaps()
+gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
{
- // Base level must already be defined
-
- for (int level = 1; level < getLevelCount(); level++)
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
- IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
- IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+ ASSERT(mMipLevels > 0);
- if (upper != NULL && lower != NULL)
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateTexture(mTextureWidth, mTextureHeight, mMipLevels, getUsage(), mTextureFormat,
+ getPool(), &mTexture, NULL);
+
+ if (FAILED(result))
{
- mRenderer->boxFilter(upper, lower);
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D storage texture, result: 0x%X.", result);
}
-
- SafeRelease(upper);
- SafeRelease(lower);
}
-}
-IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const
-{
- return mTexture;
+ *outTexture = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage9_2D::initializeRenderTarget()
+gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage)
{
- ASSERT(mRenderTarget == NULL);
+ ASSERT(destStorage);
+
+ TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(destStorage);
- if (mTexture != NULL && isRenderTarget())
+ int levels = getLevelCount();
+ for (int i = 0; i < levels; ++i)
{
- IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
+ IDirect3DSurface9 *srcSurf = NULL;
+ gl::Error error = getSurfaceLevel(i, false, &srcSurf);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderTarget = new RenderTarget9(mRenderer, surface);
+ IDirect3DSurface9 *dstSurf = NULL;
+ error = dest9->getSurfaceLevel(i, true, &dstSurf);
+ if (error.isError())
+ {
+ SafeRelease(srcSurf);
+ return error;
+ }
+
+ error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
+
+ SafeRelease(srcSurf);
+ SafeRelease(dstSurf);
+
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
: TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
{
mTexture = NULL;
- for (int i = 0; i < 6; ++i)
+ for (int i = 0; i < CUBE_FACE_COUNT; ++i)
{
mRenderTarget[i] = NULL;
}
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
- int height = size;
- const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
- d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
- UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
+ mInternalFormat = internalformat;
- HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- gl::error(GL_OUT_OF_MEMORY);
- }
- }
+ int height = size;
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mMipLevels = mTopLevel + levels;
- initializeRenderTarget();
- initializeSerials(getLevelCount() * 6, 6);
+ initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
TextureStorage9_Cube::~TextureStorage9_Cube()
{
SafeRelease(mTexture);
- for (int i = 0; i < 6; ++i)
+ for (int i = 0; i < CUBE_FACE_COUNT; ++i)
{
SafeDelete(mRenderTarget[i]);
}
@@ -250,74 +327,146 @@ TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStor
// Increments refcount on surface.
// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
+gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface)
{
- IDirect3DSurface9 *surface = NULL;
+ IDirect3DBaseTexture9 *baseTexture = NULL;
+ gl::Error error = getBaseTexture(&baseTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DCubeTexture9 *texture = static_cast<IDirect3DCubeTexture9*>(baseTexture);
- if (mTexture)
+ D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
+ HRESULT result = texture->GetCubeMapSurface(face, level + mTopLevel, outSurface);
+
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
- HRESULT result = mTexture->GetCubeMapSurface(face, level + mTopLevel, &surface);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result);
+ }
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level != 0 && isManaged() && dirty)
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(face, NULL);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+{
+ ASSERT(outRT);
+ ASSERT(index.mipIndex == 0);
+ ASSERT(index.layerIndex >= 0 && index.layerIndex < CUBE_FACE_COUNT);
+
+ if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+ gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, 0, false, &surface);
+ if (error.isError())
{
- mTexture->AddDirtyRect(face, NULL);
+ return error;
}
+
+ mRenderTarget[index.layerIndex] = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0);
}
- return surface;
+ *outRT = mRenderTarget[index.layerIndex];
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- return mRenderTarget[index.layerIndex];
+ IDirect3DSurface9 *upper = NULL;
+ gl::Error error = getCubeMapSurface(sourceIndex.type, sourceIndex.mipIndex, false, &upper);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DSurface9 *lower = NULL;
+ error = getCubeMapSurface(destIndex.type, destIndex.mipIndex, true, &lower);
+ if (error.isError())
+ {
+ SafeRelease(upper);
+ return error;
+ }
+
+ ASSERT(upper && lower);
+ error = mRenderer->boxFilter(upper, lower);
+
+ SafeRelease(upper);
+ SafeRelease(lower);
+
+ return error;
}
-void TextureStorage9_Cube::generateMipmaps()
+gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
{
- // Base level must already be defined
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
- for (int level = 1; level < getLevelCount(); level++)
- {
- IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false);
- IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true);
+ ASSERT(mMipLevels > 0);
+ ASSERT(mTextureWidth == mTextureHeight);
- if (upper != NULL && lower != NULL)
- {
- mRenderer->boxFilter(upper, lower);
- }
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateCubeTexture(mTextureWidth, mMipLevels, getUsage(), mTextureFormat, getPool(),
+ &mTexture, NULL);
- SafeRelease(upper);
- SafeRelease(lower);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube storage texture, result: 0x%X.", result);
}
}
-}
-IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const
-{
- return mTexture;
+ *outTexture = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage9_Cube::initializeRenderTarget()
+gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage)
{
- if (mTexture != NULL && isRenderTarget())
- {
- IDirect3DSurface9 *surface = NULL;
+ ASSERT(destStorage);
+
+ TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(destStorage);
- for (int i = 0; i < 6; ++i)
+ int levels = getLevelCount();
+ for (int f = 0; f < CUBE_FACE_COUNT; f++)
+ {
+ for (int i = 0; i < levels; i++)
{
- ASSERT(mRenderTarget[i] == NULL);
+ IDirect3DSurface9 *srcSurf = NULL;
+ gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf);
+ if (error.isError())
+ {
+ return error;
+ }
- surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
+ IDirect3DSurface9 *dstSurf = NULL;
+ error = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf);
+ if (error.isError())
+ {
+ SafeRelease(srcSurf);
+ return error;
+ }
+
+ error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
- mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
+ SafeRelease(srcSurf);
+ SafeRelease(dstSurf);
+
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-} \ No newline at end of file
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
index e698c7dd56..da0e1f2f18 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
@@ -33,20 +33,28 @@ class TextureStorage9 : public TextureStorage
D3DPOOL getPool() const;
DWORD getUsage() const;
- virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
- virtual void generateMipmaps() = 0;
+ virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
virtual int getLevelCount() const;
+ virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
+
protected:
int mTopLevel;
+ size_t mMipLevels;
+ size_t mTextureWidth;
+ size_t mTextureHeight;
+ GLenum mInternalFormat;
+ D3DFORMAT mTextureFormat;
+
Renderer9 *mRenderer;
- TextureStorage9(Renderer *renderer, DWORD usage);
+ TextureStorage9(Renderer9 *renderer, DWORD usage);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage9);
@@ -58,22 +66,21 @@ class TextureStorage9 : public TextureStorage
class TextureStorage9_2D : public TextureStorage9
{
public:
- TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain);
- TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
+ TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain);
+ TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual ~TextureStorage9_2D();
static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage);
- IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
- virtual void generateMipmaps();
+ gl::Error getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D);
- void initializeRenderTarget();
-
IDirect3DTexture9 *mTexture;
RenderTarget9 *mRenderTarget;
};
@@ -81,23 +88,24 @@ class TextureStorage9_2D : public TextureStorage9
class TextureStorage9_Cube : public TextureStorage9
{
public:
- TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
+ TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
virtual ~TextureStorage9_Cube();
static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage);
- IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
- virtual void generateMipmaps();
+ gl::Error getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube);
- void initializeRenderTarget();
+ static const size_t CUBE_FACE_COUNT = 6;
IDirect3DCubeTexture9 *mTexture;
- RenderTarget9 *mRenderTarget[6];
+ RenderTarget9 *mRenderTarget[CUBE_FACE_COUNT];
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
index 66a6c64d81..791c108462 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
@@ -19,7 +19,7 @@ class Renderer9;
class VertexArray9 : public VertexArrayImpl
{
public:
- VertexArray9(rx::Renderer9 *renderer)
+ VertexArray9(Renderer9 *renderer)
: VertexArrayImpl(),
mRenderer(renderer)
{
@@ -35,7 +35,7 @@ class VertexArray9 : public VertexArrayImpl
private:
DISALLOW_COPY_AND_ASSIGN(VertexArray9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
index 4cf7779118..b90133097c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -10,14 +10,14 @@
#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
#include "libGLESv2/renderer/vertexconversion.h"
-#include "libGLESv2/renderer/BufferImpl.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/VertexAttribute.h"
#include "libGLESv2/Buffer.h"
namespace rx
{
-VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer)
+VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer)
{
mVertexBuffer = NULL;
mBufferSize = 0;
@@ -97,8 +97,14 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib
{
if (buffer)
{
- BufferImpl *storage = buffer->getImplementation();
- input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
+ BufferD3D *storage = BufferD3D::makeFromBuffer(buffer);
+ ASSERT(storage);
+ gl::Error error = storage->getData(&input);
+ if (error.isError())
+ {
+ return error;
+ }
+ input += static_cast<int>(attrib.offset);
}
else
{
@@ -203,7 +209,7 @@ gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::s
else
{
// Round up to divisor, if possible
- elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
+ elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
if (d3d9VertexInfo.outputElementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
index bdcf4bb64a..9af2b98a6e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
@@ -18,7 +18,7 @@ class Renderer9;
class VertexBuffer9 : public VertexBuffer
{
public:
- explicit VertexBuffer9(rx::Renderer9 *renderer);
+ explicit VertexBuffer9(Renderer9 *renderer);
virtual ~VertexBuffer9();
virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
@@ -39,7 +39,7 @@ class VertexBuffer9 : public VertexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
IDirect3DVertexBuffer9 *mVertexBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
index e7a91e62d6..a98b2081f3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -9,6 +9,7 @@
#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
@@ -390,8 +391,9 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
caps->maxVertexUniformBlocks = 0;
- const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 10;
- const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 8;
+ // SM3 only supports 11 output variables, with a special 12th register for PSIZE.
+ const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 9;
+ const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 7;
caps->maxVertexOutputComponents = ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3
: MAX_VERTEX_OUTPUT_VECTORS_SM2) * 4;
@@ -459,7 +461,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
!(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
!(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
- !(isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);
+ !(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);
}
else
{
@@ -531,10 +533,24 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize
*levelOffset = upsampleCount;
}
-RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT)
{
- RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
- return RenderTarget9::makeRenderTarget9(renderTarget);
+ RenderTarget *renderTarget = NULL;
+ gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ *outRT = RenderTarget9::makeRenderTarget9(renderTarget);
+ return gl::Error(GL_NO_ERROR);
+}
+
+Workarounds GenerateWorkarounds()
+{
+ Workarounds workarounds;
+ workarounds.mrtPerfWorkaround = true;
+ workarounds.setDataFasterThanImageUpload = false;
+ return workarounds;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
index b0a940e60a..9760b9735a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
@@ -12,6 +12,7 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
namespace gl
{
@@ -21,6 +22,7 @@ class FramebufferAttachment;
namespace rx
{
class RenderTarget9;
+struct Workarounds;
namespace gl_d3d9
{
@@ -74,7 +76,8 @@ inline bool isDeviceLostError(HRESULT errorCode)
}
}
-RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT);
+Workarounds GenerateWorkarounds();
}