DrawContext API change: introduce TextureDesc

This commit is contained in:
Henrik Rydgård 2017-01-16 23:43:07 +07:00
parent d2c4cbacad
commit 8654d42528
8 changed files with 119 additions and 81 deletions

View file

@ -51,9 +51,16 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *_thin3D)
: gfxCtx_(gfxCtx), thin3d(_thin3D)
{
using namespace Draw;
fbTex = thin3d->CreateTexture(LINEAR2D, DataFormat::R8G8B8A8_UNORM, 480, 272, 1, 1);
TextureDesc desc{};
desc.type = TextureType::LINEAR2D;
desc.format = DataFormat::R8G8B8A8_UNORM;
desc.width = 480;
desc.height = 272;
desc.depth = 1;
desc.mipLevels = 1;
fbTex = thin3d->CreateTexture(desc);
InputLayoutDesc desc = {
InputLayoutDesc inputDesc = {
{
{ 24, false },
},
@ -69,7 +76,7 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *_thin3D)
vdata = thin3d->CreateBuffer(24 * 4, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
idata = thin3d->CreateBuffer(sizeof(int) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA);
InputLayout *inputLayout = thin3d->CreateInputLayout(desc);
InputLayout *inputLayout = thin3d->CreateInputLayout(inputDesc);
DepthStencilState *depth = thin3d->CreateDepthStencilState({ false, false, Comparison::LESS });
BlendState *blendstateOff = thin3d->CreateBlendState({ false, 0xF });
RasterState *rasterNoCull = thin3d->CreateRasterState({});

View file

@ -77,12 +77,14 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty
}
bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type) {
using namespace Draw;
int width[16], height[16];
uint8_t *image[16] = { nullptr };
int num_levels;
int zim_flags;
Draw::DataFormat fmt;
DataFormat fmt;
if (!LoadTextureLevels(data, dataSize, type, width, height, &num_levels, &fmt, image, &zim_flags)) {
return false;
@ -96,7 +98,14 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag
if (texture_)
delete texture_;
texture_ = draw_->CreateTexture(Draw::LINEAR2D, fmt, width[0], height[0], 1, num_levels);
TextureDesc desc{};
desc.type = TextureType::LINEAR2D;
desc.format = fmt;
desc.width = width[0];
desc.height = height[0];
desc.depth = 1;
desc.mipLevels = num_levels;
texture_ = draw_->CreateTexture(desc);
for (int i = 0; i < num_levels; i++) {
if (image[i]) {
texture_->SetImageData(0, 0, 0, width[i], height[i], 1, i, width[i] * 4, image[i]);

View file

@ -279,7 +279,15 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
entry->bmWidth = (size.cx + 3) & ~3;
entry->bmHeight = (size.cy + 3) & ~3;
entry->lastUsedFrame = frameCount_;
entry->texture = thin3d_->CreateTexture(LINEAR2D, DataFormat::R4G4B4A4_UNORM, entry->bmWidth, entry->bmHeight, 1, 1);
TextureDesc desc{};
desc.type = TextureType::LINEAR2D;
desc.format = DataFormat::R4G4B4A4_UNORM;
desc.width = entry->bmWidth;
desc.height = entry->bmHeight;
desc.depth = 1;
desc.mipLevels = 1;
entry->texture = thin3d_->CreateTexture(desc);
// Convert the bitmap to a gl-compatible array of pixels.
uint16_t *bitmapData = new uint16_t[entry->bmWidth * entry->bmHeight];

View file

@ -162,7 +162,7 @@ enum ClearFlag : int {
STENCIL = 4,
};
enum TextureType : uint8_t {
enum class TextureType : uint8_t {
UNKNOWN,
LINEAR1D,
LINEAR2D,
@ -332,7 +332,6 @@ public:
class Texture : public RefCountedObject {
public:
virtual bool Create(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) = 0;
virtual void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) = 0;
virtual void AutoGenMipmaps() = 0;
virtual void Finalize() = 0; // TODO: Tidy up
@ -468,6 +467,15 @@ struct DeviceCaps {
bool dualSourceBlend;
};
struct TextureDesc {
TextureType type;
DataFormat format;
int width;
int height;
int depth;
int mipLevels;
};
class DrawContext : public RefCountedObject {
public:
virtual ~DrawContext();
@ -491,7 +499,7 @@ public:
// Resources
virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0;
virtual Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) = 0;
virtual Texture *CreateTexture(const TextureDesc &desc) = 0;
virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) = 0;
virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0;

View file

@ -31,8 +31,7 @@ public:
RasterState *CreateRasterState(const RasterStateDesc &desc) override;
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
Texture *CreateTexture() override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
Texture *CreateTexture(const TextureDesc &desc) override;
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
void BindTextures(int start, int count, Texture **textures) override;
@ -307,7 +306,25 @@ public:
D3D11RasterState *raster;
};
class D3D11ShaderModule {
class D3D11Texture : public Texture {
public:
D3D11Texture() {}
bool Create(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override;
void AutoGenMipmaps() override {}
void Finalize() override {}
};
Texture *D3D11DrawContext::CreateTexture(const TextureDesc &desc) {
D3D11Texture *tex = new D3D11Texture();
// ....
return tex;
}
class D3D11ShaderModule : public ShaderModule {
public:
std::vector<uint8_t> byteCode_;
};

View file

@ -351,15 +351,15 @@ private:
class D3D9Texture : public Texture {
public:
D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, TextureType type, DataFormat format, int width, int height, int depth, int mipLevels);
D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc);
~D3D9Texture();
bool Create(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override;
void AutoGenMipmaps() override {}
void SetToSampler(LPDIRECT3DDEVICE9 device, int sampler);
void Finalize() override {}
private:
bool Create(const TextureDesc &desc);
LPDIRECT3DDEVICE9 device_;
LPDIRECT3DDEVICE9EX deviceEx_;
TextureType type_;
@ -379,9 +379,9 @@ D3DFORMAT FormatToD3D(DataFormat fmt) {
}
}
D3D9Texture::D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, TextureType type, DataFormat format, int width, int height, int depth, int mipLevels)
: device_(device), deviceEx_(deviceEx), type_(type), tex_(NULL), volTex_(NULL), cubeTex_(NULL) {
Create(type, format, width, height, depth, mipLevels);
D3D9Texture::D3D9Texture(LPDIRECT3DDEVICE9 device, LPDIRECT3DDEVICE9EX deviceEx, const TextureDesc &desc)
: device_(device), deviceEx_(deviceEx), tex_(nullptr), volTex_(nullptr), cubeTex_(nullptr) {
Create(desc);
}
D3D9Texture::~D3D9Texture() {
@ -396,13 +396,13 @@ D3D9Texture::~D3D9Texture() {
}
}
bool D3D9Texture::Create(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) {
width_ = width;
height_ = height;
depth_ = depth;
type_ = type;
bool D3D9Texture::Create(const TextureDesc &desc) {
width_ = desc.width;
height_ = desc.height;
depth_ = desc.depth;
type_ = desc.type;
tex_ = NULL;
fmt_ = FormatToD3D(format);
fmt_ = FormatToD3D(desc.format);
HRESULT hr = E_FAIL;
D3DPOOL pool = D3DPOOL_MANAGED;
@ -411,16 +411,16 @@ bool D3D9Texture::Create(TextureType type, DataFormat format, int width, int hei
pool = D3DPOOL_DEFAULT;
usage = D3DUSAGE_DYNAMIC;
}
switch (type) {
case LINEAR1D:
case LINEAR2D:
hr = device_->CreateTexture(width, height, mipLevels, usage, fmt_, pool, &tex_, NULL);
switch (type_) {
case TextureType::LINEAR1D:
case TextureType::LINEAR2D:
hr = device_->CreateTexture(desc.width, desc.height, desc.mipLevels, usage, fmt_, pool, &tex_, NULL);
break;
case LINEAR3D:
hr = device_->CreateVolumeTexture(width, height, depth, mipLevels, usage, fmt_, pool, &volTex_, NULL);
case TextureType::LINEAR3D:
hr = device_->CreateVolumeTexture(desc.width, desc.height, desc.depth, desc.mipLevels, usage, fmt_, pool, &volTex_, NULL);
break;
case CUBE:
hr = device_->CreateCubeTexture(width, mipLevels, usage, fmt_, pool, &cubeTex_, NULL);
case TextureType::CUBE:
hr = device_->CreateCubeTexture(desc.width, desc.mipLevels, usage, fmt_, pool, &cubeTex_, NULL);
break;
}
if (FAILED(hr)) {
@ -451,7 +451,7 @@ void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int d
}
switch (type_) {
case LINEAR2D:
case TextureType::LINEAR2D:
{
D3DLOCKED_RECT rect;
if (x == 0 && y == 0) {
@ -489,16 +489,16 @@ void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int d
void D3D9Texture::SetToSampler(LPDIRECT3DDEVICE9 device, int sampler) {
switch (type_) {
case LINEAR1D:
case LINEAR2D:
case TextureType::LINEAR1D:
case TextureType::LINEAR2D:
device->SetTexture(sampler, tex_);
break;
case LINEAR3D:
case TextureType::LINEAR3D:
device->SetTexture(sampler, volTex_);
break;
case CUBE:
case TextureType::CUBE:
device->SetTexture(sampler, cubeTex_);
break;
}
@ -524,7 +524,7 @@ public:
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
Texture *CreateTexture(const TextureDesc &desc) override;
void BindTextures(int start, int count, Texture **textures) override;
void BindSamplerStates(int start, int count, SamplerState **states) override {
@ -692,8 +692,8 @@ RasterState *D3D9Context::CreateRasterState(const RasterStateDesc &desc) {
return rs;
}
Texture *D3D9Context::CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) {
D3D9Texture *tex = new D3D9Texture(device_, deviceEx_, type, format, width, height, depth, mipLevels);
Texture *D3D9Context::CreateTexture(const TextureDesc &desc) {
D3D9Texture *tex = new D3D9Texture(device_, deviceEx_, desc);
return tex;
}

View file

@ -512,7 +512,7 @@ public:
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
Texture *CreateTexture(const TextureDesc &desc) override;
void BindSamplerStates(int start, int count, SamplerState **states) override {
if (samplerStates_.size() < (size_t)(start + count)) {
@ -622,27 +622,27 @@ InputLayout *OpenGLContext::CreateInputLayout(const InputLayoutDesc &desc) {
GLuint TypeToTarget(TextureType type) {
switch (type) {
#ifndef USING_GLES2
case LINEAR1D: return GL_TEXTURE_1D;
case TextureType::LINEAR1D: return GL_TEXTURE_1D;
#endif
case LINEAR2D: return GL_TEXTURE_2D;
case LINEAR3D: return GL_TEXTURE_3D;
case CUBE: return GL_TEXTURE_CUBE_MAP;
case TextureType::LINEAR2D: return GL_TEXTURE_2D;
case TextureType::LINEAR3D: return GL_TEXTURE_3D;
case TextureType::CUBE: return GL_TEXTURE_CUBE_MAP;
#ifndef USING_GLES2
case ARRAY1D: return GL_TEXTURE_1D_ARRAY;
case TextureType::ARRAY1D: return GL_TEXTURE_1D_ARRAY;
#endif
case ARRAY2D: return GL_TEXTURE_2D_ARRAY;
case TextureType::ARRAY2D: return GL_TEXTURE_2D_ARRAY;
default: return GL_NONE;
}
}
class OpenGLTexture : public Texture, GfxResourceHolder {
public:
OpenGLTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) : tex_(0), target_(TypeToTarget(type)), format_(format), mipLevels_(mipLevels) {
OpenGLTexture(const TextureDesc &desc) : tex_(0), target_(TypeToTarget(desc.type)), format_(desc.format), mipLevels_(desc.mipLevels) {
generatedMips_ = false;
canWrap_ = true;
width_ = width;
height_ = height;
depth_ = depth;
width_ = desc.width;
height_ = desc.height;
depth_ = desc.depth;
glGenTextures(1, &tex_);
register_gl_resource_holder(this);
}
@ -651,18 +651,6 @@ public:
Destroy();
}
bool Create(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override {
generatedMips_ = false;
canWrap_ = true;
format_ = format;
target_ = TypeToTarget(type);
mipLevels_ = mipLevels;
width_ = width;
height_ = height;
depth_ = depth;
return true;
}
void Destroy() {
if (tex_) {
glDeleteTextures(1, &tex_);
@ -670,6 +658,7 @@ public:
generatedMips_ = false;
}
}
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override;
void AutoGenMipmaps() override;
@ -705,8 +694,8 @@ private:
bool canWrap_;
};
Texture *OpenGLContext::CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) {
return new OpenGLTexture(type, format, width, height, depth, mipLevels);
Texture *OpenGLContext::CreateTexture(const TextureDesc &desc) {
return new OpenGLTexture(desc);
}
void OpenGLTexture::AutoGenMipmaps() {

View file

@ -364,7 +364,7 @@ public:
Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) override;
ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize) override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
Texture *CreateTexture(const TextureDesc &desc) override;
void SetScissorRect(int left, int top, int width, int height) override;
void SetViewports(int count, Viewport *viewports) override;
@ -563,26 +563,15 @@ enum class TextureState {
class VKTexture : public Texture {
public:
VKTexture(VulkanContext *vulkan, TextureType type, DataFormat format, int width, int height, int depth, int mipLevels)
: vulkan_(vulkan), format_(format), mipLevels_(mipLevels) {
Create(type, format, width, height, depth, mipLevels);
VKTexture(VulkanContext *vulkan, const TextureDesc &desc)
: vulkan_(vulkan), format_(desc.format), mipLevels_(desc.mipLevels) {
Create(desc);
}
~VKTexture() {
Destroy();
}
bool Create(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override {
format_ = format;
mipLevels_ = mipLevels;
width_ = width;
height_ = height;
depth_ = depth;
vkTex_ = new VulkanTexture(vulkan_);
// We don't actually do anything here.
return true;
}
void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) override;
void Finalize() override {}
void AutoGenMipmaps() override {}
@ -590,6 +579,17 @@ public:
VkImageView GetImageView() { return vkTex_->GetImageView(); }
private:
bool Create(const TextureDesc &desc) {
format_ = desc.format;
mipLevels_ = desc.mipLevels;
width_ = desc.width;
height_ = desc.height;
depth_ = desc.depth;
vkTex_ = new VulkanTexture(vulkan_);
// We don't actually do anything here.
return true;
}
void Destroy() {
if (vkTex_) {
vkTex_->Destroy();
@ -940,8 +940,8 @@ InputLayout *VKContext::CreateInputLayout(const InputLayoutDesc &desc) {
return vl;
}
Texture *VKContext::CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) {
return new VKTexture(vulkan_, type, format, width, height, depth, mipLevels);
Texture *VKContext::CreateTexture(const TextureDesc &desc) {
return new VKTexture(vulkan_, desc);
}
void VKTexture::SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data) {