Skip to content

Commit

Permalink
More modern way to specify vertex data format (inputlayout)
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Dec 27, 2016
1 parent 166243e commit 1ed7f0d
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 128 deletions.
16 changes: 11 additions & 5 deletions GPU/Software/SoftGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,19 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *_thin3D)
using namespace Draw;
fbTex = thin3d->CreateTexture(LINEAR2D, DataFormat::R8G8B8A8_UNORM, 480, 272, 1, 1);

std::vector<VertexComponent> components;
components.push_back(VertexComponent("Position", SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0));
components.push_back(VertexComponent("TexCoord0", SEM_TEXCOORD0, DataFormat::R32G32_FLOAT, 12));
components.push_back(VertexComponent("Color0", SEM_COLOR0, DataFormat::R8G8B8A8_UNORM, 20));
InputLayoutDesc desc = {
{
{ 24, false },
},
{
{ 0, SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0 },
{ 0, SEM_TEXCOORD0, DataFormat::R32G32_FLOAT, 12 },
{ 0, SEM_COLOR0, DataFormat::R32G32B32_FLOAT, 20 },
},
};

ShaderModule *vshader = thin3d->GetVshaderPreset(VS_TEXTURE_COLOR_2D);
vformat = thin3d->CreateVertexFormat(components, 24, vshader);
vformat = thin3d->CreateInputLayout(desc);

vdata = thin3d->CreateBuffer(24 * 4, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
idata = thin3d->CreateBuffer(sizeof(int) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA);
Expand Down
3 changes: 2 additions & 1 deletion Windows/GPU/WindowsVulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ static VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugRep
return false;

#ifdef _WIN32
OutputDebugStringA(message.str().c_str());
std::string msg = message.str();
OutputDebugStringA(msg.c_str());
if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
if (options->breakOnError) {
DebugBreak();
Expand Down
18 changes: 11 additions & 7 deletions ext/native/gfx_es2/draw_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,18 @@ void DrawBuffer::Init(Draw::DrawContext *t3d) {
t3d_ = t3d;
inited_ = true;

std::vector<VertexComponent> components;
components.push_back(VertexComponent("Position", SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0));
components.push_back(VertexComponent("TexCoord0", SEM_TEXCOORD0, DataFormat::R32G32_FLOAT, 12));
components.push_back(VertexComponent("Color0", SEM_COLOR0, DataFormat::R8G8B8A8_UNORM, 20));

ShaderModule *vshader = t3d_->GetVshaderPreset(VS_TEXTURE_COLOR_2D);
InputLayoutDesc desc = {
{
{sizeof(Vertex), false},
},
{
{ 0, SEM_POSITION, DataFormat::R32G32B32_FLOAT, 0 },
{ 0, SEM_TEXCOORD0, DataFormat::R32G32_FLOAT, 12 },
{ 0, SEM_COLOR0, DataFormat::R8G8B8A8_UNORM, 20 },
},
};

vformat_ = t3d_->CreateVertexFormat(components, 24, vshader);
vformat_ = t3d_->CreateInputLayout(desc);
if (vformat_->RequiresBuffer()) {
vbuf_ = t3d_->CreateBuffer(MAX_VERTS * sizeof(Vertex), BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
} else {
Expand Down
29 changes: 16 additions & 13 deletions ext/native/thin3d/thin3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,18 +299,21 @@ class Texture : public RefCountedObject {
int width_, height_, depth_;
};

struct VertexComponent {
VertexComponent() : name(nullptr), type(DataFormat::UNDEFINED), semantic(255), offset(255) {}
VertexComponent(const char *name, Semantic semantic, DataFormat dataType, uint8_t offset) {
this->name = name;
this->semantic = semantic;
this->type = dataType;
this->offset = offset;
}
const char *name;
uint8_t semantic;
DataFormat type;
uint8_t offset;
struct BindingDesc {
int stride;
bool instanceRate;
};

struct AttributeDesc {
int binding;
int location; // corresponds to semantic
DataFormat format;
int offset;
};

struct InputLayoutDesc {
std::vector<BindingDesc> bindings;
std::vector<AttributeDesc> attributes;
};

class InputLayout : public RefCountedObject {
Expand Down Expand Up @@ -451,7 +454,7 @@ class DrawContext : public RefCountedObject {
virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0;
virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0;
virtual Pipeline *CreatePipeline(const PipelineDesc &desc) = 0;
virtual InputLayout *CreateVertexFormat(const std::vector<VertexComponent> &components, int stride, ShaderModule *vshader) = 0;
virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0;

virtual Texture *CreateTexture() = 0; // To be later filled in by ->LoadFromFile or similar.
virtual Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) = 0;
Expand Down
54 changes: 29 additions & 25 deletions ext/native/thin3d/thin3d_d3d9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static const int primCountDivisor[] = {
1,
};

class Thin3DDX9DepthStencilState : public DepthStencilState {
class D3D9DepthStencilState : public DepthStencilState {
public:
BOOL depthTestEnabled;
BOOL depthWriteEnabled;
Expand Down Expand Up @@ -230,24 +230,25 @@ class Thin3DDX9Buffer : public Buffer {
};


class Thin3DDX9VertexFormat : public InputLayout {
class D3D9InputLayout : public InputLayout {
public:
Thin3DDX9VertexFormat(LPDIRECT3DDEVICE9 device, const std::vector<VertexComponent> &components, int stride);
~Thin3DDX9VertexFormat() {
D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc &desc);
~D3D9InputLayout() {
if (decl_) {
decl_->Release();
}
}
int GetStride() const { return stride_; }
int GetStride(int binding) const { return stride_[binding]; }
void Apply(LPDIRECT3DDEVICE9 device) {
device->SetVertexDeclaration(decl_);
}
bool RequiresBuffer() override {
return false;
}

private:
LPDIRECT3DVERTEXDECLARATION9 decl_;
int stride_;
int stride_[4];
};

class D3D9ShaderModule : public ShaderModule {
Expand Down Expand Up @@ -460,7 +461,7 @@ class D3D9Context : public DrawContext {
RasterState *CreateRasterState(const RasterStateDesc &desc) override;
Buffer *CreateBuffer(size_t size, uint32_t usageFlags) override;
Pipeline *CreatePipeline(const PipelineDesc &desc) override;
InputLayout *CreateVertexFormat(const std::vector<VertexComponent> &components, int stride, ShaderModule *vshader) override;
InputLayout *CreateInputLayout(const InputLayoutDesc &desc) override;
Texture *CreateTexture() override;
Texture *CreateTexture(TextureType type, DataFormat format, int width, int height, int depth, int mipLevels) override;
ShaderModule *CreateShaderModule(ShaderStage stage, const char *glsl_source, const char *hlsl_source, const char *vulkan_source) override;
Expand All @@ -471,7 +472,7 @@ class D3D9Context : public DrawContext {
bs->Apply(device_);
}
void SetDepthStencilState(DepthStencilState *state) override {
Thin3DDX9DepthStencilState *bs = static_cast<Thin3DDX9DepthStencilState *>(state);
D3D9DepthStencilState *bs = static_cast<D3D9DepthStencilState *>(state);
bs->Apply(device_);
}
void SetRasterState(RasterState *state) override {
Expand Down Expand Up @@ -565,15 +566,15 @@ Pipeline *D3D9Context::CreatePipeline(const PipelineDesc &desc) {
}

DepthStencilState *D3D9Context::CreateDepthStencilState(const DepthStencilStateDesc &desc) {
Thin3DDX9DepthStencilState *ds = new Thin3DDX9DepthStencilState();
D3D9DepthStencilState *ds = new D3D9DepthStencilState();
ds->depthTestEnabled = desc.depthTestEnabled;
ds->depthWriteEnabled = desc.depthWriteEnabled;
ds->depthCompare = compareToD3D9[(int)desc.depthCompare];
return ds;
}

InputLayout *D3D9Context::CreateVertexFormat(const std::vector<VertexComponent> &components, int stride, ShaderModule *vshader) {
Thin3DDX9VertexFormat *fmt = new Thin3DDX9VertexFormat(device_, components, stride);
InputLayout *D3D9Context::CreateInputLayout(const InputLayoutDesc &desc) {
D3D9InputLayout *fmt = new D3D9InputLayout(device_, desc);
return fmt;
}

Expand Down Expand Up @@ -676,26 +677,29 @@ static int VertexDataTypeToD3DType(DataFormat type) {
}
}

Thin3DDX9VertexFormat::Thin3DDX9VertexFormat(LPDIRECT3DDEVICE9 device, const std::vector<VertexComponent> &components, int stride) : decl_(NULL) {
D3DVERTEXELEMENT9 *elements = new D3DVERTEXELEMENT9[components.size() + 1];
D3D9InputLayout::D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc &desc) : decl_(NULL) {
D3DVERTEXELEMENT9 *elements = new D3DVERTEXELEMENT9[desc.attributes.size() + 1];
size_t i;
for (i = 0; i < components.size(); i++) {
elements[i].Stream = 0;
elements[i].Offset = components[i].offset;
for (i = 0; i < desc.attributes.size(); i++) {
elements[i].Stream = desc.attributes[i].binding;
elements[i].Offset = desc.attributes[i].offset;
elements[i].Method = D3DDECLMETHOD_DEFAULT;
SemanticToD3D9UsageAndIndex(components[i].semantic, &elements[i].Usage, &elements[i].UsageIndex);
elements[i].Type = VertexDataTypeToD3DType(components[i].type);
SemanticToD3D9UsageAndIndex(desc.attributes[i].location, &elements[i].Usage, &elements[i].UsageIndex);
elements[i].Type = VertexDataTypeToD3DType(desc.attributes[i].format);
}
D3DVERTEXELEMENT9 end = D3DDECL_END();
// Zero the last one.
memcpy(&elements[i], &end, sizeof(elements[i]));

for (i = 0; i < desc.bindings.size(); i++) {
stride_[i] = desc.bindings[i].stride;
}

HRESULT hr = device->CreateVertexDeclaration(elements, &decl_);
if (FAILED(hr)) {
ELOG("Error creating vertex decl");
}
delete[] elements;
stride_ = stride;
}

Buffer *D3D9Context::CreateBuffer(size_t size, uint32_t usageFlags) {
Expand All @@ -709,9 +713,9 @@ void D3D9Pipeline::Apply(LPDIRECT3DDEVICE9 device) {

void D3D9Context::Draw(Primitive prim, InputLayout *format, Buffer *vdata, int vertexCount, int offset) {
Thin3DDX9Buffer *vbuf = static_cast<Thin3DDX9Buffer *>(vdata);
Thin3DDX9VertexFormat *fmt = static_cast<Thin3DDX9VertexFormat *>(format);
D3D9InputLayout *fmt = static_cast<D3D9InputLayout *>(format);

vbuf->BindAsVertexBuf(device_, fmt->GetStride(), offset);
vbuf->BindAsVertexBuf(device_, fmt->GetStride(9), offset);
curPipeline_->Apply(device_);
fmt->Apply(device_);
device_->DrawPrimitive(primToD3D9[(int)prim], offset, vertexCount / 3);
Expand All @@ -720,21 +724,21 @@ void D3D9Context::Draw(Primitive prim, InputLayout *format, Buffer *vdata, int v
void D3D9Context::DrawIndexed(Primitive prim, InputLayout *format, Buffer *vdata, Buffer *idata, int vertexCount, int offset) {
Thin3DDX9Buffer *vbuf = static_cast<Thin3DDX9Buffer *>(vdata);
Thin3DDX9Buffer *ibuf = static_cast<Thin3DDX9Buffer *>(idata);
Thin3DDX9VertexFormat *fmt = static_cast<Thin3DDX9VertexFormat *>(format);
D3D9InputLayout *fmt = static_cast<D3D9InputLayout *>(format);

curPipeline_->Apply(device_);
fmt->Apply(device_);
vbuf->BindAsVertexBuf(device_, fmt->GetStride(), offset);
vbuf->BindAsVertexBuf(device_, fmt->GetStride(0), offset);
ibuf->BindAsIndexBuf(device_);
device_->DrawIndexedPrimitive(primToD3D9[(int)prim], 0, 0, vertexCount, 0, vertexCount / primCountDivisor[(int)prim]);
}

void D3D9Context::DrawUP(Primitive prim, InputLayout *format, const void *vdata, int vertexCount) {
Thin3DDX9VertexFormat *fmt = static_cast<Thin3DDX9VertexFormat *>(format);
D3D9InputLayout *fmt = static_cast<D3D9InputLayout *>(format);

curPipeline_->Apply(device_);
fmt->Apply(device_);
device_->DrawPrimitiveUP(primToD3D9[(int)prim], vertexCount / 3, vdata, fmt->GetStride());
device_->DrawPrimitiveUP(primToD3D9[(int)prim], vertexCount / 3, vdata, fmt->GetStride(0));
}

static uint32_t SwapRB(uint32_t c) {
Expand Down
Loading

0 comments on commit 1ed7f0d

Please sign in to comment.