Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,491 @@
#ifdef KINC_OCULUS
#include <kinc/vr/vrinterface.h>
#include "Direct3D11.h"
#include <Kore/Graphics4/Graphics.h>
#include <kinc/log.h>
#include "OVR_CAPI_D3D.h"
#include "d3d11.h"
#include <vector>
#if _MSC_VER > 1600
#include "DirectXMath.h"
using namespace DirectX;
#else
#include "xnamath.h"
#endif //_MSC_VER > 1600
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dcompiler.lib")
using namespace Kore;
namespace {
kinc_vr_sensor_state_t sensorStates[2];
}
//------------------------------------------------------------
struct DepthBuffer {
ID3D11DepthStencilView *TexDsv;
DepthBuffer(ID3D11Device *Device, int sizeW, int sizeH, int sampleCount = 1) {
DXGI_FORMAT format = DXGI_FORMAT_D32_FLOAT;
D3D11_TEXTURE2D_DESC dsDesc;
dsDesc.Width = sizeW;
dsDesc.Height = sizeH;
dsDesc.MipLevels = 1;
dsDesc.ArraySize = 1;
dsDesc.Format = format;
dsDesc.SampleDesc.Count = sampleCount;
dsDesc.SampleDesc.Quality = 0;
dsDesc.Usage = D3D11_USAGE_DEFAULT;
dsDesc.CPUAccessFlags = 0;
dsDesc.MiscFlags = 0;
dsDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
ID3D11Texture2D *Tex;
Device->CreateTexture2D(&dsDesc, nullptr, &Tex);
Device->CreateDepthStencilView(Tex, nullptr, &TexDsv);
Tex->Release();
}
~DepthBuffer() {
TexDsv->Release();
TexDsv = nullptr;
}
};
//-----------------------------------------------------------
struct Camera {
XMVECTOR Pos;
XMVECTOR Rot;
Camera(){};
Camera(XMVECTOR *pos, XMVECTOR *rot) : Pos(*pos), Rot(*rot){};
Camera(const XMVECTOR &pos, const XMVECTOR &rot) : Pos(pos), Rot(rot){};
XMMATRIX GetViewMatrix() {
XMVECTOR forward = XMVector3Rotate(XMVectorSet(0, 0, -1, 0), Rot);
return (XMMatrixLookAtRH(Pos, XMVectorAdd(Pos, forward), XMVector3Rotate(XMVectorSet(0, 1, 0, 0), Rot)));
}
static void *operator new(std::size_t size) {
UNREFERENCED_PARAMETER(size);
return _aligned_malloc(sizeof(Camera), __alignof(Camera));
}
static void operator delete(void *p) {
_aligned_free(p);
}
};
//---------------------------------------------------------------------
struct DirectX11 {
HWND Window;
bool Running;
int WinSizeW;
int WinSizeH;
HINSTANCE hInstance;
DirectX11() : Window(nullptr), Running(false), WinSizeW(0), WinSizeH(0), hInstance(nullptr) {}
~DirectX11() {
ReleaseDevice();
CloseWindow();
}
bool InitWindow(HINSTANCE hinst, const char *title, const char *windowClassName) {
hInstance = hinst;
Running = true;
// Adjust the window size and show at InitDevice time
wchar_t wchTitle[256];
MultiByteToWideChar(CP_ACP, 0, title, -1, wchTitle, 256);
wchar_t wchClassName[256];
MultiByteToWideChar(CP_ACP, 0, windowClassName, -1, wchClassName, 256);
Window = CreateWindowW(wchClassName, wchTitle, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, 0, 0, hinst, 0);
if (!Window)
return false;
SetWindowLongPtr(Window, 0, LONG_PTR(this));
return true;
}
void CloseWindow() {
if (Window) {
Window = nullptr;
}
}
bool InitDevice(int vpW, int vpH, const LUID *pLuid, bool windowed = true, int scale = 1) {
WinSizeW = vpW;
WinSizeH = vpH;
if (scale == 0)
scale = 1;
RECT size = {0, 0, vpW / scale, vpH / scale};
AdjustWindowRect(&size, WS_OVERLAPPEDWINDOW, false);
const UINT flags = SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW;
if (!SetWindowPos(Window, nullptr, 0, 0, size.right - size.left, size.bottom - size.top, flags))
return false;
return true;
}
void SetAndClearRenderTarget(ID3D11RenderTargetView *rendertarget, DepthBuffer *depthbuffer, float R = 0, float G = 0, float B = 0, float A = 0) {
float black[] = {R, G, B, A}; // Important that alpha=0, if want pixels to be transparent, for manual layers
dx_ctx.context->OMSetRenderTargets(1, &rendertarget, (depthbuffer ? depthbuffer->TexDsv : nullptr));
dx_ctx.context->ClearRenderTargetView(rendertarget, black);
if (depthbuffer)
dx_ctx.context->ClearDepthStencilView(depthbuffer->TexDsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
}
void SetViewport(float vpX, float vpY, float vpW, float vpH) {
D3D11_VIEWPORT D3Dvp;
D3Dvp.Width = vpW;
D3Dvp.Height = vpH;
D3Dvp.MinDepth = 0;
D3Dvp.MaxDepth = 1;
D3Dvp.TopLeftX = vpX;
D3Dvp.TopLeftY = vpY;
dx_ctx.context->RSSetViewports(1, &D3Dvp);
}
void ReleaseDevice() {}
};
static DirectX11 Platform;
//---------------------------------------------------------------------
// ovrSwapTextureSet wrapper class that also maintains the render target views needed for D3D11 rendering.
struct OculusTexture {
ovrSession Session;
ovrTextureSwapChain TextureChain;
std::vector<ID3D11RenderTargetView *> TexRtv;
OculusTexture(ovrSession session, int sizeW, int sizeH, int sampleCount = 1) : Session(session), TextureChain(nullptr) {
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Width = sizeW;
desc.Height = sizeH;
desc.MipLevels = 1;
desc.SampleCount = sampleCount;
desc.MiscFlags = ovrTextureMisc_DX_Typeless | ovrTextureMisc_AutoGenerateMips;
desc.BindFlags = ovrTextureBind_DX_RenderTarget;
desc.StaticImage = ovrFalse;
ovrResult result = ovr_CreateTextureSwapChainDX(session, dx_ctx.device, &desc, &TextureChain);
int textureCount = 0;
ovr_GetTextureSwapChainLength(Session, TextureChain, &textureCount);
if (OVR_SUCCESS(result)) {
for (int i = 0; i < textureCount; ++i) {
ID3D11Texture2D *tex = nullptr;
ovr_GetTextureSwapChainBufferDX(Session, TextureChain, i, IID_PPV_ARGS(&tex));
D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtvd.ViewDimension = (sampleCount > 1) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
ID3D11RenderTargetView *rtv;
dx_ctx.device->CreateRenderTargetView(tex, &rtvd, &rtv);
TexRtv.push_back(rtv);
tex->Release();
}
}
}
~OculusTexture() {
for (int i = 0; i < (int)TexRtv.size(); ++i) {
TexRtv[i]->Release();
TexRtv[i] = nullptr;
}
if (TextureChain) {
ovr_DestroyTextureSwapChain(Session, TextureChain);
TextureChain = nullptr;
}
}
ID3D11RenderTargetView *GetRTV() {
int index = 0;
ovr_GetTextureSwapChainCurrentIndex(Session, TextureChain, &index);
return TexRtv[index];
}
void Commit() {
ovr_CommitTextureSwapChain(Session, TextureChain);
}
};
//---------------------------------------------------------------------
namespace {
// Initialize these to nullptr here to handle dx_ctx.device lost failures cleanly
ovrMirrorTexture mirrorTexture = nullptr;
OculusTexture *pEyeRenderTexture[2] = {nullptr, nullptr};
DepthBuffer *pEyeDepthBuffer[2] = {nullptr, nullptr};
ovrSizei windowSize;
long long frameIndex = 0;
int msaaRate = 4;
bool isVisible = true;
ovrSession session;
ovrHmdDesc hmdDesc;
ovrPosef EyeRenderPose[2];
double sensorSampleTime;
// Make the eye render buffers (caution if actual size < requested due to HW limits).
ovrRecti eyeRenderViewport[2];
void done() {
if (mirrorTexture)
ovr_DestroyMirrorTexture(session, mirrorTexture);
for (int eye = 0; eye < 2; ++eye) {
delete pEyeRenderTexture[eye];
delete pEyeDepthBuffer[eye];
}
Platform.ReleaseDevice();
ovr_Destroy(session);
}
void createOculusTexture() {
// Create mirror texture
ovrMirrorTextureDesc mirrorDesc;
memset(&mirrorDesc, 0, sizeof(mirrorDesc));
mirrorDesc.Width = Platform.WinSizeW;
mirrorDesc.Height = Platform.WinSizeH;
mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
mirrorDesc.MirrorOptions = ovrMirrorOption_Default;
HRESULT result = ovr_CreateMirrorTextureWithOptionsDX(session, dx_ctx.device, &mirrorDesc, &mirrorTexture);
if (!OVR_SUCCESS(result)) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to create mirror texture.");
done();
}
// Make eye render buffers
for (int eye = 0; eye < 2; ++eye) {
ovrSizei idealSize = ovr_GetFovTextureSize(session, ovrEyeType(eye), hmdDesc.DefaultEyeFov[eye], 1);
pEyeRenderTexture[eye] = new OculusTexture(session, idealSize.w, idealSize.h);
pEyeDepthBuffer[eye] = new DepthBuffer(dx_ctx.device, idealSize.w, idealSize.h);
eyeRenderViewport[eye].Pos.x = 0;
eyeRenderViewport[eye].Pos.y = 0;
eyeRenderViewport[eye].Size = idealSize;
if (!pEyeRenderTexture[eye]->TextureChain) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to create texture.");
done();
}
}
}
}
void *kinc_vr_interface_init(void *hinst, const char *title, const char *windowClassName) {
// Initializes LibOVR, and the Rift
ovrInitParams initParams = {ovrInit_RequestVersion | ovrInit_FocusAware, OVR_MINOR_VERSION, NULL, 0, 0};
ovrResult result = ovr_Initialize(&initParams);
if (!OVR_SUCCESS(result)) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to initialize libOVR.");
return (0);
}
if (!Platform.InitWindow((HINSTANCE)hinst, title, windowClassName)) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to open window.");
return (0);
}
ovrGraphicsLuid luid;
result = ovr_Create(&session, &luid);
if (!OVR_SUCCESS(result)) {
kinc_log(KINC_LOG_LEVEL_ERROR, "HMD not connected.");
return false; // TODO: retry
}
hmdDesc = ovr_GetHmdDesc(session);
// Setup Window and Graphics
// Note: the mirror window can be any size, for this sample we use 1/2 the HMD resolution
windowSize = {hmdDesc.Resolution.w / 2, hmdDesc.Resolution.h / 2};
if (!Platform.InitDevice(windowSize.w, windowSize.h, reinterpret_cast<LUID *>(&luid))) {
kinc_log(KINC_LOG_LEVEL_ERROR, "Failed to init dx_ctx.device.");
done();
}
// FloorLevel will give tracking poses where the floor height is 0
ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel);
// Return window
return Platform.Window;
}
void kinc_vr_interface_begin() {
// Call ovr_GetRenderDesc each frame to get the ovrEyeRenderDesc, as the returned values (e.g. HmdToEyeOffset) may change at runtime.
ovrEyeRenderDesc eyeRenderDesc[2];
eyeRenderDesc[0] = ovr_GetRenderDesc(session, ovrEye_Left, hmdDesc.DefaultEyeFov[0]);
eyeRenderDesc[1] = ovr_GetRenderDesc(session, ovrEye_Right, hmdDesc.DefaultEyeFov[1]);
// Get both eye poses simultaneously, with IPD offset already included.
ovrPosef HmdToEyePose[2] = {eyeRenderDesc[0].HmdToEyePose, eyeRenderDesc[1].HmdToEyePose};
ovr_GetEyePoses(session, frameIndex, ovrTrue, HmdToEyePose, EyeRenderPose, &sensorSampleTime);
}
void kinc_vr_interface_begin_render(int eye) {
if (pEyeRenderTexture[0] == nullptr || pEyeRenderTexture[1] == nullptr)
createOculusTexture();
// Clear and set up rendertarget
Platform.SetAndClearRenderTarget(pEyeRenderTexture[eye]->GetRTV(), pEyeDepthBuffer[eye]);
Platform.SetViewport((float)eyeRenderViewport[eye].Pos.x, (float)eyeRenderViewport[eye].Pos.y, (float)eyeRenderViewport[eye].Size.w,
(float)eyeRenderViewport[eye].Size.h);
}
void kinc_vr_interface_end_render(int eye) {
// Commit rendering to the swap chain
pEyeRenderTexture[eye]->Commit();
}
namespace {
kinc_matrix4x4_t convert(XMMATRIX &m) {
XMFLOAT4X4 fView;
XMStoreFloat4x4(&fView, m);
kinc_matrix4x4_t mat;
kinc_matrix4x4_set(&mat, 0, 0, fView._11);
kinc_matrix4x4_set(&mat, 0, 1, fView._12);
kinc_matrix4x4_set(&mat, 0, 2, fView._13);
kinc_matrix4x4_set(&mat, 0, 3, fView._14);
kinc_matrix4x4_set(&mat, 1, 0, fView._21);
kinc_matrix4x4_set(&mat, 1, 1, fView._22);
kinc_matrix4x4_set(&mat, 1, 2, fView._23);
kinc_matrix4x4_set(&mat, 1, 3, fView._24);
kinc_matrix4x4_set(&mat, 2, 0, fView._31);
kinc_matrix4x4_set(&mat, 2, 1, fView._32);
kinc_matrix4x4_set(&mat, 2, 2, fView._33);
kinc_matrix4x4_set(&mat, 2, 3, fView._34);
kinc_matrix4x4_set(&mat, 3, 0, fView._41);
kinc_matrix4x4_set(&mat, 3, 1, fView._42);
kinc_matrix4x4_set(&mat, 3, 2, fView._43);
kinc_matrix4x4_set(&mat, 3, 3, fView._44);
return mat;
}
}
kinc_vr_sensor_state_t kinc_vr_interface_get_sensor_state(int eye) {
kinc_vr_pose_state_t poseState;
ovrQuatf orientation = EyeRenderPose[eye].Orientation;
poseState.vrPose.orientation.x = orientation.x;
poseState.vrPose.orientation.y = orientation.y;
poseState.vrPose.orientation.z = orientation.z;
poseState.vrPose.orientation.w = orientation.w;
ovrVector3f pos = EyeRenderPose[eye].Position;
poseState.vrPose.position.x = pos.x;
poseState.vrPose.position.y = pos.y;
poseState.vrPose.position.z = pos.z;
ovrFovPort fov = hmdDesc.DefaultEyeFov[eye];
poseState.vrPose.left = fov.LeftTan;
poseState.vrPose.right = fov.RightTan;
poseState.vrPose.bottom = fov.DownTan;
poseState.vrPose.top = fov.UpTan;
// Get the pose information in XM format
XMVECTOR eyeQuat = XMVectorSet(orientation.x, orientation.y, orientation.z, orientation.w);
XMVECTOR eyePos = XMVectorSet(pos.x, pos.y, pos.z, 0);
// Get view and projection matrices for the Rift camera
Camera finalCam(eyePos, eyeQuat);
XMMATRIX view = finalCam.GetViewMatrix();
ovrMatrix4f p = ovrMatrix4f_Projection(fov, 0.2f, 1000.0f, ovrProjection_None);
XMMATRIX proj = XMMatrixSet(p.M[0][0], p.M[1][0], p.M[2][0], p.M[3][0], p.M[0][1], p.M[1][1], p.M[2][1], p.M[3][1], p.M[0][2], p.M[1][2], p.M[2][2],
p.M[3][2], p.M[0][3], p.M[1][3], p.M[2][3], p.M[3][3]);
poseState.vrPose.eye = convert(view);
kinc_matrix4x4_transpose(&poseState.vrPose.eye);
poseState.vrPose.projection = convert(proj);
kinc_matrix4x4_transpose(&poseState.vrPose.projection);
ovrSessionStatus sessionStatus;
ovr_GetSessionStatus(session, &sessionStatus);
poseState.isVisible = sessionStatus.IsVisible;
poseState.hmdPresenting = sessionStatus.HmdPresent;
poseState.hmdMounted = sessionStatus.HmdMounted;
poseState.displayLost = sessionStatus.DisplayLost;
poseState.shouldQuit = sessionStatus.ShouldQuit;
poseState.shouldRecenter = sessionStatus.ShouldRecenter;
sensorStates[eye].pose = poseState;
return sensorStates[eye];
}
kinc_vr_pose_state_t kinc_vr_interface_get_controller(int index) {
kinc_vr_pose_state_t todo;
return todo;
}
void kinc_vr_interface_warp_swap() {
// Initialize our single full screen Fov layer.
ovrLayerEyeFov ld = {};
ld.Header.Type = ovrLayerType_EyeFov;
ld.Header.Flags = 0;
if (isVisible) {
for (int eye = 0; eye < 2; ++eye) {
ld.ColorTexture[eye] = pEyeRenderTexture[eye]->TextureChain;
ld.Viewport[eye] = eyeRenderViewport[eye];
ld.Fov[eye] = hmdDesc.DefaultEyeFov[eye];
ld.RenderPose[eye] = EyeRenderPose[eye];
ld.SensorSampleTime = sensorSampleTime;
}
}
ovrLayerHeader *layers = &ld.Header;
ovrResult result = ovr_SubmitFrame(session, frameIndex, nullptr, &layers, 1);
if (!OVR_SUCCESS(result)) {
isVisible = false;
}
else {
isVisible = true;
}
frameIndex++;
// Render mirror
ID3D11Texture2D *tex = nullptr;
ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&tex));
dx_ctx.context->CopyResource(backBuffer, tex);
tex->Release();
}
void kinc_vr_interface_update_tracking_origin(kinc_tracking_origin_t origin) {
switch (origin) {
case KINC_TRACKING_ORIGIN_STAND:
ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel);
break;
case KINC_TRACKING_ORIGIN_SIT:
ovr_SetTrackingOriginType(session, ovrTrackingOrigin_EyeLevel);
break;
default:
ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel);
break;
}
}
void kinc_vr_interface_reset_hmd_pose() {
ovr_RecenterTrackingOrigin(session);
}
void kinc_vr_interface_ovr_shutdown() {
ovr_Shutdown();
}
#endif

View File

@ -0,0 +1,41 @@
#pragma once
#include <d3d11.h>
#include <dxgi.h>
#include <stdbool.h>
#define MAXIMUM_WINDOWS 16
struct dx_window {
HWND hwnd;
IDXGISwapChain *swapChain;
ID3D11Texture2D *backBuffer;
ID3D11RenderTargetView *renderTargetView;
ID3D11Texture2D *depthStencil;
ID3D11DepthStencilView *depthStencilView;
int width;
int height;
int new_width;
int new_height;
bool vsync;
int depth_bits;
int stencil_bits;
};
struct dx_context {
ID3D11Device *device;
ID3D11DeviceContext *context;
IDXGIDevice *dxgiDevice;
IDXGIAdapter *dxgiAdapter;
IDXGIFactory *dxgiFactory;
int current_window;
struct dx_window windows[MAXIMUM_WINDOWS];
};
extern struct dx_context dx_ctx;
#include <kinc/backend/SystemMicrosoft.h>

View File

@ -0,0 +1,11 @@
#include "ShaderHash.h"
// djb2
uint32_t kinc_internal_hash_name(unsigned char *str) {
unsigned long hash = 5381;
int c;
while ((c = *str++)) {
hash = hash * 33 ^ c;
}
return hash;
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t hash;
uint32_t index;
} kinc_internal_hash_index_t;
uint32_t kinc_internal_hash_name(unsigned char *str);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,203 @@
#include "Direct3D11.h"
#include <kinc/graphics4/compute.h>
#include <kinc/graphics4/texture.h>
#include <kinc/log.h>
#include <kinc/math/core.h>
#include <kinc/backend/SystemMicrosoft.h>
#include <assert.h>
static int getMultipleOf16(int value) {
int ret = 16;
while (ret < value)
ret += 16;
return ret;
}
void kinc_g4_compute_shader_init(kinc_g4_compute_shader *shader, void *_data, int length) {
unsigned index = 0;
uint8_t *data = (uint8_t *)_data;
#ifndef KINC_KONG
memset(&shader->impl.attributes, 0, sizeof(shader->impl.attributes));
int attributesCount = data[index++];
for (int i = 0; i < attributesCount; ++i) {
unsigned char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
shader->impl.attributes[i].hash = kinc_internal_hash_name(name);
shader->impl.attributes[i].index = data[index++];
}
memset(&shader->impl.textures, 0, sizeof(shader->impl.textures));
uint8_t texCount = data[index++];
for (unsigned i = 0; i < texCount; ++i) {
unsigned char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
shader->impl.textures[i].hash = kinc_internal_hash_name(name);
shader->impl.textures[i].index = data[index++];
}
memset(&shader->impl.constants, 0, sizeof(shader->impl.constants));
uint8_t constantCount = data[index++];
shader->impl.constantsSize = 0;
for (unsigned i = 0; i < constantCount; ++i) {
unsigned char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
kinc_g4_compute_internal_shader_constant constant;
constant.hash = kinc_internal_hash_name(name);
constant.offset = *(uint32_t *)&data[index];
index += 4;
constant.size = *(uint32_t *)&data[index];
index += 4;
constant.columns = data[index];
index += 1;
constant.rows = data[index];
index += 1;
shader->impl.constants[i] = constant;
shader->impl.constantsSize = constant.offset + constant.size;
}
#endif
shader->impl.length = (int)(length - index);
shader->impl.data = (uint8_t *)malloc(shader->impl.length);
assert(shader->impl.data != NULL);
memcpy(shader->impl.data, &data[index], shader->impl.length);
HRESULT hr =
dx_ctx.device->lpVtbl->CreateComputeShader(dx_ctx.device, shader->impl.data, shader->impl.length, NULL, (ID3D11ComputeShader **)&shader->impl.shader);
if (hr != S_OK) {
kinc_log(KINC_LOG_LEVEL_WARNING, "Could not initialize compute shader.");
return;
}
#ifndef KINC_KONG
D3D11_BUFFER_DESC desc;
desc.ByteWidth = getMultipleOf16(shader->impl.constantsSize);
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &desc, NULL, &shader->impl.constantBuffer));
#endif
}
void kinc_g4_compute_shader_destroy(kinc_g4_compute_shader *shader) {}
static kinc_g4_compute_internal_shader_constant *compute_findConstant(kinc_g4_compute_internal_shader_constant *constants, uint32_t hash) {
for (int i = 0; i < 64; ++i) {
if (constants[i].hash == hash) {
return &constants[i];
}
}
return NULL;
}
static kinc_internal_hash_index_t *compute_findTextureUnit(kinc_internal_hash_index_t *units, uint32_t hash) {
for (int i = 0; i < 64; ++i) {
if (units[i].hash == hash) {
return &units[i];
}
}
return NULL;
}
#ifndef KINC_KONG
kinc_g4_constant_location_t kinc_g4_compute_shader_get_constant_location(kinc_g4_compute_shader *shader, const char *name) {
kinc_g4_constant_location_t location = {0};
uint32_t hash = kinc_internal_hash_name((unsigned char *)name);
kinc_g4_compute_internal_shader_constant *constant = compute_findConstant(shader->impl.constants, hash);
if (constant == NULL) {
location.impl.computeOffset = 0;
location.impl.computeSize = 0;
location.impl.computeColumns = 0;
location.impl.computeRows = 0;
}
else {
location.impl.computeOffset = constant->offset;
location.impl.computeSize = constant->size;
location.impl.computeColumns = constant->columns;
location.impl.computeRows = constant->rows;
}
if (location.impl.computeSize == 0) {
kinc_log(KINC_LOG_LEVEL_WARNING, "Uniform %s not found.", name);
}
return location;
}
kinc_g4_texture_unit_t kinc_g4_compute_shader_get_texture_unit(kinc_g4_compute_shader *shader, const char *name) {
char unitName[64];
int unitOffset = 0;
size_t len = strlen(name);
if (len > 63) {
len = 63;
}
strncpy(unitName, name, len + 1);
if (unitName[len - 1] == ']') { // Check for array - mySampler[2]
unitOffset = (int)(unitName[len - 2] - '0'); // Array index is unit offset
unitName[len - 3] = 0; // Strip array from name
}
uint32_t hash = kinc_internal_hash_name((unsigned char *)unitName);
kinc_g4_texture_unit_t unit;
for (int i = 0; i < KINC_G4_SHADER_TYPE_COUNT; ++i) {
unit.stages[i] = -1;
}
kinc_internal_hash_index_t *compute_unit = compute_findTextureUnit(shader->impl.textures, hash);
if (compute_unit == NULL) {
unit.stages[KINC_G4_SHADER_TYPE_COMPUTE] = -1;
#ifndef NDEBUG
static int notFoundCount = 0;
if (notFoundCount < 10) {
kinc_log(KINC_LOG_LEVEL_WARNING, "Sampler %s not found.", unitName);
++notFoundCount;
}
else if (notFoundCount == 10) {
kinc_log(KINC_LOG_LEVEL_WARNING, "Giving up on sampler not found messages.", unitName);
++notFoundCount;
}
#endif
}
else {
unit.stages[KINC_G4_SHADER_TYPE_COMPUTE] = compute_unit->index + unitOffset;
}
return unit;
}
#endif
void kinc_g4_set_compute_shader(kinc_g4_compute_shader *shader) {
dx_ctx.context->lpVtbl->CSSetShader(dx_ctx.context, (ID3D11ComputeShader *)shader->impl.shader, NULL, 0);
#ifndef KINC_KONG
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)shader->impl.constantBuffer, 0, NULL, computeConstants, 0, 0);
dx_ctx.context->lpVtbl->CSSetConstantBuffers(dx_ctx.context, 0, 1, &shader->impl.constantBuffer);
#endif
}
void kinc_g4_compute(int x, int y, int z) {
dx_ctx.context->lpVtbl->Dispatch(dx_ctx.context, x, y, z);
ID3D11UnorderedAccessView *nullView = NULL;
dx_ctx.context->lpVtbl->CSSetUnorderedAccessViews(dx_ctx.context, 0, 1, &nullView, NULL);
}

View File

@ -0,0 +1,45 @@
#pragma once
#include <kinc/backend/graphics4/ShaderHash.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ID3D11Buffer;
typedef struct kinc_g4_compute_constant_location_impl {
uint32_t offset;
uint32_t size;
uint8_t columns;
uint8_t rows;
} kinc_g4_compute_constant_location_impl;
typedef struct kinc_g4_compute_texture_unit_impl {
int unit;
} kinc_g4_compute_texture_unit_impl;
typedef struct kinc_g4_compute_internal_shader_constant {
uint32_t hash;
uint32_t offset;
uint32_t size;
uint8_t columns;
uint8_t rows;
} kinc_g4_compute_internal_shader_constant;
typedef struct kinc_g4_compute_shader_impl {
#ifndef KINC_KONG
kinc_g4_compute_internal_shader_constant constants[64];
int constantsSize;
kinc_internal_hash_index_t attributes[64];
kinc_internal_hash_index_t textures[64];
struct ID3D11Buffer *constantBuffer;
#endif
void *shader;
uint8_t *data;
int length;
} kinc_g4_compute_shader_impl;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,51 @@
#ifdef KINC_KONG
#include <kinc/graphics4/constantbuffer.h>
void kinc_g4_constant_buffer_init(kinc_g4_constant_buffer *buffer, size_t size) {
buffer->impl.size = size;
buffer->impl.last_start = 0;
buffer->impl.last_size = size;
D3D11_BUFFER_DESC desc;
desc.ByteWidth = (UINT)get_multiple_of_16(size);
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &desc, NULL, &buffer->impl.buffer));
}
void kinc_g4_constant_buffer_destroy(kinc_g4_constant_buffer *buffer) {
buffer->impl.buffer->lpVtbl->Release(buffer->impl.buffer);
}
uint8_t *kinc_g4_constant_buffer_lock_all(kinc_g4_constant_buffer *buffer) {
return kinc_g4_constant_buffer_lock(buffer, 0, kinc_g4_constant_buffer_size(buffer));
}
uint8_t *kinc_g4_constant_buffer_lock(kinc_g4_constant_buffer *buffer, size_t start, size_t size) {
buffer->impl.last_start = start;
buffer->impl.last_size = size;
D3D11_MAPPED_SUBRESOURCE mapped_resource;
memset(&mapped_resource, 0, sizeof(D3D11_MAPPED_SUBRESOURCE));
dx_ctx.context->lpVtbl->Map(dx_ctx.context, (ID3D11Resource *)buffer->impl.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource);
uint8_t *data = (uint8_t *)mapped_resource.pData;
return &data[start];
}
void kinc_g4_constant_buffer_unlock_all(kinc_g4_constant_buffer *buffer) {
kinc_g4_constant_buffer_unlock(buffer, buffer->impl.last_size);
}
void kinc_g4_constant_buffer_unlock(kinc_g4_constant_buffer *buffer, size_t count) {
dx_ctx.context->lpVtbl->Unmap(dx_ctx.context, (ID3D11Resource *)buffer->impl.buffer, 0);
}
size_t kinc_g4_constant_buffer_size(kinc_g4_constant_buffer *buffer) {
return buffer->impl.size;
}
#endif

View File

@ -0,0 +1,14 @@
#pragma once
#ifdef KINC_KONG
struct ID3D11Buffer;
typedef struct kinc_g4_constant_buffer_impl {
struct ID3D11Buffer *buffer;
size_t size;
size_t last_start;
size_t last_size;
} kinc_g4_constant_buffer_impl;
#endif

View File

@ -0,0 +1,113 @@
// Windows 7
#define WINVER 0x0601
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0601
#define NOATOM
#define NOCLIPBOARD
#define NOCOLOR
#define NOCOMM
#define NOCTLMGR
#define NODEFERWINDOWPOS
#define NODRAWTEXT
#define NOGDI
#define NOGDICAPMASKS
#define NOHELP
#define NOICONS
#define NOKANJI
#define NOKEYSTATES
#define NOMB
#define NOMCX
#define NOMEMMGR
#define NOMENUS
#define NOMETAFILE
#define NOMINMAX
// #define NOMSG
#define NONLS
#define NOOPENFILE
#define NOPROFILER
#define NORASTEROPS
#define NOSCROLL
#define NOSERVICE
#define NOSHOWWINDOW
#define NOSOUND
#define NOSYSCOMMANDS
#define NOSYSMETRICS
#define NOTEXTMETRIC
// #define NOUSER
#define NOVIRTUALKEYCODES
#define NOWH
#define NOWINMESSAGES
#define NOWINOFFSETS
#define NOWINSTYLES
#define WIN32_LEAN_AND_MEAN
#include <kinc/graphics4/graphics.h>
#include <kinc/backend/SystemMicrosoft.h>
#ifdef KINC_WINDOWSAPP
#include <d3d11_1.h>
#else
#pragma warning(disable : 4005)
#include <d3d11.h>
#endif
#include "Direct3D11.h"
#include <assert.h>
#include <malloc.h>
#include <stdint.h>
struct dx_context dx_ctx = {0};
static uint8_t vertexConstants[1024 * 4];
static uint8_t fragmentConstants[1024 * 4];
static uint8_t geometryConstants[1024 * 4];
static uint8_t tessControlConstants[1024 * 4];
static uint8_t tessEvalConstants[1024 * 4];
static uint8_t computeConstants[1024 * 4];
static D3D11_COMPARISON_FUNC get_comparison(kinc_g4_compare_mode_t compare) {
switch (compare) {
default:
case KINC_G4_COMPARE_ALWAYS:
return D3D11_COMPARISON_ALWAYS;
case KINC_G4_COMPARE_NEVER:
return D3D11_COMPARISON_NEVER;
case KINC_G4_COMPARE_EQUAL:
return D3D11_COMPARISON_EQUAL;
case KINC_G4_COMPARE_NOT_EQUAL:
return D3D11_COMPARISON_NOT_EQUAL;
case KINC_G4_COMPARE_LESS:
return D3D11_COMPARISON_LESS;
case KINC_G4_COMPARE_LESS_EQUAL:
return D3D11_COMPARISON_LESS_EQUAL;
case KINC_G4_COMPARE_GREATER:
return D3D11_COMPARISON_GREATER;
case KINC_G4_COMPARE_GREATER_EQUAL:
return D3D11_COMPARISON_GREATER_EQUAL;
}
}
static size_t get_multiple_of_16(size_t value) {
size_t ret = 16;
while (ret < value) {
ret += 16;
}
return ret;
}
#include "Direct3D11.c.h"
#include "ShaderHash.c.h"
#include "compute.c.h"
#include "constantbuffer.c.h"
#include "indexbuffer.c.h"
#include "pipeline.c.h"
#include "rendertarget.c.h"
#include "shader.c.h"
#include "texture.c.h"
#include "texturearray.c.h"
#include "vertexbuffer.c.h"

View File

@ -0,0 +1,89 @@
#include <kinc/graphics4/indexbuffer.h>
void kinc_g4_index_buffer_init(kinc_g4_index_buffer_t *buffer, int count, kinc_g4_index_buffer_format_t format, kinc_g4_usage_t usage) {
buffer->impl.count = count;
buffer->impl.sixteen = format == KINC_G4_INDEX_BUFFER_FORMAT_16BIT;
buffer->impl.last_start = 0;
buffer->impl.last_count = count;
uint32_t byte_size = buffer->impl.sixteen ? sizeof(uint16_t) * count : sizeof(uint32_t) * count;
if (usage == KINC_G4_USAGE_DYNAMIC) {
buffer->impl.indices = NULL;
}
else {
buffer->impl.indices = malloc(byte_size);
}
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = byte_size;
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
buffer->impl.usage = usage;
switch (usage) {
case KINC_G4_USAGE_STATIC:
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
break;
case KINC_G4_USAGE_DYNAMIC:
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
break;
case KINC_G4_USAGE_READABLE:
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
break;
}
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &bufferDesc, NULL, &buffer->impl.ib));
}
void kinc_g4_index_buffer_destroy(kinc_g4_index_buffer_t *buffer) {
buffer->impl.ib->lpVtbl->Release(buffer->impl.ib);
free(buffer->impl.indices);
buffer->impl.indices = NULL;
}
static int kinc_g4_internal_index_buffer_stride(kinc_g4_index_buffer_t *buffer) {
return buffer->impl.sixteen ? 2 : 4;
}
void *kinc_g4_index_buffer_lock_all(kinc_g4_index_buffer_t *buffer) {
return kinc_g4_index_buffer_lock(buffer, 0, kinc_g4_index_buffer_count(buffer));
}
void *kinc_g4_index_buffer_lock(kinc_g4_index_buffer_t *buffer, int start, int count) {
buffer->impl.last_start = start;
buffer->impl.last_count = count;
if (buffer->impl.usage == KINC_G4_USAGE_DYNAMIC) {
D3D11_MAPPED_SUBRESOURCE mappedResource;
memset(&mappedResource, 0, sizeof(D3D11_MAPPED_SUBRESOURCE));
dx_ctx.context->lpVtbl->Map(dx_ctx.context, (ID3D11Resource *)buffer->impl.ib, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
uint8_t *data = (uint8_t *)mappedResource.pData;
return &data[start * kinc_g4_internal_index_buffer_stride(buffer)];
}
else {
uint8_t *data = (uint8_t *)buffer->impl.indices;
return &data[start * kinc_g4_internal_index_buffer_stride(buffer)];
}
}
void kinc_g4_index_buffer_unlock_all(kinc_g4_index_buffer_t *buffer) {
kinc_g4_index_buffer_unlock(buffer, buffer->impl.last_count);
}
void kinc_g4_index_buffer_unlock(kinc_g4_index_buffer_t *buffer, int count) {
if (buffer->impl.usage == KINC_G4_USAGE_DYNAMIC) {
dx_ctx.context->lpVtbl->Unmap(dx_ctx.context, (ID3D11Resource *)buffer->impl.ib, 0);
}
else {
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)buffer->impl.ib, 0, NULL, buffer->impl.indices, 0, 0);
}
}
int kinc_g4_index_buffer_count(kinc_g4_index_buffer_t *buffer) {
return buffer->impl.count;
}

View File

@ -0,0 +1,13 @@
#pragma once
struct ID3D11Buffer;
typedef struct {
struct ID3D11Buffer *ib;
void *indices;
int count;
int usage;
bool sixteen;
int last_start;
int last_count;
} kinc_g4_index_buffer_impl_t;

View File

@ -0,0 +1,878 @@
#include <kinc/graphics4/pipeline.h>
#include <kinc/graphics4/shader.h>
#include <kinc/graphics4/vertexbuffer.h>
#include <kinc/libs/stb_sprintf.h>
#include <kinc/log.h>
kinc_g4_pipeline_t *currentPipeline = NULL;
float currentBlendFactor[4] = {0, 0, 0, 0};
bool needPipelineRebind = true;
static D3D11_CULL_MODE convert_cull_mode(kinc_g4_cull_mode_t cullMode) {
switch (cullMode) {
case KINC_G4_CULL_CLOCKWISE:
return D3D11_CULL_BACK;
case KINC_G4_CULL_COUNTER_CLOCKWISE:
return D3D11_CULL_FRONT;
case KINC_G4_CULL_NOTHING:
return D3D11_CULL_NONE;
default:
assert(false);
return D3D11_CULL_NONE;
}
}
static D3D11_BLEND convert_blend_factor(kinc_g4_blending_factor_t factor) {
switch (factor) {
case KINC_G4_BLEND_ONE:
return D3D11_BLEND_ONE;
case KINC_G4_BLEND_ZERO:
return D3D11_BLEND_ZERO;
case KINC_G4_BLEND_SOURCE_ALPHA:
return D3D11_BLEND_SRC_ALPHA;
case KINC_G4_BLEND_DEST_ALPHA:
return D3D11_BLEND_DEST_ALPHA;
case KINC_G4_BLEND_INV_SOURCE_ALPHA:
return D3D11_BLEND_INV_SRC_ALPHA;
case KINC_G4_BLEND_INV_DEST_ALPHA:
return D3D11_BLEND_INV_DEST_ALPHA;
case KINC_G4_BLEND_SOURCE_COLOR:
return D3D11_BLEND_SRC_COLOR;
case KINC_G4_BLEND_DEST_COLOR:
return D3D11_BLEND_DEST_COLOR;
case KINC_G4_BLEND_INV_SOURCE_COLOR:
return D3D11_BLEND_INV_SRC_COLOR;
case KINC_G4_BLEND_INV_DEST_COLOR:
return D3D11_BLEND_INV_DEST_COLOR;
default:
assert(false);
return D3D11_BLEND_SRC_ALPHA;
}
}
static D3D11_BLEND_OP convert_blend_operation(kinc_g4_blending_operation_t operation) {
switch (operation) {
case KINC_G4_BLENDOP_ADD:
return D3D11_BLEND_OP_ADD;
case KINC_G4_BLENDOP_SUBTRACT:
return D3D11_BLEND_OP_SUBTRACT;
case KINC_G4_BLENDOP_REVERSE_SUBTRACT:
return D3D11_BLEND_OP_REV_SUBTRACT;
case KINC_G4_BLENDOP_MIN:
return D3D11_BLEND_OP_MIN;
case KINC_G4_BLENDOP_MAX:
return D3D11_BLEND_OP_MAX;
default:
assert(false);
return D3D11_BLEND_OP_ADD;
}
}
static D3D11_STENCIL_OP get_stencil_action(kinc_g4_stencil_action_t action) {
switch (action) {
default:
case KINC_G4_STENCIL_KEEP:
return D3D11_STENCIL_OP_KEEP;
case KINC_G4_STENCIL_ZERO:
return D3D11_STENCIL_OP_ZERO;
case KINC_G4_STENCIL_REPLACE:
return D3D11_STENCIL_OP_REPLACE;
case KINC_G4_STENCIL_INCREMENT:
return D3D11_STENCIL_OP_INCR;
case KINC_G4_STENCIL_INCREMENT_WRAP:
return D3D11_STENCIL_OP_INCR_SAT;
case KINC_G4_STENCIL_DECREMENT:
return D3D11_STENCIL_OP_DECR;
case KINC_G4_STENCIL_DECREMENT_WRAP:
return D3D11_STENCIL_OP_DECR_SAT;
case KINC_G4_STENCIL_INVERT:
return D3D11_STENCIL_OP_INVERT;
}
}
void kinc_internal_set_constants(void) {
#ifndef KINC_KONG
if (currentPipeline->vertex_shader->impl.constantsSize > 0) {
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)currentPipeline->impl.vertexConstantBuffer, 0, NULL, vertexConstants, 0, 0);
dx_ctx.context->lpVtbl->VSSetConstantBuffers(dx_ctx.context, 0, 1, &currentPipeline->impl.vertexConstantBuffer);
}
if (currentPipeline->fragment_shader->impl.constantsSize > 0) {
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)currentPipeline->impl.fragmentConstantBuffer, 0, NULL, fragmentConstants, 0,
0);
dx_ctx.context->lpVtbl->PSSetConstantBuffers(dx_ctx.context, 0, 1, &currentPipeline->impl.fragmentConstantBuffer);
}
if (currentPipeline->geometry_shader != NULL && currentPipeline->geometry_shader->impl.constantsSize > 0) {
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)currentPipeline->impl.geometryConstantBuffer, 0, NULL, geometryConstants, 0,
0);
dx_ctx.context->lpVtbl->GSSetConstantBuffers(dx_ctx.context, 0, 1, &currentPipeline->impl.geometryConstantBuffer);
}
if (currentPipeline->tessellation_control_shader != NULL && currentPipeline->tessellation_control_shader->impl.constantsSize > 0) {
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)currentPipeline->impl.tessControlConstantBuffer, 0, NULL,
tessControlConstants, 0, 0);
dx_ctx.context->lpVtbl->HSSetConstantBuffers(dx_ctx.context, 0, 1, &currentPipeline->impl.tessControlConstantBuffer);
}
if (currentPipeline->tessellation_evaluation_shader != NULL && currentPipeline->tessellation_evaluation_shader->impl.constantsSize > 0) {
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)currentPipeline->impl.tessEvalConstantBuffer, 0, NULL, tessEvalConstants, 0,
0);
dx_ctx.context->lpVtbl->DSSetConstantBuffers(dx_ctx.context, 0, 1, &currentPipeline->impl.tessEvalConstantBuffer);
}
#endif
}
void kinc_g4_pipeline_init(struct kinc_g4_pipeline *state) {
memset(state, 0, sizeof(struct kinc_g4_pipeline));
kinc_g4_internal_pipeline_set_defaults(state);
state->impl.d3d11inputLayout = NULL;
state->impl.fragmentConstantBuffer = NULL;
state->impl.vertexConstantBuffer = NULL;
state->impl.geometryConstantBuffer = NULL;
state->impl.tessEvalConstantBuffer = NULL;
state->impl.tessControlConstantBuffer = NULL;
state->impl.depthStencilState = NULL;
state->impl.rasterizerState = NULL;
state->impl.rasterizerStateScissor = NULL;
state->impl.blendState = NULL;
}
void kinc_g4_pipeline_destroy(struct kinc_g4_pipeline *state) {
if (state->impl.d3d11inputLayout != NULL) {
state->impl.d3d11inputLayout->lpVtbl->Release(state->impl.d3d11inputLayout);
state->impl.d3d11inputLayout = NULL;
}
if (state->impl.fragmentConstantBuffer != NULL) {
state->impl.fragmentConstantBuffer->lpVtbl->Release(state->impl.fragmentConstantBuffer);
state->impl.fragmentConstantBuffer = NULL;
}
if (state->impl.vertexConstantBuffer != NULL) {
state->impl.vertexConstantBuffer->lpVtbl->Release(state->impl.vertexConstantBuffer);
state->impl.vertexConstantBuffer = NULL;
}
if (state->impl.geometryConstantBuffer != NULL) {
state->impl.geometryConstantBuffer->lpVtbl->Release(state->impl.geometryConstantBuffer);
state->impl.geometryConstantBuffer = NULL;
}
if (state->impl.tessEvalConstantBuffer != NULL) {
state->impl.tessEvalConstantBuffer->lpVtbl->Release(state->impl.tessEvalConstantBuffer);
state->impl.tessEvalConstantBuffer = NULL;
}
if (state->impl.tessControlConstantBuffer != NULL) {
state->impl.tessControlConstantBuffer->lpVtbl->Release(state->impl.tessControlConstantBuffer);
state->impl.tessControlConstantBuffer = NULL;
}
if (state->impl.depthStencilState != NULL) {
state->impl.depthStencilState->lpVtbl->Release(state->impl.depthStencilState);
state->impl.depthStencilState = NULL;
}
if (state->impl.rasterizerState != NULL) {
state->impl.rasterizerState->lpVtbl->Release(state->impl.rasterizerState);
state->impl.rasterizerState = NULL;
}
if (state->impl.rasterizerStateScissor != NULL) {
state->impl.rasterizerStateScissor->lpVtbl->Release(state->impl.rasterizerStateScissor);
state->impl.rasterizerStateScissor = NULL;
}
if (state->impl.blendState != NULL) {
state->impl.blendState->lpVtbl->Release(state->impl.blendState);
state->impl.blendState = NULL;
}
}
void kinc_internal_set_rasterizer_state(struct kinc_g4_pipeline *pipeline, bool scissoring) {
if (scissoring && pipeline->impl.rasterizerStateScissor != NULL)
dx_ctx.context->lpVtbl->RSSetState(dx_ctx.context, pipeline->impl.rasterizerStateScissor);
else if (pipeline->impl.rasterizerState != NULL)
dx_ctx.context->lpVtbl->RSSetState(dx_ctx.context, pipeline->impl.rasterizerState);
}
void kinc_internal_set_pipeline(struct kinc_g4_pipeline *pipeline, bool scissoring) {
dx_ctx.context->lpVtbl->OMSetDepthStencilState(dx_ctx.context, pipeline->impl.depthStencilState, pipeline->stencil_reference_value);
UINT sampleMask = 0xffffffff;
dx_ctx.context->lpVtbl->OMSetBlendState(dx_ctx.context, pipeline->impl.blendState, currentBlendFactor, sampleMask);
kinc_internal_set_rasterizer_state(pipeline, scissoring);
dx_ctx.context->lpVtbl->VSSetShader(dx_ctx.context, (ID3D11VertexShader *)pipeline->vertex_shader->impl.shader, NULL, 0);
dx_ctx.context->lpVtbl->PSSetShader(dx_ctx.context, (ID3D11PixelShader *)pipeline->fragment_shader->impl.shader, NULL, 0);
dx_ctx.context->lpVtbl->GSSetShader(dx_ctx.context,
pipeline->geometry_shader != NULL ? (ID3D11GeometryShader *)pipeline->geometry_shader->impl.shader : NULL, NULL, 0);
dx_ctx.context->lpVtbl->HSSetShader(
dx_ctx.context, pipeline->tessellation_control_shader != NULL ? (ID3D11HullShader *)pipeline->tessellation_control_shader->impl.shader : NULL, NULL, 0);
dx_ctx.context->lpVtbl->DSSetShader(
dx_ctx.context, pipeline->tessellation_evaluation_shader != NULL ? (ID3D11DomainShader *)pipeline->tessellation_evaluation_shader->impl.shader : NULL,
NULL, 0);
dx_ctx.context->lpVtbl->IASetInputLayout(dx_ctx.context, pipeline->impl.d3d11inputLayout);
}
void kinc_internal_pipeline_rebind() {
if (currentPipeline != NULL && needPipelineRebind) {
kinc_internal_set_pipeline(currentPipeline, kinc_internal_scissoring);
needPipelineRebind = false;
}
}
#ifndef KINC_KONG
static kinc_internal_shader_constant_t *findConstant(kinc_internal_shader_constant_t *constants, uint32_t hash) {
for (int i = 0; i < 64; ++i) {
if (constants[i].hash == hash) {
return &constants[i];
}
}
return NULL;
}
static kinc_internal_hash_index_t *findTextureUnit(kinc_internal_hash_index_t *units, uint32_t hash) {
for (int i = 0; i < 64; ++i) {
if (units[i].hash == hash) {
return &units[i];
}
}
return NULL;
}
void kinc_g4_pipeline_get_constant_locations(kinc_g4_pipeline_t *state, kinc_g4_constant_location_t *vertex_locations,
kinc_g4_constant_location_t *fragment_locations, int *vertex_sizes, int *fragment_sizes, int *max_vertex,
int *max_fragment) {
// *max_vertex = state->vertex_shader->impl.constantsSize;
// *max_fragment = state->fragment_shader->impl.constantsSize;
// if (vertex_locations != null && fragment_locations != null) {
// for (int i = 0; i < state->vertex_shader->impl.constantsSize; i++) {
// kinc_internal_shader_constant_t *constant = state->vertex_shader->impl.constants[i];
// vertex_location[i].impl.vertexOffset = constant->offset;
// vertex_location[i].impl.vertexSize = constant->size;
// vertex_location[i].impl.vertexColumns = constant->columns;
// vertex_location[i].impl.vertexRows = constant->rows;
// vertex_sizes[i] = constant->size;
// }
// for (int i = 0; i < state->fragment_shader->impl.constantsSize; i++) {
// kinc_internal_shader_constant_t *constant = state->fragment_shader->impl.constants[i];
// fragment_location[i].impl.vertexOffset = constant->offset;
// fragment_location[i].impl.vertexSize = constant->size;
// fragment_location[i].impl.vertexColumns = constant->columns;
// fragment_location[i].impl.vertexRows = constant->rows;
// fragment_sizes[i] = constant->size;
// }
// }
}
kinc_g4_constant_location_t kinc_g4_pipeline_get_constant_location(struct kinc_g4_pipeline *state, const char *name) {
kinc_g4_constant_location_t location = {0};
uint32_t hash = kinc_internal_hash_name((unsigned char *)name);
kinc_internal_shader_constant_t *constant = findConstant(state->vertex_shader->impl.constants, hash);
if (constant == NULL) {
location.impl.vertexOffset = 0;
location.impl.vertexSize = 0;
location.impl.vertexColumns = 0;
location.impl.vertexRows = 0;
}
else {
location.impl.vertexOffset = constant->offset;
location.impl.vertexSize = constant->size;
location.impl.vertexColumns = constant->columns;
location.impl.vertexRows = constant->rows;
}
constant = findConstant(state->fragment_shader->impl.constants, hash);
if (constant == NULL) {
location.impl.fragmentOffset = 0;
location.impl.fragmentSize = 0;
location.impl.fragmentColumns = 0;
location.impl.fragmentRows = 0;
}
else {
location.impl.fragmentOffset = constant->offset;
location.impl.fragmentSize = constant->size;
location.impl.fragmentColumns = constant->columns;
location.impl.fragmentRows = constant->rows;
}
constant = state->geometry_shader == NULL ? NULL : findConstant(state->geometry_shader->impl.constants, hash);
if (constant == NULL) {
location.impl.geometryOffset = 0;
location.impl.geometrySize = 0;
location.impl.geometryColumns = 0;
location.impl.geometryRows = 0;
}
else {
location.impl.geometryOffset = constant->offset;
location.impl.geometrySize = constant->size;
location.impl.geometryColumns = constant->columns;
location.impl.geometryRows = constant->rows;
}
constant = state->tessellation_control_shader == NULL ? NULL : findConstant(state->tessellation_control_shader->impl.constants, hash);
if (constant == NULL) {
location.impl.tessControlOffset = 0;
location.impl.tessControlSize = 0;
location.impl.tessControlColumns = 0;
location.impl.tessControlRows = 0;
}
else {
location.impl.tessControlOffset = constant->offset;
location.impl.tessControlSize = constant->size;
location.impl.tessControlColumns = constant->columns;
location.impl.tessControlRows = constant->rows;
}
constant = state->tessellation_evaluation_shader == NULL ? NULL : findConstant(state->tessellation_evaluation_shader->impl.constants, hash);
if (constant == NULL) {
location.impl.tessEvalOffset = 0;
location.impl.tessEvalSize = 0;
location.impl.tessEvalColumns = 0;
location.impl.tessEvalRows = 0;
}
else {
location.impl.tessEvalOffset = constant->offset;
location.impl.tessEvalSize = constant->size;
location.impl.tessEvalColumns = constant->columns;
location.impl.tessEvalRows = constant->rows;
}
if (location.impl.vertexSize == 0 && location.impl.fragmentSize == 0 && location.impl.geometrySize == 0 && location.impl.tessControlSize == 0 &&
location.impl.tessEvalSize == 0) {
kinc_log(KINC_LOG_LEVEL_WARNING, "Uniform %s not found.", name);
}
return location;
}
kinc_g4_texture_unit_t kinc_g4_pipeline_get_texture_unit(struct kinc_g4_pipeline *state, const char *name) {
char unitName[64];
int unitOffset = 0;
size_t len = strlen(name);
if (len > 63)
len = 63;
strncpy(unitName, name, len + 1);
if (unitName[len - 1] == ']') { // Check for array - mySampler[2]
unitOffset = (int)(unitName[len - 2] - '0'); // Array index is unit offset
unitName[len - 3] = 0; // Strip array from name
}
uint32_t hash = kinc_internal_hash_name((unsigned char *)unitName);
kinc_g4_texture_unit_t unit;
for (int i = 0; i < KINC_G4_SHADER_TYPE_COUNT; ++i) {
unit.stages[i] = -1;
}
kinc_internal_hash_index_t *fragmentUnit = findTextureUnit(state->fragment_shader->impl.textures, hash);
if (fragmentUnit != NULL) {
unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] = fragmentUnit->index + unitOffset;
}
kinc_internal_hash_index_t *vertexUnit = findTextureUnit(state->vertex_shader->impl.textures, hash);
if (vertexUnit != NULL) {
unit.stages[KINC_G4_SHADER_TYPE_VERTEX] = vertexUnit->index + unitOffset;
}
return unit;
}
#endif
static char stringCache[1024];
static int stringCacheIndex = 0;
static void setVertexDesc(D3D11_INPUT_ELEMENT_DESC *vertexDesc, int attributeIndex, int index, int stream, bool instanced, int subindex) {
if (subindex < 0) {
vertexDesc->SemanticName = "TEXCOORD";
vertexDesc->SemanticIndex = attributeIndex;
}
else {
// SPIRV_CROSS uses TEXCOORD_0_0,... for split up matrices
int stringStart = stringCacheIndex;
strcpy(&stringCache[stringCacheIndex], "TEXCOORD");
stringCacheIndex += (int)strlen("TEXCOORD");
sprintf(&stringCache[stringCacheIndex], "%i", attributeIndex);
stringCacheIndex += (int)strlen(&stringCache[stringCacheIndex]);
strcpy(&stringCache[stringCacheIndex], "_");
stringCacheIndex += 2;
vertexDesc->SemanticName = &stringCache[stringStart];
vertexDesc->SemanticIndex = subindex;
}
vertexDesc->InputSlot = stream;
vertexDesc->AlignedByteOffset = (index == 0) ? 0 : D3D11_APPEND_ALIGNED_ELEMENT;
vertexDesc->InputSlotClass = instanced ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
vertexDesc->InstanceDataStepRate = instanced ? 1 : 0;
}
#define usedCount 32
static int getAttributeLocation(kinc_internal_hash_index_t *attributes, const char *name, bool *used) {
uint32_t hash = kinc_internal_hash_name((unsigned char *)name);
for (int i = 0; i < 64; ++i) {
if (attributes[i].hash == hash) {
return attributes[i].index;
}
}
for (int i = 0; i < usedCount; ++i) {
if (!used[i]) {
used[i] = true;
return i;
}
}
return 0;
}
static void createRenderTargetBlendDesc(struct kinc_g4_pipeline *pipe, D3D11_RENDER_TARGET_BLEND_DESC *rtbd, int targetNum) {
rtbd->BlendEnable = pipe->blend_source != KINC_G4_BLEND_ONE || pipe->blend_destination != KINC_G4_BLEND_ZERO ||
pipe->alpha_blend_source != KINC_G4_BLEND_ONE || pipe->alpha_blend_destination != KINC_G4_BLEND_ZERO;
rtbd->SrcBlend = convert_blend_factor(pipe->blend_source);
rtbd->DestBlend = convert_blend_factor(pipe->blend_destination);
rtbd->BlendOp = convert_blend_operation(pipe->blend_operation);
rtbd->SrcBlendAlpha = convert_blend_factor(pipe->alpha_blend_source);
rtbd->DestBlendAlpha = convert_blend_factor(pipe->alpha_blend_destination);
rtbd->BlendOpAlpha = convert_blend_operation(pipe->alpha_blend_operation);
rtbd->RenderTargetWriteMask = (((pipe->color_write_mask_red[targetNum] ? D3D11_COLOR_WRITE_ENABLE_RED : 0) |
(pipe->color_write_mask_green[targetNum] ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0)) |
(pipe->color_write_mask_blue[targetNum] ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0)) |
(pipe->color_write_mask_alpha[targetNum] ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0);
}
void kinc_g4_pipeline_compile(struct kinc_g4_pipeline *state) {
#ifndef KINC_KONG
if (state->vertex_shader->impl.constantsSize > 0) {
D3D11_BUFFER_DESC desc;
desc.ByteWidth = (UINT)get_multiple_of_16(state->vertex_shader->impl.constantsSize);
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &desc, NULL, &state->impl.vertexConstantBuffer));
}
if (state->fragment_shader->impl.constantsSize > 0) {
D3D11_BUFFER_DESC desc;
desc.ByteWidth = (UINT)get_multiple_of_16(state->fragment_shader->impl.constantsSize);
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &desc, NULL, &state->impl.fragmentConstantBuffer));
}
if (state->geometry_shader != NULL && state->geometry_shader->impl.constantsSize > 0) {
D3D11_BUFFER_DESC desc;
desc.ByteWidth = (UINT)get_multiple_of_16(state->geometry_shader->impl.constantsSize);
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &desc, NULL, &state->impl.geometryConstantBuffer));
}
if (state->tessellation_control_shader != NULL && state->tessellation_control_shader->impl.constantsSize > 0) {
D3D11_BUFFER_DESC desc;
desc.ByteWidth = (UINT)get_multiple_of_16(state->tessellation_control_shader->impl.constantsSize);
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &desc, NULL, &state->impl.tessControlConstantBuffer));
}
if (state->tessellation_evaluation_shader != NULL && state->tessellation_evaluation_shader->impl.constantsSize > 0) {
D3D11_BUFFER_DESC desc;
desc.ByteWidth = (UINT)get_multiple_of_16(state->tessellation_evaluation_shader->impl.constantsSize);
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &desc, NULL, &state->impl.tessEvalConstantBuffer));
}
#endif
int all = 0;
for (int stream = 0; state->input_layout[stream] != NULL; ++stream) {
for (int index = 0; index < state->input_layout[stream]->size; ++index) {
if (state->input_layout[stream]->elements[index].data == KINC_G4_VERTEX_DATA_F32_4X4) {
all += 4;
}
else {
all += 1;
}
}
}
#ifndef KINC_KONG
bool used[usedCount];
for (int i = 0; i < usedCount; ++i)
used[i] = false;
for (int i = 0; i < 64; ++i) {
used[state->vertex_shader->impl.attributes[i].index] = true;
}
#endif
stringCacheIndex = 0;
D3D11_INPUT_ELEMENT_DESC *vertexDesc = (D3D11_INPUT_ELEMENT_DESC *)alloca(sizeof(D3D11_INPUT_ELEMENT_DESC) * all);
#ifdef KINC_KONG
#define getAttributeLocation(a, b, c) index
#endif
int i = 0;
for (int stream = 0; state->input_layout[stream] != NULL; ++stream) {
for (int index = 0; index < state->input_layout[stream]->size; ++index) {
switch (state->input_layout[stream]->elements[index].data) {
case KINC_G4_VERTEX_DATA_F32_1X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32_FLOAT;
++i;
break;
case KINC_G4_VERTEX_DATA_F32_2X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32_FLOAT;
++i;
break;
case KINC_G4_VERTEX_DATA_F32_3X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32B32_FLOAT;
++i;
break;
case KINC_G4_VERTEX_DATA_F32_4X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
++i;
break;
case KINC_G4_VERTEX_DATA_I8_1X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U8_1X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I8_1X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8_SNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_U8_1X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8_UNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_I8_2X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U8_2X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I8_2X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8_SNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_U8_2X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8_UNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_I8_4X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8B8A8_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U8_4X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8B8A8_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I8_4X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8B8A8_SNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_U8_4X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R8G8B8A8_UNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_I16_1X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U16_1X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I16_1X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16_SNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_U16_1X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16_UNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_I16_2X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U16_2X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I16_2X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16_SNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_U16_2X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16_UNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_I16_4X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16B16A16_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U16_4X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16B16A16_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I16_4X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16B16A16_SNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_U16_4X_NORMALIZED:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R16G16B16A16_UNORM;
++i;
break;
case KINC_G4_VERTEX_DATA_I32_1X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U32_1X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I32_2X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U32_2X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I32_3X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32B32_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U32_3X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32B32_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_I32_4X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32B32A32_SINT;
++i;
break;
case KINC_G4_VERTEX_DATA_U32_4X:
setVertexDesc(&vertexDesc[i],
getAttributeLocation(state->vertex_shader->impl.attributes, state->input_layout[stream]->elements[index].name, used), index,
stream, state->input_layout[stream]->instanced, -1);
vertexDesc[i].Format = DXGI_FORMAT_R32G32B32A32_UINT;
++i;
break;
case KINC_G4_VERTEX_DATA_F32_4X4: {
char name[101];
strcpy(name, state->input_layout[stream]->elements[index].name);
strcat(name, "_");
size_t length = strlen(name);
sprintf(&name[length], "%i", 0);
name[length + 1] = 0;
int attributeLocation = getAttributeLocation(state->vertex_shader->impl.attributes, name, used);
for (int i2 = 0; i2 < 4; ++i2) {
setVertexDesc(&vertexDesc[i], attributeLocation, index + i2, stream, state->input_layout[stream]->instanced, i2);
vertexDesc[i].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
++i;
}
break;
}
default:
break;
}
}
}
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateInputLayout(dx_ctx.device, vertexDesc, all, state->vertex_shader->impl.data,
state->vertex_shader->impl.length, &state->impl.d3d11inputLayout));
{
D3D11_DEPTH_STENCIL_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.DepthEnable = state->depth_mode != KINC_G4_COMPARE_ALWAYS;
desc.DepthWriteMask = state->depth_write ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = get_comparison(state->depth_mode);
desc.StencilEnable = state->stencil_front_mode != KINC_G4_COMPARE_ALWAYS || state->stencil_back_mode != KINC_G4_COMPARE_ALWAYS ||
state->stencil_front_both_pass != KINC_G4_STENCIL_KEEP || state->stencil_back_both_pass != KINC_G4_STENCIL_KEEP ||
state->stencil_front_depth_fail != KINC_G4_STENCIL_KEEP || state->stencil_back_depth_fail != KINC_G4_STENCIL_KEEP ||
state->stencil_front_fail != KINC_G4_STENCIL_KEEP || state->stencil_back_fail != KINC_G4_STENCIL_KEEP;
desc.StencilReadMask = state->stencil_read_mask;
desc.StencilWriteMask = state->stencil_write_mask;
desc.FrontFace.StencilFunc = desc.BackFace.StencilFunc = get_comparison(state->stencil_front_mode);
desc.FrontFace.StencilDepthFailOp = desc.BackFace.StencilDepthFailOp = get_stencil_action(state->stencil_front_depth_fail);
desc.FrontFace.StencilPassOp = desc.BackFace.StencilPassOp = get_stencil_action(state->stencil_front_both_pass);
desc.FrontFace.StencilFailOp = desc.BackFace.StencilFailOp = get_stencil_action(state->stencil_front_fail);
desc.BackFace.StencilFunc = desc.BackFace.StencilFunc = get_comparison(state->stencil_back_mode);
desc.BackFace.StencilDepthFailOp = desc.BackFace.StencilDepthFailOp = get_stencil_action(state->stencil_back_depth_fail);
desc.BackFace.StencilPassOp = desc.BackFace.StencilPassOp = get_stencil_action(state->stencil_back_both_pass);
desc.BackFace.StencilFailOp = desc.BackFace.StencilFailOp = get_stencil_action(state->stencil_back_fail);
dx_ctx.device->lpVtbl->CreateDepthStencilState(dx_ctx.device, &desc, &state->impl.depthStencilState);
}
{
D3D11_RASTERIZER_DESC rasterDesc;
rasterDesc.CullMode = convert_cull_mode(state->cull_mode);
rasterDesc.FillMode = D3D11_FILL_SOLID;
rasterDesc.FrontCounterClockwise = TRUE;
rasterDesc.DepthBias = 0;
rasterDesc.SlopeScaledDepthBias = 0.0f;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = TRUE;
rasterDesc.ScissorEnable = FALSE;
rasterDesc.MultisampleEnable = FALSE;
rasterDesc.AntialiasedLineEnable = FALSE;
dx_ctx.device->lpVtbl->CreateRasterizerState(dx_ctx.device, &rasterDesc, &state->impl.rasterizerState);
rasterDesc.ScissorEnable = TRUE;
dx_ctx.device->lpVtbl->CreateRasterizerState(dx_ctx.device, &rasterDesc, &state->impl.rasterizerStateScissor);
// We need d3d11_3 for conservative raster
// D3D11_RASTERIZER_DESC2 rasterDesc;
// rasterDesc.ConservativeRaster = conservativeRasterization ? D3D11_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF;
// dx_ctx.device->CreateRasterizerState2(&rasterDesc, &rasterizerState);
// rasterDesc.ScissorEnable = TRUE;
// dx_ctx.device->CreateRasterizerState2(&rasterDesc, &rasterizerStateScissor);
}
{
bool independentBlend = false;
for (int i = 1; i < 8; ++i) {
if (state->color_write_mask_red[0] != state->color_write_mask_red[i] || state->color_write_mask_green[0] != state->color_write_mask_green[i] ||
state->color_write_mask_blue[0] != state->color_write_mask_blue[i] || state->color_write_mask_alpha[0] != state->color_write_mask_alpha[i]) {
independentBlend = true;
break;
}
}
D3D11_BLEND_DESC blendDesc;
memset(&blendDesc, 0, sizeof(blendDesc));
blendDesc.AlphaToCoverageEnable = false;
blendDesc.IndependentBlendEnable = independentBlend;
D3D11_RENDER_TARGET_BLEND_DESC rtbd[8];
memset(&rtbd, 0, sizeof(rtbd));
createRenderTargetBlendDesc(state, &rtbd[0], 0);
blendDesc.RenderTarget[0] = rtbd[0];
if (independentBlend) {
for (int i = 1; i < 8; ++i) {
createRenderTargetBlendDesc(state, &rtbd[i], i);
blendDesc.RenderTarget[i] = rtbd[i];
}
}
dx_ctx.device->lpVtbl->CreateBlendState(dx_ctx.device, &blendDesc, &state->impl.blendState);
}
}

View File

@ -0,0 +1,37 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct ID3D11InputLayout;
struct ID3D11PixelShader;
struct ID3D11VertexShader;
struct ID3D11Buffer;
struct ID3D11DepthStencilState;
struct ID3D11RasterizerState;
struct ID3D11BlendState;
typedef struct {
// PipelineStateImpl();
//~PipelineStateImpl();
struct ID3D11InputLayout *d3d11inputLayout;
struct ID3D11Buffer *fragmentConstantBuffer;
struct ID3D11Buffer *vertexConstantBuffer;
struct ID3D11Buffer *geometryConstantBuffer;
struct ID3D11Buffer *tessEvalConstantBuffer;
struct ID3D11Buffer *tessControlConstantBuffer;
struct ID3D11DepthStencilState *depthStencilState;
struct ID3D11RasterizerState *rasterizerState;
struct ID3D11RasterizerState *rasterizerStateScissor;
struct ID3D11BlendState *blendState;
// void set(Graphics4::PipelineState* pipeline, bool scissoring);
// void setRasterizerState(bool scissoring);
// static void setConstants();
} kinc_g4_pipeline_impl_t;
void kinc_internal_set_constants(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,468 @@
#include <kinc/error.h>
#include <kinc/graphics4/rendertarget.h>
#include <kinc/log.h>
static DXGI_FORMAT convertRenderTargetFormat(kinc_g4_render_target_format_t format) {
switch (format) {
case KINC_G4_RENDER_TARGET_FORMAT_128BIT_FLOAT:
return DXGI_FORMAT_R32G32B32A32_FLOAT;
case KINC_G4_RENDER_TARGET_FORMAT_64BIT_FLOAT:
return DXGI_FORMAT_R16G16B16A16_FLOAT;
case KINC_G4_RENDER_TARGET_FORMAT_32BIT_RED_FLOAT:
return DXGI_FORMAT_R32_FLOAT;
case KINC_G4_RENDER_TARGET_FORMAT_16BIT_RED_FLOAT:
return DXGI_FORMAT_R16_FLOAT;
case KINC_G4_RENDER_TARGET_FORMAT_8BIT_RED:
return DXGI_FORMAT_R8_UNORM;
case KINC_G4_RENDER_TARGET_FORMAT_32BIT:
default:
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
}
static int formatRenderTargetByteSize(kinc_g4_render_target_format_t format) {
switch (format) {
case KINC_G4_RENDER_TARGET_FORMAT_128BIT_FLOAT:
return 16;
case KINC_G4_RENDER_TARGET_FORMAT_64BIT_FLOAT:
return 8;
case KINC_G4_RENDER_TARGET_FORMAT_32BIT_RED_FLOAT:
return 4;
case KINC_G4_RENDER_TARGET_FORMAT_16BIT_RED_FLOAT:
return 2;
case KINC_G4_RENDER_TARGET_FORMAT_8BIT_RED:
return 1;
case KINC_G4_RENDER_TARGET_FORMAT_32BIT:
default:
return 4;
}
}
void kinc_g4_render_target_init_with_multisampling(kinc_g4_render_target_t *renderTarget, int width, int height, kinc_g4_render_target_format_t format,
int depthBufferBits, int stencilBufferBits, int samples_per_pixel) {
renderTarget->isCubeMap = false;
renderTarget->isDepthAttachment = false;
renderTarget->texWidth = renderTarget->width = width;
renderTarget->texHeight = renderTarget->height = height;
renderTarget->impl.format = format;
renderTarget->impl.textureStaging = NULL;
D3D11_TEXTURE2D_DESC desc;
desc.Width = width;
desc.Height = height;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = convertRenderTargetFormat(format);
if (format == KINC_G4_RENDER_TARGET_FORMAT_16BIT_DEPTH) {
renderTarget->isDepthAttachment = true;
depthBufferBits = 16;
stencilBufferBits = 0;
}
bool antialiasing = samples_per_pixel > 1;
if (antialiasing) {
desc.SampleDesc.Count = samples_per_pixel;
desc.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
}
else {
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
}
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0; // D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
renderTarget->impl.textureRender = NULL;
renderTarget->impl.textureSample = NULL;
renderTarget->impl.renderTargetSRV = NULL;
for (int i = 0; i < 6; i++) {
renderTarget->impl.renderTargetViewRender[i] = NULL;
renderTarget->impl.renderTargetViewSample[i] = NULL;
}
if (!renderTarget->isDepthAttachment) {
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, NULL, &renderTarget->impl.textureRender));
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
renderTargetViewDesc.Format = desc.Format;
renderTargetViewDesc.ViewDimension = antialiasing ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateRenderTargetView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.textureRender,
&renderTargetViewDesc, &renderTarget->impl.renderTargetViewRender[0]));
if (antialiasing) {
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, NULL, &renderTarget->impl.textureSample));
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
renderTargetViewDesc.Format = desc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateRenderTargetView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.textureSample,
&renderTargetViewDesc, &renderTarget->impl.renderTargetViewSample[0]));
}
else {
renderTarget->impl.textureSample = renderTarget->impl.textureRender;
renderTarget->impl.renderTargetViewSample[0] = renderTarget->impl.renderTargetViewRender[0];
}
}
renderTarget->impl.depthStencil = NULL;
renderTarget->impl.depthStencilSRV = NULL;
for (int i = 0; i < 6; i++) {
renderTarget->impl.depthStencilView[i] = NULL;
}
DXGI_FORMAT depthFormat;
DXGI_FORMAT depthViewFormat;
DXGI_FORMAT depthResourceFormat;
if (depthBufferBits == 16 && stencilBufferBits == 0) {
depthFormat = DXGI_FORMAT_R16_TYPELESS;
depthViewFormat = DXGI_FORMAT_D16_UNORM;
depthResourceFormat = DXGI_FORMAT_R16_UNORM;
}
else {
depthFormat = DXGI_FORMAT_R24G8_TYPELESS;
depthViewFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthResourceFormat = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
if (depthBufferBits > 0) {
D3D11_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Format = depthFormat;
depthStencilDesc.Width = width;
depthStencilDesc.Height = height;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
if (antialiasing) {
depthStencilDesc.SampleDesc.Count = 4;
depthStencilDesc.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
}
else {
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
}
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &depthStencilDesc, NULL, &renderTarget->impl.depthStencil));
D3D11_DEPTH_STENCIL_VIEW_DESC viewDesc;
viewDesc.Format = depthViewFormat;
viewDesc.ViewDimension = antialiasing ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;
viewDesc.Flags = 0;
if (!antialiasing) {
viewDesc.Texture2D.MipSlice = 0;
}
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateDepthStencilView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.depthStencil, &viewDesc,
&renderTarget->impl.depthStencilView[0]));
}
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
if (!renderTarget->isDepthAttachment) {
shaderResourceViewDesc.Format = desc.Format;
shaderResourceViewDesc.ViewDimension = antialiasing ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.textureSample,
&shaderResourceViewDesc, &renderTarget->impl.renderTargetSRV));
}
if (depthBufferBits > 0) {
shaderResourceViewDesc.Format = depthResourceFormat;
shaderResourceViewDesc.ViewDimension = antialiasing ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.depthStencil,
&shaderResourceViewDesc, &renderTarget->impl.depthStencilSRV));
}
if (renderTarget->impl.renderTargetViewRender[0] != NULL) {
FLOAT colors[4] = {0, 0, 0, 0};
dx_ctx.context->lpVtbl->ClearRenderTargetView(dx_ctx.context, renderTarget->impl.renderTargetViewRender[0], colors);
}
}
void kinc_g4_render_target_init_cube_with_multisampling(kinc_g4_render_target_t *renderTarget, int cubeMapSize, kinc_g4_render_target_format_t format,
int depthBufferBits, int stencilBufferBits, int samples_per_pixel) {
renderTarget->width = cubeMapSize;
renderTarget->height = cubeMapSize;
renderTarget->isCubeMap = true;
renderTarget->isDepthAttachment = false;
renderTarget->texWidth = renderTarget->width;
renderTarget->texHeight = renderTarget->height;
renderTarget->impl.format = format;
renderTarget->impl.textureStaging = NULL;
D3D11_TEXTURE2D_DESC desc;
desc.Width = renderTarget->width;
desc.Height = renderTarget->height;
desc.MipLevels = 1;
desc.ArraySize = 6;
desc.Format = convertRenderTargetFormat(format);
if (format == KINC_G4_RENDER_TARGET_FORMAT_16BIT_DEPTH) {
renderTarget->isDepthAttachment = true;
depthBufferBits = 16;
stencilBufferBits = 0;
}
bool antialiasing = samples_per_pixel > 1;
if (antialiasing) {
desc.SampleDesc.Count = samples_per_pixel;
desc.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
}
else {
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
}
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0; // D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
renderTarget->impl.textureRender = NULL;
renderTarget->impl.textureSample = NULL;
renderTarget->impl.renderTargetSRV = NULL;
for (int i = 0; i < 6; i++) {
renderTarget->impl.renderTargetViewRender[i] = NULL;
renderTarget->impl.renderTargetViewSample[i] = NULL;
}
if (!renderTarget->isDepthAttachment) {
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, NULL, &renderTarget->impl.textureRender));
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
renderTargetViewDesc.Format = desc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
renderTargetViewDesc.Texture2DArray.MipSlice = 0;
renderTargetViewDesc.Texture2DArray.ArraySize = 1;
for (int i = 0; i < 6; i++) {
renderTargetViewDesc.Texture2DArray.FirstArraySlice = i;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateRenderTargetView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.textureRender,
&renderTargetViewDesc, &renderTarget->impl.renderTargetViewRender[i]));
}
if (antialiasing) {
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, NULL, &renderTarget->impl.textureSample));
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
renderTargetViewDesc.Format = desc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
renderTargetViewDesc.Texture2D.MipSlice = 0;
renderTargetViewDesc.Texture2DArray.ArraySize = 1;
for (int i = 0; i < 6; i++) {
renderTargetViewDesc.Texture2DArray.FirstArraySlice = i;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateRenderTargetView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.textureSample,
&renderTargetViewDesc, &renderTarget->impl.renderTargetViewSample[i]));
}
}
else {
renderTarget->impl.textureSample = renderTarget->impl.textureRender;
for (int i = 0; i < 6; i++) {
renderTarget->impl.renderTargetViewSample[i] = renderTarget->impl.renderTargetViewRender[i];
}
}
}
renderTarget->impl.depthStencil = NULL;
renderTarget->impl.depthStencilSRV = NULL;
for (int i = 0; i < 6; i++) {
renderTarget->impl.depthStencilView[i] = NULL;
}
DXGI_FORMAT depthFormat;
DXGI_FORMAT depthViewFormat;
DXGI_FORMAT depthResourceFormat;
if (depthBufferBits == 16 && stencilBufferBits == 0) {
depthFormat = DXGI_FORMAT_R16_TYPELESS;
depthViewFormat = DXGI_FORMAT_D16_UNORM;
depthResourceFormat = DXGI_FORMAT_R16_UNORM;
}
else {
depthFormat = DXGI_FORMAT_R24G8_TYPELESS;
depthViewFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthResourceFormat = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
if (depthBufferBits > 0) {
D3D11_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Format = depthFormat;
depthStencilDesc.Width = renderTarget->width;
depthStencilDesc.Height = renderTarget->height;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
depthStencilDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.ArraySize = 6;
if (antialiasing) {
depthStencilDesc.SampleDesc.Count = 4;
depthStencilDesc.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
}
else {
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
}
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &depthStencilDesc, NULL, &renderTarget->impl.depthStencil));
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
depthStencilViewDesc.Format = depthViewFormat;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
depthStencilViewDesc.Texture2DArray.MipSlice = 0;
depthStencilViewDesc.Texture2DArray.ArraySize = 1;
depthStencilViewDesc.Flags = 0;
for (int i = 0; i < 6; i++) {
depthStencilViewDesc.Texture2DArray.FirstArraySlice = i;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateDepthStencilView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.depthStencil,
&depthStencilViewDesc, &renderTarget->impl.depthStencilView[i]));
}
}
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
if (!renderTarget->isDepthAttachment) {
shaderResourceViewDesc.Format = desc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
shaderResourceViewDesc.TextureCube.MostDetailedMip = 0;
shaderResourceViewDesc.TextureCube.MipLevels = 1;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.textureSample,
&shaderResourceViewDesc, &renderTarget->impl.renderTargetSRV));
}
if (depthBufferBits > 0) {
shaderResourceViewDesc.Format = depthResourceFormat;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
shaderResourceViewDesc.TextureCube.MostDetailedMip = 0;
shaderResourceViewDesc.TextureCube.MipLevels = 1;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)renderTarget->impl.depthStencil,
&shaderResourceViewDesc, &renderTarget->impl.depthStencilSRV));
}
if (!renderTarget->isDepthAttachment) {
FLOAT colors[4] = {0, 0, 0, 0};
for (int i = 0; i < 6; i++) {
dx_ctx.context->lpVtbl->ClearRenderTargetView(dx_ctx.context, renderTarget->impl.renderTargetViewRender[i], colors);
}
}
}
void kinc_g4_render_target_destroy(kinc_g4_render_target_t *renderTarget) {
for (int i = 0; i < 6; i++) {
if (renderTarget->impl.renderTargetViewRender[i] != NULL)
renderTarget->impl.renderTargetViewRender[i]->lpVtbl->Release(renderTarget->impl.renderTargetViewRender[i]);
if (renderTarget->impl.renderTargetViewSample[i] != NULL &&
renderTarget->impl.renderTargetViewSample[i] != renderTarget->impl.renderTargetViewRender[i])
renderTarget->impl.renderTargetViewSample[i]->lpVtbl->Release(renderTarget->impl.renderTargetViewSample[i]);
if (renderTarget->impl.depthStencilView[i] != NULL)
renderTarget->impl.depthStencilView[i]->lpVtbl->Release(renderTarget->impl.depthStencilView[i]);
}
if (renderTarget->impl.renderTargetSRV != NULL)
renderTarget->impl.renderTargetSRV->lpVtbl->Release(renderTarget->impl.renderTargetSRV);
if (renderTarget->impl.depthStencilSRV != NULL)
renderTarget->impl.depthStencilSRV->lpVtbl->Release(renderTarget->impl.depthStencilSRV);
if (renderTarget->impl.depthStencil != NULL)
renderTarget->impl.depthStencil->lpVtbl->Release(renderTarget->impl.depthStencil);
if (renderTarget->impl.textureRender != NULL)
renderTarget->impl.textureRender->lpVtbl->Release(renderTarget->impl.textureRender);
if (renderTarget->impl.textureStaging != NULL)
renderTarget->impl.textureStaging->lpVtbl->Release(renderTarget->impl.textureStaging);
if (renderTarget->impl.textureSample != NULL && renderTarget->impl.textureSample != renderTarget->impl.textureRender)
renderTarget->impl.textureSample->lpVtbl->Release(renderTarget->impl.textureSample);
}
#ifdef KINC_KONG
void kinc_g4_render_target_use_color_as_texture(kinc_g4_render_target_t *renderTarget, uint32_t unit) {
if (renderTarget->impl.textureSample != renderTarget->impl.textureRender) {
dx_ctx.context->lpVtbl->ResolveSubresource(dx_ctx.context, (ID3D11Resource *)renderTarget->impl.textureSample, 0,
(ID3D11Resource *)renderTarget->impl.textureRender, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
}
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, unit, 1,
renderTarget->isDepthAttachment ? &renderTarget->impl.depthStencilSRV : &renderTarget->impl.renderTargetSRV);
}
#else
void kinc_g4_render_target_use_color_as_texture(kinc_g4_render_target_t *renderTarget, kinc_g4_texture_unit_t unit) {
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] < 0 && unit.stages[KINC_G4_SHADER_TYPE_VERTEX] < 0)
return;
if (renderTarget->impl.textureSample != renderTarget->impl.textureRender) {
dx_ctx.context->lpVtbl->ResolveSubresource(dx_ctx.context, (ID3D11Resource *)renderTarget->impl.textureSample, 0,
(ID3D11Resource *)renderTarget->impl.textureRender, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
}
if (unit.stages[KINC_G4_SHADER_TYPE_VERTEX] >= 0) {
dx_ctx.context->lpVtbl->VSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_VERTEX], 1,
renderTarget->isDepthAttachment ? &renderTarget->impl.depthStencilSRV
: &renderTarget->impl.renderTargetSRV);
}
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] >= 0) {
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], 1,
renderTarget->isDepthAttachment ? &renderTarget->impl.depthStencilSRV
: &renderTarget->impl.renderTargetSRV);
}
}
#endif
void kinc_g4_render_target_use_depth_as_texture(kinc_g4_render_target_t *renderTarget, kinc_g4_texture_unit_t unit) {
if (unit.stages[KINC_G4_SHADER_TYPE_VERTEX] >= 0) {
dx_ctx.context->lpVtbl->VSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_VERTEX], 1, &renderTarget->impl.depthStencilSRV);
}
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] >= 0) {
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], 1, &renderTarget->impl.depthStencilSRV);
}
}
void kinc_g4_render_target_set_depth_stencil_from(kinc_g4_render_target_t *renderTarget, kinc_g4_render_target_t *source) {
renderTarget->impl.depthStencil = source->impl.depthStencil;
for (int i = 0; i < 6; i++) {
renderTarget->impl.depthStencilView[i] = source->impl.depthStencilView[i];
}
renderTarget->impl.depthStencilSRV = source->impl.depthStencilSRV;
}
void kinc_g4_render_target_get_pixels(kinc_g4_render_target_t *renderTarget, uint8_t *data) {
if (renderTarget->impl.textureStaging == NULL) {
D3D11_TEXTURE2D_DESC desc;
desc.Width = renderTarget->texWidth;
desc.Height = renderTarget->texHeight;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = convertRenderTargetFormat((kinc_g4_render_target_format_t)renderTarget->impl.format);
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, NULL, &renderTarget->impl.textureStaging));
}
D3D11_BOX sourceRegion;
sourceRegion.left = 0;
sourceRegion.right = renderTarget->texWidth;
sourceRegion.top = 0;
sourceRegion.bottom = renderTarget->texHeight;
sourceRegion.front = 0;
sourceRegion.back = 1;
dx_ctx.context->lpVtbl->CopySubresourceRegion(dx_ctx.context, (ID3D11Resource *)renderTarget->impl.textureStaging, 0, 0, 0, 0,
(ID3D11Resource *)renderTarget->impl.textureRender, 0, &sourceRegion);
D3D11_MAPPED_SUBRESOURCE mappedResource;
dx_ctx.context->lpVtbl->Map(dx_ctx.context, (ID3D11Resource *)renderTarget->impl.textureStaging, 0, D3D11_MAP_READ, 0, &mappedResource);
int size;
if (mappedResource.RowPitch != 0) {
size = mappedResource.RowPitch * renderTarget->texHeight;
}
else {
size = renderTarget->texWidth * renderTarget->texHeight * formatRenderTargetByteSize((kinc_g4_render_target_format_t)renderTarget->impl.format);
}
memcpy(data, mappedResource.pData, size);
dx_ctx.context->lpVtbl->Unmap(dx_ctx.context, (ID3D11Resource *)renderTarget->impl.textureStaging, 0);
}
void kinc_g4_render_target_generate_mipmaps(kinc_g4_render_target_t *renderTarget, int levels) {}

View File

@ -0,0 +1,27 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct ID3D11Texture2D;
struct ID3D11RenderTargetView;
struct ID3D11DepthStencilView;
struct ID3D11ShaderResourceView;
typedef struct {
struct ID3D11Texture2D *textureRender;
struct ID3D11Texture2D *textureSample;
struct ID3D11Texture2D *textureStaging;
struct ID3D11RenderTargetView *renderTargetViewRender[6];
struct ID3D11RenderTargetView *renderTargetViewSample[6];
struct ID3D11Texture2D *depthStencil;
struct ID3D11DepthStencilView *depthStencilView[6];
struct ID3D11ShaderResourceView *renderTargetSRV;
struct ID3D11ShaderResourceView *depthStencilSRV;
int format;
} kinc_g4_render_target_impl_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,114 @@
#include <kinc/graphics4/shader.h>
void kinc_g4_shader_destroy(kinc_g4_shader_t *shader) {
if (shader->impl.shader != NULL) {
((IUnknown *)shader->impl.shader)->lpVtbl->Release(shader->impl.shader);
free(shader->impl.data);
}
}
void kinc_g4_shader_init(kinc_g4_shader_t *shader, const void *_data, size_t length, kinc_g4_shader_type_t type) {
unsigned index = 0;
uint8_t *data = (uint8_t *)_data;
shader->impl.type = (int)type;
#ifndef KINC_KONG
memset(&shader->impl.attributes, 0, sizeof(shader->impl.attributes));
int attributesCount = data[index++];
for (int i = 0; i < attributesCount; ++i) {
unsigned char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
shader->impl.attributes[i].hash = kinc_internal_hash_name(name);
shader->impl.attributes[i].index = data[index++];
}
memset(&shader->impl.textures, 0, sizeof(shader->impl.textures));
uint8_t texCount = data[index++];
for (unsigned i = 0; i < texCount; ++i) {
unsigned char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
shader->impl.textures[i].hash = kinc_internal_hash_name(name);
shader->impl.textures[i].index = data[index++];
}
memset(&shader->impl.constants, 0, sizeof(shader->impl.constants));
uint8_t constantCount = data[index++];
shader->impl.constantsSize = 0;
for (unsigned i = 0; i < constantCount; ++i) {
unsigned char name[256];
for (unsigned i2 = 0; i2 < 255; ++i2) {
name[i2] = data[index++];
if (name[i2] == 0)
break;
}
kinc_internal_shader_constant_t constant;
constant.hash = kinc_internal_hash_name(name);
constant.offset = *(uint32_t *)&data[index];
index += 4;
constant.size = *(uint32_t *)&data[index];
index += 4;
constant.columns = data[index];
index += 1;
constant.rows = data[index];
index += 1;
shader->impl.constants[i] = constant;
shader->impl.constantsSize = constant.offset + constant.size;
}
#endif
shader->impl.length = (int)(length - index);
shader->impl.data = (uint8_t *)malloc(shader->impl.length);
assert(shader->impl.data != NULL);
memcpy(shader->impl.data, &data[index], shader->impl.length);
switch (type) {
case KINC_G4_SHADER_TYPE_VERTEX:
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateVertexShader(dx_ctx.device, shader->impl.data, shader->impl.length, NULL,
(ID3D11VertexShader **)&shader->impl.shader));
break;
case KINC_G4_SHADER_TYPE_FRAGMENT:
kinc_microsoft_affirm(
dx_ctx.device->lpVtbl->CreatePixelShader(dx_ctx.device, shader->impl.data, shader->impl.length, NULL, (ID3D11PixelShader **)&shader->impl.shader));
break;
case KINC_G4_SHADER_TYPE_GEOMETRY:
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateGeometryShader(dx_ctx.device, shader->impl.data, shader->impl.length, NULL,
(ID3D11GeometryShader **)&shader->impl.shader));
break;
case KINC_G4_SHADER_TYPE_TESSELLATION_CONTROL:
kinc_microsoft_affirm(
dx_ctx.device->lpVtbl->CreateHullShader(dx_ctx.device, shader->impl.data, shader->impl.length, NULL, (ID3D11HullShader **)&shader->impl.shader));
break;
case KINC_G4_SHADER_TYPE_TESSELLATION_EVALUATION:
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateDomainShader(dx_ctx.device, shader->impl.data, shader->impl.length, NULL,
(ID3D11DomainShader **)&shader->impl.shader));
break;
}
}
#ifdef KRAFIX_LIBRARY
extern int krafix_compile(const char *source, char *output, int *length, const char *targetlang, const char *system, const char *shadertype, int version);
#endif
int kinc_g4_shader_init_from_source(kinc_g4_shader_t *shader, const char *source, kinc_g4_shader_type_t type) {
#ifdef KRAFIX_LIBRARY
char *output = malloc(1024 * 1024);
int length;
int errors = krafix_compile(source, output, &length, "d3d11", "windows", type == KINC_G4_SHADER_TYPE_FRAGMENT ? "frag" : "vert", -1);
if (errors > 0) {
return errors;
}
kinc_g4_shader_init(shader, output, length, type);
return 0;
#else
return 0;
#endif
}

View File

@ -0,0 +1,62 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <kinc/backend/graphics4/ShaderHash.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t hash;
uint32_t offset;
uint32_t size;
uint8_t columns;
uint8_t rows;
} kinc_internal_shader_constant_t;
typedef struct {
#ifndef KINC_KONG
kinc_internal_shader_constant_t constants[64];
int constantsSize;
kinc_internal_hash_index_t attributes[64];
kinc_internal_hash_index_t textures[64];
#endif
void *shader;
uint8_t *data;
int length;
int type;
} kinc_g4_shader_impl_t;
typedef struct {
uint32_t vertexOffset;
uint32_t vertexSize;
uint32_t fragmentOffset;
uint32_t fragmentSize;
uint32_t geometryOffset;
uint32_t geometrySize;
uint32_t tessEvalOffset;
uint32_t tessEvalSize;
uint32_t tessControlOffset;
uint32_t tessControlSize;
uint32_t computeOffset;
uint32_t computeSize;
uint8_t vertexColumns;
uint8_t vertexRows;
uint8_t fragmentColumns;
uint8_t fragmentRows;
uint8_t geometryColumns;
uint8_t geometryRows;
uint8_t tessEvalColumns;
uint8_t tessEvalRows;
uint8_t tessControlColumns;
uint8_t tessControlRows;
uint8_t computeColumns;
uint8_t computeRows;
} kinc_g4_constant_location_impl_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,377 @@
#include <kinc/graphics4/texture.h>
#include <kinc/graphics4/textureunit.h>
#include <assert.h>
static kinc_g4_texture_t *setTextures[16] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
static DXGI_FORMAT convertFormat(kinc_image_format_t format) {
switch (format) {
case KINC_IMAGE_FORMAT_RGBA128:
return DXGI_FORMAT_R32G32B32A32_FLOAT;
case KINC_IMAGE_FORMAT_RGBA64:
return DXGI_FORMAT_R16G16B16A16_FLOAT;
case KINC_IMAGE_FORMAT_RGB24:
return DXGI_FORMAT_R8G8B8A8_UNORM;
case KINC_IMAGE_FORMAT_A32:
return DXGI_FORMAT_R32_FLOAT;
case KINC_IMAGE_FORMAT_A16:
return DXGI_FORMAT_R16_FLOAT;
case KINC_IMAGE_FORMAT_GREY8:
return DXGI_FORMAT_R8_UNORM;
case KINC_IMAGE_FORMAT_BGRA32:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case KINC_IMAGE_FORMAT_RGBA32:
return DXGI_FORMAT_R8G8B8A8_UNORM;
default:
assert(false);
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
}
static int formatByteSize(kinc_image_format_t format) {
switch (format) {
case KINC_IMAGE_FORMAT_RGBA128:
return 16;
case KINC_IMAGE_FORMAT_RGBA64:
return 8;
case KINC_IMAGE_FORMAT_RGB24:
return 4;
case KINC_IMAGE_FORMAT_A32:
return 4;
case KINC_IMAGE_FORMAT_A16:
return 2;
case KINC_IMAGE_FORMAT_GREY8:
return 1;
case KINC_IMAGE_FORMAT_BGRA32:
case KINC_IMAGE_FORMAT_RGBA32:
return 4;
default:
assert(false);
return 4;
}
}
static bool isHdr(kinc_image_format_t format) {
return format == KINC_IMAGE_FORMAT_RGBA128 || format == KINC_IMAGE_FORMAT_RGBA64 || format == KINC_IMAGE_FORMAT_A32 || format == KINC_IMAGE_FORMAT_A16;
}
void kinc_g4_texture_init_from_image(kinc_g4_texture_t *texture, kinc_image_t *image) {
memset(&texture->impl, 0, sizeof(texture->impl));
texture->impl.stage = 0;
texture->tex_width = image->width;
texture->tex_height = image->height;
texture->tex_depth = 1;
texture->format = image->format;
texture->impl.rowPitch = 0;
D3D11_TEXTURE2D_DESC desc;
desc.Width = image->width;
desc.Height = image->height;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = convertFormat(image->format);
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0; // D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = image->data;
data.SysMemPitch = image->width * formatByteSize(image->format);
data.SysMemSlicePitch = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, &data, &texture->impl.texture));
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture, NULL, &texture->impl.view));
}
void kinc_g4_texture_init_from_image3d(kinc_g4_texture_t *texture, kinc_image_t *image) {
memset(&texture->impl, 0, sizeof(texture->impl));
texture->impl.stage = 0;
texture->tex_width = image->width;
texture->tex_height = image->height;
texture->tex_depth = image->depth;
texture->format = image->format;
texture->impl.rowPitch = 0;
D3D11_TEXTURE3D_DESC desc;
desc.Width = image->width;
desc.Height = image->height;
desc.Depth = image->depth;
desc.MipLevels = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = 0;
desc.Format = convertFormat(image->format);
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = image->data;
data.SysMemPitch = image->width * formatByteSize(image->format);
data.SysMemSlicePitch = image->width * image->height * formatByteSize(image->format);
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture3D(dx_ctx.device, &desc, &data, &texture->impl.texture3D));
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture3D, NULL, &texture->impl.view));
}
void kinc_g4_texture_init(kinc_g4_texture_t *texture, int width, int height, kinc_image_format_t format) {
memset(&texture->impl, 0, sizeof(texture->impl));
texture->impl.stage = 0;
texture->tex_width = width;
texture->tex_height = height;
texture->tex_depth = 1;
texture->format = format;
D3D11_TEXTURE2D_DESC desc;
desc.Width = width;
desc.Height = height;
desc.MipLevels = desc.ArraySize = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = 0;
if (format == KINC_IMAGE_FORMAT_RGBA128) { // for compute
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
}
else {
desc.Format = convertFormat(format);
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
}
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, NULL, &texture->impl.texture));
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture, NULL, &texture->impl.view));
if (format == KINC_IMAGE_FORMAT_RGBA128) {
D3D11_UNORDERED_ACCESS_VIEW_DESC du;
du.Format = desc.Format;
du.Texture2D.MipSlice = 0;
du.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
kinc_microsoft_affirm(
dx_ctx.device->lpVtbl->CreateUnorderedAccessView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture, &du, &texture->impl.computeView));
}
}
void kinc_g4_texture_init3d(kinc_g4_texture_t *texture, int width, int height, int depth, kinc_image_format_t format) {
memset(&texture->impl, 0, sizeof(texture->impl));
texture->impl.stage = 0;
texture->tex_width = width;
texture->tex_height = height;
texture->tex_depth = depth;
texture->format = format;
texture->impl.hasMipmaps = true;
D3D11_TEXTURE3D_DESC desc;
desc.Width = width;
desc.Height = height;
desc.Depth = depth;
desc.MipLevels = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
desc.Format = format == KINC_IMAGE_FORMAT_RGBA32 ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R8_UNORM;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET | D3D11_BIND_UNORDERED_ACCESS;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture3D(dx_ctx.device, &desc, NULL, &texture->impl.texture3D));
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture3D, NULL, &texture->impl.view));
}
// TextureImpl::TextureImpl() : hasMipmaps(false), renderView(nullptr), computeView(nullptr) {}
void kinc_internal_texture_unset(kinc_g4_texture_t *texture);
void kinc_g4_texture_destroy(kinc_g4_texture_t *texture) {
kinc_internal_texture_unset(texture);
if (texture->impl.view != NULL) {
texture->impl.view->lpVtbl->Release(texture->impl.view);
}
if (texture->impl.texture != NULL) {
texture->impl.texture->lpVtbl->Release(texture->impl.texture);
}
if (texture->impl.texture3D != NULL) {
texture->impl.texture3D->lpVtbl->Release(texture->impl.texture3D);
}
if (texture->impl.computeView != NULL) {
texture->impl.computeView->lpVtbl->Release(texture->impl.computeView);
}
}
void kinc_internal_texture_unmipmap(kinc_g4_texture_t *texture) {
texture->impl.hasMipmaps = false;
}
#ifdef KINC_KONG
void kinc_internal_texture_set(kinc_g4_texture_t *texture, uint32_t unit) {
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, unit, 1, &texture->impl.view);
texture->impl.stage = unit;
setTextures[unit] = texture;
}
#else
void kinc_internal_texture_set(kinc_g4_texture_t *texture, kinc_g4_texture_unit_t unit) {
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] < 0 && unit.stages[KINC_G4_SHADER_TYPE_VERTEX] < 0 && unit.stages[KINC_G4_SHADER_TYPE_COMPUTE] < 0)
return;
if (unit.stages[KINC_G4_SHADER_TYPE_VERTEX] >= 0) {
dx_ctx.context->lpVtbl->VSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_VERTEX], 1, &texture->impl.view);
}
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] >= 0) {
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], 1, &texture->impl.view);
}
if (unit.stages[KINC_G4_SHADER_TYPE_COMPUTE] >= 0) {
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_COMPUTE], 1, &texture->impl.view);
}
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] >= 0 || unit.stages[KINC_G4_SHADER_TYPE_VERTEX] >= 0) {
texture->impl.stage =
unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] >= 0 ? unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] : unit.stages[KINC_G4_SHADER_TYPE_VERTEX];
setTextures[texture->impl.stage] = texture;
}
}
#endif
void kinc_internal_texture_set_image(kinc_g4_texture_t *texture, kinc_g4_texture_unit_t unit) {
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] < 0 && unit.stages[KINC_G4_SHADER_TYPE_VERTEX] < 0 && unit.stages[KINC_G4_SHADER_TYPE_COMPUTE] < 0)
return;
if (texture->impl.computeView == NULL) {
D3D11_UNORDERED_ACCESS_VIEW_DESC du;
du.Format = texture->format == KINC_IMAGE_FORMAT_RGBA32 ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R8_UNORM;
du.Texture3D.MipSlice = 0;
du.Texture3D.FirstWSlice = 0;
du.Texture3D.WSize = -1;
du.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
kinc_microsoft_affirm(
dx_ctx.device->lpVtbl->CreateUnorderedAccessView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture3D, &du, &texture->impl.computeView));
}
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] >= 0) {
ID3D11ShaderResourceView *nullView = NULL;
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, 0, 1, &nullView);
dx_ctx.context->lpVtbl->CSSetUnorderedAccessViews(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], 1, &texture->impl.computeView, NULL);
}
if (unit.stages[KINC_G4_SHADER_TYPE_VERTEX] >= 0) {
ID3D11ShaderResourceView *nullView = NULL;
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, 0, 1, &nullView);
dx_ctx.context->lpVtbl->CSSetUnorderedAccessViews(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_VERTEX], 1, &texture->impl.computeView, NULL);
}
if (unit.stages[KINC_G4_SHADER_TYPE_COMPUTE] >= 0) {
ID3D11ShaderResourceView *nullView = NULL;
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, 0, 1, &nullView);
dx_ctx.context->lpVtbl->CSSetUnorderedAccessViews(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_COMPUTE], 1, &texture->impl.computeView, NULL);
}
}
void kinc_internal_texture_unset(kinc_g4_texture_t *texture) {
if (setTextures[texture->impl.stage] == texture) {
setTextures[texture->impl.stage] = NULL;
}
}
uint8_t *kinc_g4_texture_lock(kinc_g4_texture_t *texture) {
D3D11_MAPPED_SUBRESOURCE mappedResource;
kinc_microsoft_affirm(dx_ctx.context->lpVtbl->Map(dx_ctx.context, (ID3D11Resource *)texture->impl.texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
texture->impl.rowPitch = mappedResource.RowPitch;
return (uint8_t *)mappedResource.pData;
}
void kinc_g4_texture_unlock(kinc_g4_texture_t *texture) {
dx_ctx.context->lpVtbl->Unmap(dx_ctx.context, (ID3D11Resource *)texture->impl.texture, 0);
}
void kinc_g4_texture_clear(kinc_g4_texture_t *texture, int x, int y, int z, int width, int height, int depth, unsigned color) {
if (texture->impl.renderView == NULL) {
texture->tex_depth > 1 ? kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateRenderTargetView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture3D,
0, &texture->impl.renderView))
: kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateRenderTargetView(dx_ctx.device, (ID3D11Resource *)texture->impl.texture, 0,
&texture->impl.renderView));
}
static float clearColor[4];
clearColor[0] = ((color & 0x00ff0000) >> 16) / 255.0f;
clearColor[1] = ((color & 0x0000ff00) >> 8) / 255.0f;
clearColor[2] = (color & 0x000000ff) / 255.0f;
clearColor[3] = ((color & 0xff000000) >> 24) / 255.0f;
dx_ctx.context->lpVtbl->ClearRenderTargetView(dx_ctx.context, texture->impl.renderView, clearColor);
}
int kinc_g4_texture_stride(kinc_g4_texture_t *texture) {
assert(texture->impl.rowPitch != 0); // stride is not yet set, lock and unlock the texture first (or find a good fix for this and send a PR)
return texture->impl.rowPitch;
}
static void enableMipmaps(kinc_g4_texture_t *texture, int texWidth, int texHeight, int format) {
D3D11_TEXTURE2D_DESC desc;
desc.Width = texWidth;
desc.Height = texHeight;
desc.MipLevels = 0;
desc.ArraySize = 1;
desc.Format = convertFormat((kinc_image_format_t)format);
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
ID3D11Texture2D *mipMappedTexture;
ID3D11ShaderResourceView *mipMappedView;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, NULL, &mipMappedTexture));
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)mipMappedTexture, NULL, &mipMappedView));
D3D11_BOX sourceRegion;
sourceRegion.left = 0;
sourceRegion.right = texWidth;
sourceRegion.top = 0;
sourceRegion.bottom = texHeight;
sourceRegion.front = 0;
sourceRegion.back = 1;
dx_ctx.context->lpVtbl->CopySubresourceRegion(dx_ctx.context, (ID3D11Resource *)mipMappedTexture, 0, 0, 0, 0, (ID3D11Resource *)texture->impl.texture, 0,
&sourceRegion);
if (texture->impl.texture != NULL) {
texture->impl.texture->lpVtbl->Release(texture->impl.texture);
}
texture->impl.texture = mipMappedTexture;
if (texture->impl.view != NULL) {
texture->impl.view->lpVtbl->Release(texture->impl.view);
}
texture->impl.view = mipMappedView;
texture->impl.hasMipmaps = true;
}
void kinc_g4_texture_generate_mipmaps(kinc_g4_texture_t *texture, int levels) {
if (!texture->impl.hasMipmaps) {
enableMipmaps(texture, texture->tex_width, texture->tex_height, texture->format);
}
dx_ctx.context->lpVtbl->GenerateMips(dx_ctx.context, texture->impl.view);
}
void kinc_g4_texture_set_mipmap(kinc_g4_texture_t *texture, kinc_image_t *mipmap, int level) {
if (!texture->impl.hasMipmaps) {
enableMipmaps(texture, texture->tex_width, texture->tex_height, texture->format);
}
D3D11_BOX dstRegion;
dstRegion.left = 0;
dstRegion.right = mipmap->width;
dstRegion.top = 0;
dstRegion.bottom = mipmap->height;
dstRegion.front = 0;
dstRegion.back = 1;
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)texture->impl.texture, level, &dstRegion, mipmap->data,
mipmap->width * formatByteSize(mipmap->format), 0);
}

View File

@ -0,0 +1,24 @@
#pragma once
struct ID3D11Texture2D;
struct ID3D11Texture3D;
struct ID3D11ShaderResourceView;
struct ID3D11UnorderedAccessView;
struct ID3D11RenderTargetView;
// TextureImpl();
//~TextureImpl();
// void enableMipmaps(int texWidth, int texHeight, int format);
// void unmipmap();
// void unset();
typedef struct {
bool hasMipmaps;
int stage;
struct ID3D11Texture2D *texture;
struct ID3D11Texture3D *texture3D;
struct ID3D11ShaderResourceView *view;
struct ID3D11UnorderedAccessView *computeView;
struct ID3D11RenderTargetView *renderView;
int rowPitch;
} kinc_g4_texture_impl_t;

View File

@ -0,0 +1,39 @@
#include <kinc/graphics4/texturearray.h>
#include <kinc/graphics4/textureunit.h>
void kinc_g4_texture_array_init(kinc_g4_texture_array_t *array, kinc_image_t *textures, int count) {
D3D11_TEXTURE2D_DESC desc;
desc.Width = textures[0].width;
desc.Height = textures[0].height;
desc.MipLevels = 1;
desc.ArraySize = 2;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA *resdata = (D3D11_SUBRESOURCE_DATA *)alloca(sizeof(D3D11_SUBRESOURCE_DATA) * count);
for (int i = 0; i < count; ++i) {
resdata[i].pSysMem = textures[i].data;
resdata[i].SysMemPitch = textures[0].width * 4;
resdata[i].SysMemSlicePitch = 0;
}
array->impl.texture = NULL;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateTexture2D(dx_ctx.device, &desc, resdata, &array->impl.texture));
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateShaderResourceView(dx_ctx.device, (ID3D11Resource *)array->impl.texture, NULL, &array->impl.view));
}
void kinc_g4_texture_array_destroy(kinc_g4_texture_array_t *array) {}
void kinc_internal_texture_array_set(kinc_g4_texture_array_t *array, kinc_g4_texture_unit_t unit) {
if (unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT] < 0)
return;
dx_ctx.context->lpVtbl->PSSetShaderResources(dx_ctx.context, unit.stages[KINC_G4_SHADER_TYPE_FRAGMENT], 1, &array->impl.view);
// this->stage = unit.unit;
// setTextures[stage] = this;
}

View File

@ -0,0 +1,18 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct ID3D11Texture2D;
struct ID3D11ShaderResourceView;
typedef struct {
struct ID3D11Texture2D *texture;
struct ID3D11ShaderResourceView *view;
// void set(Kore::Graphics4::TextureUnit unit);
} kinc_g4_texture_array_impl_t;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,95 @@
#include <kinc/graphics4/vertexbuffer.h>
void kinc_g4_vertex_buffer_init(kinc_g4_vertex_buffer_t *buffer, int count, kinc_g4_vertex_structure_t *structure, kinc_g4_usage_t usage,
int instance_data_step_rate) {
buffer->impl.count = count;
buffer->impl.stride = 0;
for (int i = 0; i < structure->size; ++i) {
buffer->impl.stride += kinc_g4_vertex_data_size(structure->elements[i].data);
}
if (usage == KINC_G4_USAGE_DYNAMIC) {
buffer->impl.vertices = NULL;
}
else {
buffer->impl.vertices = (float *)malloc(buffer->impl.stride * count);
}
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.CPUAccessFlags = 0;
buffer->impl.usage = usage;
switch (usage) {
case KINC_G4_USAGE_STATIC:
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
break;
case KINC_G4_USAGE_DYNAMIC:
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
break;
case KINC_G4_USAGE_READABLE:
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
break;
}
bufferDesc.ByteWidth = buffer->impl.stride * count;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
kinc_microsoft_affirm(dx_ctx.device->lpVtbl->CreateBuffer(dx_ctx.device, &bufferDesc, NULL, &buffer->impl.vb));
}
void kinc_g4_vertex_buffer_destroy(kinc_g4_vertex_buffer_t *buffer) {
buffer->impl.vb->lpVtbl->Release(buffer->impl.vb);
free(buffer->impl.vertices);
buffer->impl.vertices = NULL;
}
float *kinc_g4_vertex_buffer_lock_all(kinc_g4_vertex_buffer_t *buffer) {
return kinc_g4_vertex_buffer_lock(buffer, 0, buffer->impl.count);
}
float *kinc_g4_vertex_buffer_lock(kinc_g4_vertex_buffer_t *buffer, int start, int count) {
buffer->impl.lockStart = start;
buffer->impl.lockCount = count;
if (buffer->impl.usage == KINC_G4_USAGE_DYNAMIC) {
D3D11_MAPPED_SUBRESOURCE mappedResource;
memset(&mappedResource, 0, sizeof(D3D11_MAPPED_SUBRESOURCE));
dx_ctx.context->lpVtbl->Map(dx_ctx.context, (ID3D11Resource *)buffer->impl.vb, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
float *data = (float *)mappedResource.pData;
return &data[start * buffer->impl.stride / 4];
}
else {
return &buffer->impl.vertices[start * buffer->impl.stride / 4];
}
}
void kinc_g4_vertex_buffer_unlock_all(kinc_g4_vertex_buffer_t *buffer) {
kinc_g4_vertex_buffer_unlock(buffer, buffer->impl.lockCount);
}
void kinc_g4_vertex_buffer_unlock(kinc_g4_vertex_buffer_t *buffer, int count) {
if (buffer->impl.usage == KINC_G4_USAGE_DYNAMIC) {
dx_ctx.context->lpVtbl->Unmap(dx_ctx.context, (ID3D11Resource *)buffer->impl.vb, 0);
}
else {
dx_ctx.context->lpVtbl->UpdateSubresource(dx_ctx.context, (ID3D11Resource *)buffer->impl.vb, 0, NULL, buffer->impl.vertices, 0, 0);
}
}
int kinc_internal_g4_vertex_buffer_set(kinc_g4_vertex_buffer_t *buffer, int offset) {
// UINT stride = myStride;
// UINT internaloffset = 0;
// dx_ctx.context->IASetVertexBuffers(0, 1, &vb, &stride, &internaloffset);
return 0;
}
int kinc_g4_vertex_buffer_count(kinc_g4_vertex_buffer_t *buffer) {
return buffer->impl.count;
}
int kinc_g4_vertex_buffer_stride(kinc_g4_vertex_buffer_t *buffer) {
return buffer->impl.stride;
}

View File

@ -0,0 +1,13 @@
#pragma once
struct ID3D11Buffer;
typedef struct {
struct ID3D11Buffer *vb;
int stride;
int count;
int lockStart;
int lockCount;
float *vertices;
int usage;
} kinc_g4_vertex_buffer_impl_t;