mirror of
https://github.com/libretro/RetroArch
synced 2025-02-01 20:54:10 +00:00
Combine gfx_display files into video drivers
This commit is contained in:
parent
d1b9badf41
commit
0ee2f93ca4
@ -1124,8 +1124,6 @@ ifeq ($(HAVE_VITA2D), 1)
|
||||
$(DEPS_DIR)/libvita2d/shader/texture_tint_v_gxp.o \
|
||||
$(DEPS_DIR)/libvita2d/shader/texture_tint_f_gxp.o
|
||||
|
||||
OBJ += gfx/drivers_display/gfx_display_vita2d.o
|
||||
|
||||
OBJ += gfx/drivers/vita2d_gfx.o
|
||||
|
||||
INCLUDE_DIRS += -I$(DEPS_DIR)/libvita2d/include
|
||||
@ -1133,7 +1131,6 @@ endif
|
||||
|
||||
ifeq ($(TARGET), retroarch_3ds)
|
||||
OBJ += gfx/drivers/ctr_gfx.o \
|
||||
gfx/drivers_display/gfx_display_ctr.o \
|
||||
input/drivers/ctr_input.o \
|
||||
input/drivers_joypad/ctr_joypad.o
|
||||
endif
|
||||
@ -1160,7 +1157,6 @@ endif
|
||||
|
||||
ifeq ($(TARGET), retroarch_wiiu)
|
||||
OBJ += gfx/drivers/gx2_gfx.o \
|
||||
gfx/drivers_display/gfx_display_wiiu.o \
|
||||
input/drivers/wiiu_input.o \
|
||||
input/drivers_joypad/wiiu_joypad.o \
|
||||
input/drivers_joypad/wiiu/wpad_driver.o \
|
||||
@ -1432,8 +1428,7 @@ endif
|
||||
ifeq ($(HAVE_VITAGL), 1)
|
||||
DEFINES += -DHAVE_OPENGL1 -DHAVE_VITAGL
|
||||
OBJ += gfx/drivers/gl1.o \
|
||||
gfx/drivers_context/vita_ctx.o \
|
||||
gfx/drivers_display/gfx_display_gl1.o
|
||||
gfx/drivers_context/vita_ctx.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VITAGLES), 1)
|
||||
@ -1445,16 +1440,14 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
ifeq ($(HAVE_GL_MODERN), 1)
|
||||
DEFINES += -DHAVE_OPENGL
|
||||
OBJ += gfx/drivers/gl2.o \
|
||||
$(LIBRETRO_COMM_DIR)/gfx/gl_capabilities.o \
|
||||
gfx/drivers_display/gfx_display_gl2.o
|
||||
$(LIBRETRO_COMM_DIR)/gfx/gl_capabilities.o
|
||||
endif
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/glsym/rglgen.o
|
||||
|
||||
ifeq ($(HAVE_OPENGL1), 1)
|
||||
DEFINES += -DHAVE_OPENGL1
|
||||
OBJ += gfx/drivers/gl1.o \
|
||||
gfx/drivers_display/gfx_display_gl1.o
|
||||
OBJ += gfx/drivers/gl1.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VIDEOCORE), 1)
|
||||
@ -1532,8 +1525,7 @@ ifeq ($(HAVE_METAL), 1)
|
||||
DEF_FLAGS += -fobjc-arc
|
||||
OBJ += \
|
||||
gfx/common/metal/metal_renderer.o \
|
||||
gfx/drivers/metal.o \
|
||||
gfx/drivers_display/gfx_display_metal.o
|
||||
gfx/drivers/metal.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
@ -1605,8 +1597,7 @@ ifeq ($(HAVE_VULKAN), 1)
|
||||
|
||||
OBJ += gfx/drivers/vulkan.o \
|
||||
gfx/common/vulkan_common.o \
|
||||
$(LIBRETRO_COMM_DIR)/vulkan/vulkan_symbol_wrapper.o \
|
||||
gfx/drivers_display/gfx_display_vulkan.o
|
||||
$(LIBRETRO_COMM_DIR)/vulkan/vulkan_symbol_wrapper.o
|
||||
|
||||
ifeq ($(HAVE_SLANG), 1)
|
||||
OBJ += gfx/drivers_shader/shader_vulkan.o
|
||||
@ -1622,8 +1613,7 @@ endif
|
||||
|
||||
ifeq ($(HAVE_OPENGL_CORE), 1)
|
||||
OBJ += gfx/drivers/gl3.o \
|
||||
gfx/drivers_shader/shader_gl3.o \
|
||||
gfx/drivers_display/gfx_display_gl3.o
|
||||
gfx/drivers_shader/shader_gl3.o
|
||||
|
||||
DEFINES += -DHAVE_OPENGL_CORE
|
||||
NEED_CXX_LINKER = 1
|
||||
@ -1683,31 +1673,27 @@ ifeq ($(HAVE_D3D9), 1)
|
||||
ifeq ($(HAVE_CG), 1)
|
||||
LIBS += -lcgD3D9
|
||||
OBJ += gfx/drivers/d3d9cg.o
|
||||
OBJ += gfx/drivers_display/gfx_display_d3d9cg.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D10), 1)
|
||||
HAVE_D3D_COMMON = 1
|
||||
OBJ += gfx/drivers/d3d10.o \
|
||||
gfx/common/d3d10_common.o \
|
||||
gfx/drivers_display/gfx_display_d3d10.o
|
||||
gfx/common/d3d10_common.o
|
||||
DEFINES += -DHAVE_D3D10
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D11), 1)
|
||||
HAVE_D3D_COMMON = 1
|
||||
OBJ += gfx/drivers/d3d11.o \
|
||||
gfx/common/d3d11_common.o \
|
||||
gfx/drivers_display/gfx_display_d3d11.o
|
||||
gfx/common/d3d11_common.o
|
||||
DEFINES += -DHAVE_D3D11
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D12), 1)
|
||||
HAVE_D3D_COMMON = 1
|
||||
OBJ += gfx/drivers/d3d12.o \
|
||||
gfx/common/d3d12_common.o \
|
||||
gfx/drivers_display/gfx_display_d3d12.o
|
||||
gfx/common/d3d12_common.o
|
||||
DEFINES += -DHAVE_D3D12
|
||||
endif
|
||||
|
||||
@ -1743,9 +1729,8 @@ endif
|
||||
|
||||
ifeq ($(HAVE_D3D8), 1)
|
||||
DEFINES += -DHAVE_D3D8
|
||||
OBJ += gfx/drivers/d3d8.o
|
||||
OBJ += gfx/common/d3d8_common.o
|
||||
OBJ += gfx/drivers_display/gfx_display_d3d8.o
|
||||
OBJ += gfx/drivers/d3d8.o \
|
||||
gfx/common/d3d8_common.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D9), 1)
|
||||
@ -1772,7 +1757,6 @@ endif
|
||||
ifeq ($(HAVE_HLSL),1)
|
||||
DEFINES += -DHAVE_HLSL
|
||||
OBJ += gfx/drivers/d3d9hlsl.o
|
||||
OBJ += gfx/drivers_display/gfx_display_d3d9hlsl.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SLANG),1)
|
||||
@ -2215,8 +2199,7 @@ ifneq ($(findstring Win32,$(OS)),)
|
||||
gfx/display_servers/dispserv_win32.o
|
||||
|
||||
ifeq ($(HAVE_GDI), 1)
|
||||
OBJ += gfx/drivers/gdi_gfx.o \
|
||||
gfx/drivers_display/gfx_display_gdi.o
|
||||
OBJ += gfx/drivers/gdi_gfx.o
|
||||
LIBS += -lmsimg32
|
||||
endif
|
||||
LIBS += -lhid -lsetupapi
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include "d3d10_common.h"
|
||||
#include "d3d10_defines.h"
|
||||
#include "d3dcompiler_common.h"
|
||||
|
||||
#if defined(HAVE_DYLIB) && !defined(__WINRT__)
|
||||
|
@ -13,7 +13,8 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _D3D10_DEFINES_H_
|
||||
#define _D3D10_DEFINES_H_
|
||||
|
||||
#include <retro_inline.h>
|
||||
|
||||
@ -224,19 +225,4 @@ typedef struct
|
||||
uint16_t flags;
|
||||
} d3d10_video_t;
|
||||
|
||||
static INLINE void d3d10_set_shader(D3D10Device ctx, d3d10_shader_t* shader)
|
||||
{
|
||||
ctx->lpVtbl->IASetInputLayout(ctx, shader->layout);
|
||||
ctx->lpVtbl->VSSetShader(ctx, shader->vs);
|
||||
ctx->lpVtbl->PSSetShader(ctx, shader->ps);
|
||||
ctx->lpVtbl->GSSetShader(ctx, shader->gs);
|
||||
}
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
static INLINE void
|
||||
d3d10_set_texture_and_sampler(D3D10Device ctx, UINT slot, d3d10_texture_t* texture)
|
||||
{
|
||||
ctx->lpVtbl->PSSetShaderResources(ctx, slot, 1, &texture->view);
|
||||
ctx->lpVtbl->PSSetSamplers(ctx, slot, 1, (D3D10SamplerState*)&texture->sampler);
|
||||
}
|
||||
#endif
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "d3d11_common.h"
|
||||
#include "d3d11_defines.h"
|
||||
#include "d3dcompiler_common.h"
|
||||
|
||||
#if defined(HAVE_DYLIB) && !defined(__WINRT__)
|
||||
|
@ -13,7 +13,8 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _D3D11_DEFINES_H_
|
||||
#define _D3D11_DEFINES_H_
|
||||
|
||||
#include <retro_inline.h>
|
||||
|
||||
@ -298,3 +299,5 @@ typedef struct
|
||||
IDXGIAdapter1 *adapters[D3D11_MAX_GPU_COUNT];
|
||||
d3d11_texture_t luts[GFX_MAX_TEXTURES];
|
||||
} d3d11_video_t;
|
||||
|
||||
#endif
|
@ -20,13 +20,10 @@
|
||||
#include <boolean.h>
|
||||
|
||||
#include "d3d_common.h"
|
||||
#include "d3d12_common.h"
|
||||
#include "d3d12_defines.h"
|
||||
#include "dxgi_common.h"
|
||||
#include "d3dcompiler_common.h"
|
||||
|
||||
#include "../verbosity.h"
|
||||
#include "../../configuration.h"
|
||||
|
||||
#if defined(HAVE_DYLIB) && !defined(__WINRT__)
|
||||
#include <dynamic/dylib.h>
|
||||
#endif
|
||||
@ -139,113 +136,3 @@ HRESULT WINAPI D3D12SerializeVersionedRootSignature(
|
||||
return fp(pRootSignature, ppBlob, ppErrorBlob);
|
||||
}
|
||||
#endif
|
||||
|
||||
static INLINE D3D12_GPU_VIRTUAL_ADDRESS D3D12GetGPUVirtualAddress(void* resource)
|
||||
{
|
||||
return ((ID3D12Resource*)resource)->lpVtbl->GetGPUVirtualAddress((ID3D12Resource*)resource);
|
||||
}
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS
|
||||
d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer)
|
||||
{
|
||||
D3D12_HEAP_PROPERTIES heap_props = { D3D12_HEAP_TYPE_UPLOAD, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
D3D12_MEMORY_POOL_UNKNOWN, 1, 1 };
|
||||
D3D12_RESOURCE_DESC resource_desc = { D3D12_RESOURCE_DIMENSION_BUFFER };
|
||||
|
||||
resource_desc.Width = size_in_bytes;
|
||||
resource_desc.Height = 1;
|
||||
resource_desc.DepthOrArraySize = 1;
|
||||
resource_desc.MipLevels = 1;
|
||||
resource_desc.SampleDesc.Count = 1;
|
||||
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
|
||||
device->lpVtbl->CreateCommittedResource(
|
||||
device, (D3D12_HEAP_PROPERTIES*)&heap_props, D3D12_HEAP_FLAG_NONE, &resource_desc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, uuidof(ID3D12Resource), (void**)buffer);
|
||||
|
||||
return D3D12GetGPUVirtualAddress(*buffer);
|
||||
}
|
||||
|
||||
void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
||||
d3d12_texture_t* texture, void *userdata)
|
||||
{
|
||||
D3D12_TEXTURE_COPY_LOCATION src, dst;
|
||||
|
||||
src.pResource = texture->upload_buffer;
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.PlacedFootprint = texture->layout;
|
||||
|
||||
dst.pResource = texture->handle;
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dst.SubresourceIndex = 0;
|
||||
|
||||
D3D12_RESOURCE_TRANSITION(
|
||||
cmd,
|
||||
texture->handle,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
cmd->lpVtbl->CopyTextureRegion(cmd, &dst, 0, 0, 0, &src, NULL);
|
||||
|
||||
D3D12_RESOURCE_TRANSITION(
|
||||
cmd,
|
||||
texture->handle,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
if (texture->desc.MipLevels > 1)
|
||||
{
|
||||
unsigned i;
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)userdata;
|
||||
|
||||
cmd->lpVtbl->SetComputeRootSignature(cmd, d3d12->desc.cs_rootSignature);
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->mipmapgen_pipe);
|
||||
cmd->lpVtbl->SetComputeRootDescriptorTable(cmd, CS_ROOT_ID_TEXTURE_T, texture->gpu_descriptor[0]);
|
||||
|
||||
for (i = 1; i < texture->desc.MipLevels; i++)
|
||||
{
|
||||
unsigned width = texture->desc.Width >> i;
|
||||
unsigned height = texture->desc.Height >> i;
|
||||
struct
|
||||
{
|
||||
uint32_t src_level;
|
||||
float texel_size[2];
|
||||
} cbuffer = { i - 1, { 1.0f / width, 1.0f / height } };
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier = { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION };
|
||||
barrier.Transition.pResource = texture->handle;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
barrier.Transition.Subresource = i;
|
||||
cmd->lpVtbl->ResourceBarrier(cmd, 1, &barrier);
|
||||
}
|
||||
|
||||
{
|
||||
UINT thread_group_count_x = (width + 0x7) >> 3;
|
||||
UINT thread_group_count_y = (height + 0x7) >> 3;
|
||||
cmd->lpVtbl->SetComputeRootDescriptorTable(cmd, CS_ROOT_ID_UAV_T, texture->gpu_descriptor[i]);
|
||||
cmd->lpVtbl->SetComputeRoot32BitConstants(
|
||||
cmd, CS_ROOT_ID_CONSTANTS, sizeof(cbuffer) / sizeof(uint32_t), &cbuffer, 0);
|
||||
cmd->lpVtbl->Dispatch(cmd, thread_group_count_x, thread_group_count_y, 1);
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier = { D3D12_RESOURCE_BARRIER_TYPE_UAV };
|
||||
barrier.UAV.pResource = texture->handle;
|
||||
cmd->lpVtbl->ResourceBarrier(cmd, 1, &barrier);
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier = { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION };
|
||||
barrier.Transition.pResource = texture->handle;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
barrier.Transition.Subresource = i;
|
||||
cmd->lpVtbl->ResourceBarrier(cmd, 1, &barrier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
texture->dirty = false;
|
||||
}
|
||||
|
@ -14,7 +14,8 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _D3D12_DEFINES_H_
|
||||
#define _D3D12_DEFINES_H_
|
||||
|
||||
#include <retro_inline.h>
|
||||
#include <retro_math.h>
|
||||
@ -81,8 +82,6 @@ typedef enum
|
||||
CS_ROOT_ID_MAX
|
||||
} compute_root_index_t;
|
||||
|
||||
|
||||
|
||||
typedef const ID3D12PipelineState* D3D12PipelineStateRef;
|
||||
|
||||
/* auto-generated */
|
||||
@ -354,27 +353,6 @@ typedef struct
|
||||
uint16_t flags;
|
||||
} d3d12_video_t;
|
||||
|
||||
static INLINE HRESULT
|
||||
D3D12Map(void* resource, UINT subresource, D3D12_RANGE* read_range, void** data)
|
||||
{
|
||||
return ((ID3D12Resource*)resource)
|
||||
->lpVtbl->Map((ID3D12Resource*)resource, subresource, read_range, data);
|
||||
}
|
||||
|
||||
static INLINE void D3D12Unmap(void* resource, UINT subresource, D3D12_RANGE* written_range)
|
||||
{
|
||||
((ID3D12Resource*)resource)
|
||||
->lpVtbl->Unmap((ID3D12Resource*)resource, subresource, written_range);
|
||||
}
|
||||
|
||||
/* end of auto-generated */
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS
|
||||
d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer);
|
||||
|
||||
void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
||||
d3d12_texture_t* texture, void *userdata);
|
||||
|
||||
RETRO_END_DECLS
|
||||
#endif
|
@ -94,77 +94,3 @@ void d3d8_deinitialize_symbols(void)
|
||||
dylib_initialized = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool d3d8_create_device_internal(
|
||||
LPDIRECT3DDEVICE8 dev,
|
||||
D3DPRESENT_PARAMETERS *d3dpp,
|
||||
LPDIRECT3D8 d3d,
|
||||
HWND focus_window,
|
||||
unsigned cur_mon_id,
|
||||
DWORD behavior_flags)
|
||||
{
|
||||
if (dev &&
|
||||
SUCCEEDED(IDirect3D8_CreateDevice(d3d,
|
||||
cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
focus_window,
|
||||
behavior_flags,
|
||||
d3dpp,
|
||||
(IDirect3DDevice8**)dev)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool d3d8_create_device(void *dev,
|
||||
void *d3dpp,
|
||||
LPDIRECT3D8 d3d,
|
||||
HWND focus_window,
|
||||
unsigned cur_mon_id)
|
||||
{
|
||||
if (!d3d8_create_device_internal(dev,
|
||||
(D3DPRESENT_PARAMETERS*)d3dpp,
|
||||
d3d,
|
||||
focus_window,
|
||||
cur_mon_id,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING))
|
||||
if (!d3d8_create_device_internal(
|
||||
dev,
|
||||
(D3DPRESENT_PARAMETERS*)d3dpp, d3d, focus_window,
|
||||
cur_mon_id,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool d3d8_reset(void *data, void *d3dpp)
|
||||
{
|
||||
const char *err = NULL;
|
||||
LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data;
|
||||
if (dev && IDirect3DDevice8_Reset(dev, (D3DPRESENT_PARAMETERS*)d3dpp) ==
|
||||
D3D_OK)
|
||||
return true;
|
||||
#ifndef _XBOX
|
||||
RARCH_WARN("[D3D]: Attempting to recover from dead state...\n");
|
||||
/* Try to recreate the device completely. */
|
||||
switch (IDirect3DDevice8_TestCooperativeLevel(dev))
|
||||
{
|
||||
case D3DERR_DEVICELOST:
|
||||
err = "DEVICELOST";
|
||||
break;
|
||||
|
||||
case D3DERR_DEVICENOTRESET:
|
||||
err = "DEVICENOTRESET";
|
||||
break;
|
||||
|
||||
case D3DERR_DRIVERINTERNALERROR:
|
||||
err = "DRIVERINTERNALERROR";
|
||||
break;
|
||||
|
||||
default:
|
||||
err = "Unknown";
|
||||
}
|
||||
RARCH_WARN("[D3D]: recovering from dead state: (%s).\n", err);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -73,30 +73,12 @@ typedef struct d3d8_video
|
||||
overlay_t *overlays;
|
||||
} d3d8_video_t;
|
||||
|
||||
static INLINE void *
|
||||
d3d8_vertex_buffer_lock(LPDIRECT3DVERTEXBUFFER8 vertbuf)
|
||||
{
|
||||
void *buf = NULL;
|
||||
IDirect3DVertexBuffer8_Lock(vertbuf, 0, 0, (BYTE**)&buf, 0);
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool d3d8_create_device(void *dev,
|
||||
void *d3dpp,
|
||||
LPDIRECT3D8 d3d,
|
||||
HWND focus_window,
|
||||
unsigned cur_mon_id);
|
||||
|
||||
bool d3d8_reset(void *dev, void *d3dpp);
|
||||
|
||||
void *d3d8_create(void);
|
||||
|
||||
bool d3d8_initialize_symbols(enum gfx_ctx_api api);
|
||||
|
||||
void d3d8_deinitialize_symbols(void);
|
||||
|
||||
void d3d8_set_mvp(void *data, const void *userdata);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -43,13 +43,6 @@ RETRO_BEGIN_DECLS
|
||||
#define GL_CORE_NUM_VBOS 256
|
||||
#define GL_CORE_NUM_FENCES 8
|
||||
|
||||
struct gl3_streamed_texture
|
||||
{
|
||||
GLuint tex;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
enum gl3_flags
|
||||
{
|
||||
GL3_FLAG_PBO_READBACK_ENABLE = (1 << 0),
|
||||
@ -67,6 +60,14 @@ enum gl3_flags
|
||||
GL3_FLAG_KEEP_ASPECT = (1 << 12)
|
||||
};
|
||||
|
||||
struct gl3_streamed_texture
|
||||
{
|
||||
GLuint tex;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
};
|
||||
|
||||
|
||||
typedef struct gl3
|
||||
{
|
||||
const gfx_ctx_driver_t *ctx_driver;
|
||||
|
@ -1377,179 +1377,6 @@ void vulkan_debug_mark_memory(VkDevice device, VkDeviceMemory memory)
|
||||
vulkan_debug_mark_object(device, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)memory, "RetroArch memory", ++object_count);
|
||||
}
|
||||
|
||||
void vulkan_write_quad_descriptors(
|
||||
VkDevice device,
|
||||
VkDescriptorSet set,
|
||||
VkBuffer buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize range,
|
||||
const struct vk_texture *texture,
|
||||
VkSampler sampler)
|
||||
{
|
||||
VkWriteDescriptorSet write;
|
||||
VkDescriptorBufferInfo buffer_info;
|
||||
|
||||
buffer_info.buffer = buffer;
|
||||
buffer_info.offset = offset;
|
||||
buffer_info.range = range;
|
||||
|
||||
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write.pNext = NULL;
|
||||
write.dstSet = set;
|
||||
write.dstBinding = 0;
|
||||
write.dstArrayElement = 0;
|
||||
write.descriptorCount = 1;
|
||||
write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
write.pImageInfo = NULL;
|
||||
write.pBufferInfo = &buffer_info;
|
||||
write.pTexelBufferView = NULL;
|
||||
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
||||
|
||||
if (texture)
|
||||
{
|
||||
VkDescriptorImageInfo image_info;
|
||||
|
||||
image_info.sampler = sampler;
|
||||
image_info.imageView = texture->view;
|
||||
image_info.imageLayout = texture->layout;
|
||||
|
||||
write.dstSet = set;
|
||||
write.dstBinding = 1;
|
||||
write.descriptorCount = 1;
|
||||
write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
write.pImageInfo = &image_info;
|
||||
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void vulkan_transition_texture(vk_t *vk, VkCommandBuffer cmd, struct vk_texture *texture)
|
||||
{
|
||||
/* Transition to GENERAL layout for linear streamed textures.
|
||||
* We're using linear textures here, so only
|
||||
* GENERAL layout is supported.
|
||||
* If we're already in GENERAL, add a host -> shader read memory barrier
|
||||
* to invalidate texture caches.
|
||||
*/
|
||||
if (texture->layout != VK_IMAGE_LAYOUT_PREINITIALIZED &&
|
||||
texture->layout != VK_IMAGE_LAYOUT_GENERAL)
|
||||
return;
|
||||
|
||||
switch (texture->type)
|
||||
{
|
||||
case VULKAN_TEXTURE_STREAMED:
|
||||
VULKAN_IMAGE_LAYOUT_TRANSITION(cmd, texture->image,
|
||||
texture->layout, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
|
||||
VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
break;
|
||||
|
||||
default:
|
||||
retro_assert(0 && "Attempting to transition invalid texture type.\n");
|
||||
break;
|
||||
}
|
||||
texture->layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
|
||||
void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call)
|
||||
{
|
||||
if (call->texture && call->texture->image)
|
||||
vulkan_transition_texture(vk, vk->cmd, call->texture);
|
||||
|
||||
if (call->pipeline != vk->tracker.pipeline)
|
||||
{
|
||||
VkRect2D sci;
|
||||
vkCmdBindPipeline(vk->cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS, call->pipeline);
|
||||
vk->tracker.pipeline = call->pipeline;
|
||||
|
||||
/* Changing pipeline invalidates dynamic state. */
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
|
||||
if (vk->flags & VK_FLAG_TRACKER_USE_SCISSOR)
|
||||
sci = vk->tracker.scissor;
|
||||
else
|
||||
{
|
||||
/* No scissor -> viewport */
|
||||
sci.offset.x = vk->vp.x;
|
||||
sci.offset.y = vk->vp.y;
|
||||
sci.extent.width = vk->vp.width;
|
||||
sci.extent.height = vk->vp.height;
|
||||
}
|
||||
|
||||
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
||||
vkCmdSetScissor (vk->cmd, 0, 1, &sci);
|
||||
|
||||
vk->tracker.dirty &= ~VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
else if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT)
|
||||
{
|
||||
VkRect2D sci;
|
||||
if (vk->flags & VK_FLAG_TRACKER_USE_SCISSOR)
|
||||
sci = vk->tracker.scissor;
|
||||
else
|
||||
{
|
||||
/* No scissor -> viewport */
|
||||
sci.offset.x = vk->vp.x;
|
||||
sci.offset.y = vk->vp.y;
|
||||
sci.extent.width = vk->vp.width;
|
||||
sci.extent.height = vk->vp.height;
|
||||
}
|
||||
|
||||
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
||||
vkCmdSetScissor (vk->cmd, 0, 1, &sci);
|
||||
|
||||
vk->tracker.dirty &= ~VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
/* Upload descriptors */
|
||||
{
|
||||
VkDescriptorSet set;
|
||||
/* Upload UBO */
|
||||
struct vk_buffer_range range;
|
||||
float *mvp_data_ptr = NULL;
|
||||
|
||||
if (!vulkan_buffer_chain_alloc(vk->context, &vk->chain->ubo,
|
||||
call->uniform_size, &range))
|
||||
return;
|
||||
|
||||
memcpy(range.data, call->uniform, call->uniform_size);
|
||||
|
||||
set = vulkan_descriptor_manager_alloc(
|
||||
vk->context->device,
|
||||
&vk->chain->descriptor_manager);
|
||||
|
||||
vulkan_write_quad_descriptors(
|
||||
vk->context->device,
|
||||
set,
|
||||
range.buffer,
|
||||
range.offset,
|
||||
call->uniform_size,
|
||||
call->texture,
|
||||
call->sampler);
|
||||
|
||||
vkCmdBindDescriptorSets(vk->cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
vk->pipelines.layout, 0,
|
||||
1, &set, 0, NULL);
|
||||
|
||||
vk->tracker.view = VK_NULL_HANDLE;
|
||||
vk->tracker.sampler = VK_NULL_HANDLE;
|
||||
for (
|
||||
mvp_data_ptr = &vk->tracker.mvp.data[0]
|
||||
; mvp_data_ptr < vk->tracker.mvp.data + 16
|
||||
; mvp_data_ptr++)
|
||||
*mvp_data_ptr = 0.0f;
|
||||
}
|
||||
|
||||
/* VBO is already uploaded. */
|
||||
vkCmdBindVertexBuffers(vk->cmd, 0, 1,
|
||||
&call->vbo->buffer, &call->vbo->offset);
|
||||
|
||||
/* Draw the quad */
|
||||
vkCmdDraw(vk->cmd, call->vertices, 1, 0, 0);
|
||||
}
|
||||
|
||||
struct vk_buffer vulkan_create_buffer(
|
||||
const struct vulkan_context *context,
|
||||
size_t size, VkBufferUsageFlags usage)
|
||||
@ -2255,9 +2082,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
|
||||
for (i = 0; i < format_count; i++)
|
||||
{
|
||||
if (
|
||||
formats[i].format == VK_FORMAT_R8G8B8A8_UNORM ||
|
||||
formats[i].format == VK_FORMAT_B8G8R8A8_UNORM ||
|
||||
formats[i].format == VK_FORMAT_A8B8G8R8_UNORM_PACK32)
|
||||
formats[i].format == VK_FORMAT_R8G8B8A8_UNORM
|
||||
|| formats[i].format == VK_FORMAT_B8G8R8A8_UNORM
|
||||
|| formats[i].format == VK_FORMAT_A8B8G8R8_UNORM_PACK32)
|
||||
{
|
||||
format = formats[i];
|
||||
break;
|
||||
|
@ -210,6 +210,27 @@
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
enum vk_flags
|
||||
{
|
||||
VK_FLAG_VSYNC = (1 << 0),
|
||||
VK_FLAG_KEEP_ASPECT = (1 << 1),
|
||||
VK_FLAG_FULLSCREEN = (1 << 2),
|
||||
VK_FLAG_QUITTING = (1 << 3),
|
||||
VK_FLAG_SHOULD_RESIZE = (1 << 4),
|
||||
VK_FLAG_TRACKER_USE_SCISSOR = (1 << 5),
|
||||
VK_FLAG_HW_ENABLE = (1 << 6),
|
||||
VK_FLAG_HW_VALID_SEMAPHORE = (1 << 7),
|
||||
VK_FLAG_MENU_ENABLE = (1 << 8),
|
||||
VK_FLAG_MENU_FULLSCREEN = (1 << 9),
|
||||
VK_FLAG_HDR_SUPPORT = (1 << 10),
|
||||
VK_FLAG_DISPLAY_BLEND = (1 << 11),
|
||||
VK_FLAG_READBACK_PENDING = (1 << 12),
|
||||
VK_FLAG_READBACK_STREAMED = (1 << 13),
|
||||
VK_FLAG_OVERLAY_ENABLE = (1 << 14),
|
||||
VK_FLAG_OVERLAY_FULLSCREEN = (1 << 15)
|
||||
};
|
||||
|
||||
|
||||
enum vk_texture_type
|
||||
{
|
||||
/* We will use the texture as a sampled linear texture. */
|
||||
@ -504,26 +525,6 @@ struct vk_draw_triangles
|
||||
unsigned vertices;
|
||||
};
|
||||
|
||||
enum vk_flags
|
||||
{
|
||||
VK_FLAG_VSYNC = (1 << 0),
|
||||
VK_FLAG_KEEP_ASPECT = (1 << 1),
|
||||
VK_FLAG_FULLSCREEN = (1 << 2),
|
||||
VK_FLAG_QUITTING = (1 << 3),
|
||||
VK_FLAG_SHOULD_RESIZE = (1 << 4),
|
||||
VK_FLAG_TRACKER_USE_SCISSOR = (1 << 5),
|
||||
VK_FLAG_HW_ENABLE = (1 << 6),
|
||||
VK_FLAG_HW_VALID_SEMAPHORE = (1 << 7),
|
||||
VK_FLAG_MENU_ENABLE = (1 << 8),
|
||||
VK_FLAG_MENU_FULLSCREEN = (1 << 9),
|
||||
VK_FLAG_HDR_SUPPORT = (1 << 10),
|
||||
VK_FLAG_DISPLAY_BLEND = (1 << 11),
|
||||
VK_FLAG_READBACK_PENDING = (1 << 12),
|
||||
VK_FLAG_READBACK_STREAMED = (1 << 13),
|
||||
VK_FLAG_OVERLAY_ENABLE = (1 << 14),
|
||||
VK_FLAG_OVERLAY_FULLSCREEN = (1 << 15)
|
||||
};
|
||||
|
||||
typedef struct vk
|
||||
{
|
||||
vulkan_filter_chain_t *filter_chain;
|
||||
@ -670,24 +671,8 @@ uint32_t vulkan_find_memory_type_fallback(
|
||||
uint32_t device_reqs, uint32_t host_reqs_first,
|
||||
uint32_t host_reqs_second);
|
||||
|
||||
void vulkan_transition_texture(vk_t *vk, VkCommandBuffer cmd, struct vk_texture *texture);
|
||||
|
||||
void vulkan_debug_mark_buffer(VkDevice device, VkBuffer buffer);
|
||||
|
||||
void vulkan_write_quad_descriptors(
|
||||
VkDevice device,
|
||||
VkDescriptorSet set,
|
||||
VkBuffer buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize range,
|
||||
const struct vk_texture *texture,
|
||||
VkSampler sampler);
|
||||
|
||||
/* The VBO needs to be written to before calling this.
|
||||
* Use vulkan_buffer_chain_alloc.
|
||||
*/
|
||||
void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call);
|
||||
|
||||
struct vk_buffer vulkan_create_buffer(
|
||||
const struct vulkan_context *context,
|
||||
size_t size, VkBufferUsageFlags usage);
|
||||
|
@ -55,6 +55,133 @@
|
||||
#include "../../tasks/tasks_internal.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static void gfx_display_ctr_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
ctr_scale_vector_t scale_vector;
|
||||
int colorR, colorG, colorB, colorA;
|
||||
ctr_scale_vector_t *vec = NULL;
|
||||
ctr_vertex_t *v = NULL;
|
||||
struct ctr_texture *texture = NULL;
|
||||
const float *color = NULL;
|
||||
ctr_video_t *ctr = (ctr_video_t*)data;
|
||||
|
||||
if (!ctr || !draw)
|
||||
return;
|
||||
|
||||
texture = (struct ctr_texture*)draw->texture;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!texture)
|
||||
return;
|
||||
|
||||
vec = &scale_vector;
|
||||
CTR_SET_SCALE_VECTOR(
|
||||
vec,
|
||||
CTR_TOP_FRAMEBUFFER_WIDTH,
|
||||
CTR_TOP_FRAMEBUFFER_HEIGHT,
|
||||
texture->width,
|
||||
texture->height);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_BOOLUNIFORM, 0);
|
||||
ctrGuSetVertexShaderFloatUniform(0, (float*)&scale_vector, 1);
|
||||
|
||||
if ((ctr->vertex_cache.size - (ctr->vertex_cache.current
|
||||
- ctr->vertex_cache.buffer)) < 1)
|
||||
ctr->vertex_cache.current = ctr->vertex_cache.buffer;
|
||||
|
||||
v = ctr->vertex_cache.current++;
|
||||
|
||||
v->x0 = draw->x;
|
||||
v->y0 = 240 - draw->height - draw->y;
|
||||
v->x1 = v->x0 + draw->width;
|
||||
v->y1 = v->y0 + draw->height;
|
||||
v->u0 = 0;
|
||||
v->v0 = 0;
|
||||
v->u1 = texture->active_width;
|
||||
v->v1 = texture->active_height;
|
||||
|
||||
ctrGuSetAttributeBuffers(2,
|
||||
VIRT_TO_PHYS(v),
|
||||
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 |
|
||||
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 4,
|
||||
sizeof(ctr_vertex_t));
|
||||
|
||||
color = draw->coords->color;
|
||||
colorR = (int)((*color++)*255.f);
|
||||
colorG = (int)((*color++)*255.f);
|
||||
colorB = (int)((*color++)*255.f);
|
||||
colorA = (int)((*color++)*255.f);
|
||||
|
||||
GPU_SetTexEnv(0,
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
|
||||
0,
|
||||
0,
|
||||
GPU_MODULATE, GPU_MODULATE,
|
||||
COLOR_ABGR(colorR,colorG,colorB,colorA)
|
||||
);
|
||||
|
||||
#if 0
|
||||
GPU_SetTexEnv(0,
|
||||
GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, 0),
|
||||
GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, 0),
|
||||
0,
|
||||
GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR, 0),
|
||||
GPU_REPLACE, GPU_REPLACE,
|
||||
0x3FFFFFFF);
|
||||
#endif
|
||||
|
||||
ctrGuSetTexture(GPU_TEXUNIT0,
|
||||
VIRT_TO_PHYS(texture->data),
|
||||
texture->width,
|
||||
texture->height,
|
||||
GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)
|
||||
| GPU_TEXTURE_MIN_FILTER(GPU_LINEAR)
|
||||
| GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE)
|
||||
| GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
|
||||
GPU_RGBA8);
|
||||
|
||||
GPU_SetViewport(NULL,
|
||||
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
|
||||
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
|
||||
ctr->video_mode == CTR_VIDEO_MODE_2D_800X240
|
||||
? CTR_TOP_FRAMEBUFFER_WIDTH * 2
|
||||
: CTR_TOP_FRAMEBUFFER_WIDTH);
|
||||
|
||||
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
|
||||
|
||||
if (ctr->video_mode == CTR_VIDEO_MODE_3D)
|
||||
{
|
||||
GPU_SetViewport(NULL,
|
||||
VIRT_TO_PHYS(ctr->drawbuffers.top.right),
|
||||
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
|
||||
CTR_TOP_FRAMEBUFFER_WIDTH);
|
||||
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
|
||||
}
|
||||
|
||||
GPU_SetTexEnv(0, GPU_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_ctr = {
|
||||
gfx_display_ctr_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_CTR,
|
||||
GFX_VIDEO_DRIVER_CTR,
|
||||
"ctr",
|
||||
true,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "../font_driver.h"
|
||||
#include "../common/d3d_common.h"
|
||||
#include "../common/win32_common.h"
|
||||
#include "../common/d3d10_common.h"
|
||||
#include "../common/d3d10_defines.h"
|
||||
#include "../common/dxgi_common.h"
|
||||
#include "../common/d3dcompiler_common.h"
|
||||
#ifdef HAVE_MENU
|
||||
@ -63,6 +63,20 @@
|
||||
/*
|
||||
* D3D10 COMMON
|
||||
*/
|
||||
static INLINE void d3d10_set_shader(D3D10Device ctx, d3d10_shader_t* shader)
|
||||
{
|
||||
ctx->lpVtbl->IASetInputLayout(ctx, shader->layout);
|
||||
ctx->lpVtbl->VSSetShader(ctx, shader->vs);
|
||||
ctx->lpVtbl->PSSetShader(ctx, shader->ps);
|
||||
ctx->lpVtbl->GSSetShader(ctx, shader->gs);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
d3d10_set_texture_and_sampler(D3D10Device ctx, UINT slot, d3d10_texture_t* texture)
|
||||
{
|
||||
ctx->lpVtbl->PSSetShaderResources(ctx, slot, 1, &texture->view);
|
||||
ctx->lpVtbl->PSSetSamplers(ctx, slot, 1, (D3D10SamplerState*)&texture->sampler);
|
||||
}
|
||||
|
||||
static INLINE void d3d10_release_texture(d3d10_texture_t* texture)
|
||||
{
|
||||
@ -273,6 +287,281 @@ static bool d3d10_init_shader(
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static void gfx_display_d3d10_blend_begin(void *data)
|
||||
{
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_enable,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d10_blend_end(void *data)
|
||||
{
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_disable,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d10_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
UINT offset = 0, stride = 0;
|
||||
int vertex_count = 1;
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10 || !draw || !draw->texture)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
d3d10_set_shader(d3d10->device, &d3d10->shaders[draw->pipeline_id]);
|
||||
d3d10->device->lpVtbl->Draw(d3d10->device, draw->coords->vertices, 0);
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_enable,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
d3d10_set_shader(d3d10->device, &d3d10->sprites.shader);
|
||||
stride = sizeof(d3d10_sprite_t);
|
||||
d3d10->device->lpVtbl->IASetVertexBuffers(
|
||||
d3d10->device, 0, 1, (D3D10Buffer* const)&d3d10->sprites.vbo, &stride, &offset);
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color)
|
||||
vertex_count = draw->coords->vertices;
|
||||
|
||||
if ( (!(d3d10->flags & D3D10_ST_FLAG_SPRITES_ENABLE))
|
||||
|| (vertex_count > d3d10->sprites.capacity))
|
||||
return;
|
||||
|
||||
if (d3d10->sprites.offset + vertex_count > d3d10->sprites.capacity)
|
||||
d3d10->sprites.offset = 0;
|
||||
|
||||
{
|
||||
void* mapped_vbo = NULL;
|
||||
d3d10_sprite_t* sprite = NULL;
|
||||
|
||||
d3d10->sprites.vbo->lpVtbl->Map(d3d10->sprites.vbo,
|
||||
D3D10_MAP_WRITE_NO_OVERWRITE, 0,
|
||||
(void**)&mapped_vbo);
|
||||
|
||||
sprite = (d3d10_sprite_t*)mapped_vbo + d3d10->sprites.offset;
|
||||
|
||||
if (vertex_count == 1)
|
||||
{
|
||||
sprite->pos.x = draw->x / (float)d3d10->viewport.Width;
|
||||
sprite->pos.y =
|
||||
(d3d10->viewport.Height - draw->y - draw->height)
|
||||
/ (float)d3d10->viewport.Height;
|
||||
sprite->pos.w = draw->width / (float)d3d10->viewport.Width;
|
||||
sprite->pos.h = draw->height / (float)d3d10->viewport.Height;
|
||||
|
||||
sprite->coords.u = 0.0f;
|
||||
sprite->coords.v = 0.0f;
|
||||
sprite->coords.w = 1.0f;
|
||||
sprite->coords.h = 1.0f;
|
||||
|
||||
if (draw->scale_factor)
|
||||
sprite->params.scaling = draw->scale_factor;
|
||||
else
|
||||
sprite->params.scaling = 1.0f;
|
||||
|
||||
sprite->params.rotation = draw->rotation;
|
||||
|
||||
sprite->colors[3] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
sprite->colors[2] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5],
|
||||
0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]);
|
||||
sprite->colors[1] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
|
||||
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]);
|
||||
sprite->colors[0] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
|
||||
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const float* vertex = draw->coords->vertex;
|
||||
const float* tex_coord = draw->coords->tex_coord;
|
||||
const float* color = draw->coords->color;
|
||||
|
||||
for (i = 0; i < vertex_count; i++)
|
||||
{
|
||||
d3d10_vertex_t* v = (d3d10_vertex_t*)sprite;
|
||||
v->position[0] = *vertex++;
|
||||
v->position[1] = *vertex++;
|
||||
v->texcoord[0] = *tex_coord++;
|
||||
v->texcoord[1] = *tex_coord++;
|
||||
v->color[0] = *color++;
|
||||
v->color[1] = *color++;
|
||||
v->color[2] = *color++;
|
||||
v->color[3] = *color++;
|
||||
|
||||
sprite++;
|
||||
}
|
||||
|
||||
d3d10_set_shader(d3d10->device,
|
||||
&d3d10->shaders[VIDEO_SHADER_STOCK_BLEND]);
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
d3d10->sprites.vbo->lpVtbl->Unmap(d3d10->sprites.vbo);
|
||||
}
|
||||
|
||||
d3d10_set_texture_and_sampler(d3d10->device, 0,
|
||||
(d3d10_texture_t*)draw->texture);
|
||||
d3d10->device->lpVtbl->Draw(d3d10->device, vertex_count,
|
||||
d3d10->sprites.offset);
|
||||
d3d10->sprites.offset += vertex_count;
|
||||
|
||||
if (vertex_count > 1)
|
||||
{
|
||||
d3d10_set_shader(d3d10->device, &d3d10->sprites.shader);
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_d3d10_draw_pipeline(gfx_display_ctx_draw_t* draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
UINT stride = 0, offset = 0;
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10 || !draw)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
{
|
||||
video_coord_array_t* ca = &p_disp->dispca;
|
||||
|
||||
if (!d3d10->menu_pipeline_vbo)
|
||||
{
|
||||
D3D10_BUFFER_DESC desc;
|
||||
D3D10_SUBRESOURCE_DATA vertex_data;
|
||||
|
||||
desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float);
|
||||
desc.Usage = D3D10_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
vertex_data.pSysMem = ca->coords.vertex;
|
||||
vertex_data.SysMemPitch = 0;
|
||||
vertex_data.SysMemSlicePitch = 0;
|
||||
d3d10->device->lpVtbl->CreateBuffer(d3d10->device, &desc,
|
||||
&vertex_data, &d3d10->menu_pipeline_vbo);
|
||||
}
|
||||
stride = 2 * sizeof(float);
|
||||
d3d10->device->lpVtbl->IASetVertexBuffers(
|
||||
d3d10->device, 0, 1, (D3D10Buffer* const)&d3d10->menu_pipeline_vbo, &stride, &offset);
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_pipeline,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
stride = sizeof(d3d10_vertex_t);
|
||||
d3d10->device->lpVtbl->IASetVertexBuffers(
|
||||
d3d10->device, 0, 1, (D3D10Buffer* const)&d3d10->frame.vbo, &stride, &offset);
|
||||
draw->coords->vertices = 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
d3d10->ubo_values.time += 0.01f;
|
||||
|
||||
{
|
||||
void *mapped_ubo = NULL;
|
||||
d3d10->ubo->lpVtbl->Map(d3d10->ubo, D3D10_MAP_WRITE_DISCARD, 0,
|
||||
(void**)&mapped_ubo);
|
||||
*(d3d10_uniform_t*)mapped_ubo = d3d10->ubo_values;
|
||||
d3d10->ubo->lpVtbl->Unmap(d3d10->ubo);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d10_scissor_begin(void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
D3D10_RECT rect;
|
||||
d3d10_video_t *d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
d3d10->device->lpVtbl->RSSetScissorRects(d3d10->device, 1, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d10_scissor_end(void *data,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
D3D10_RECT rect;
|
||||
d3d10_video_t *d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
d3d10->device->lpVtbl->RSSetScissorRects(d3d10->device, 1, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d10 = {
|
||||
gfx_display_d3d10_draw,
|
||||
gfx_display_d3d10_draw_pipeline,
|
||||
gfx_display_d3d10_blend_begin,
|
||||
gfx_display_d3d10_blend_end,
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_D3D10_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D10,
|
||||
"d3d10",
|
||||
true,
|
||||
gfx_display_d3d10_scissor_begin,
|
||||
gfx_display_d3d10_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -59,7 +59,7 @@
|
||||
#endif
|
||||
|
||||
#include "../common/d3d_common.h"
|
||||
#include "../common/d3d11_common.h"
|
||||
#include "../common/d3d11_defines.h"
|
||||
#include "../common/dxgi_common.h"
|
||||
#include "../common/d3dcompiler_common.h"
|
||||
#ifdef HAVE_SLANG
|
||||
@ -302,6 +302,313 @@ static void d3d11_update_texture(
|
||||
ctx->lpVtbl->GenerateMips(ctx, texture->view);
|
||||
}
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static void gfx_display_d3d11_blend_begin(void *data)
|
||||
{
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d11_blend_end(void *data)
|
||||
{
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d11_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
int vertex_count = 1;
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11 || !draw || !draw->texture)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->shaders[draw->pipeline_id];
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->Draw(d3d11->context, draw->coords->vertices, 0);
|
||||
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->sprites.shader;
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
}
|
||||
{
|
||||
UINT stride = sizeof(d3d11_sprite_t);
|
||||
UINT offset = 0;
|
||||
d3d11->context->lpVtbl->IASetVertexBuffers(
|
||||
d3d11->context, 0, 1,
|
||||
&d3d11->sprites.vbo, &stride, &offset);
|
||||
}
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
return;
|
||||
}
|
||||
|
||||
if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color)
|
||||
vertex_count = draw->coords->vertices;
|
||||
|
||||
if ( (!(d3d11->flags & D3D11_ST_FLAG_SPRITES_ENABLE))
|
||||
|| (vertex_count > d3d11->sprites.capacity))
|
||||
return;
|
||||
|
||||
if (d3d11->sprites.offset + vertex_count > d3d11->sprites.capacity)
|
||||
d3d11->sprites.offset = 0;
|
||||
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_vbo;
|
||||
d3d11_sprite_t* sprite = NULL;
|
||||
|
||||
d3d11->context->lpVtbl->Map(
|
||||
d3d11->context, (D3D11Resource)d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo);
|
||||
|
||||
sprite = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset;
|
||||
|
||||
if (vertex_count == 1)
|
||||
{
|
||||
sprite->pos.x = draw->x / (float)d3d11->viewport.Width;
|
||||
sprite->pos.y =
|
||||
(d3d11->viewport.Height - draw->y - draw->height) / (float)d3d11->viewport.Height;
|
||||
sprite->pos.w = draw->width / (float)d3d11->viewport.Width;
|
||||
sprite->pos.h = draw->height / (float)d3d11->viewport.Height;
|
||||
|
||||
sprite->coords.u = 0.0f;
|
||||
sprite->coords.v = 0.0f;
|
||||
sprite->coords.w = 1.0f;
|
||||
sprite->coords.h = 1.0f;
|
||||
|
||||
if (draw->scale_factor)
|
||||
sprite->params.scaling = draw->scale_factor;
|
||||
else
|
||||
sprite->params.scaling = 1.0f;
|
||||
|
||||
sprite->params.rotation = draw->rotation;
|
||||
|
||||
sprite->colors[3] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
sprite->colors[2] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5],
|
||||
0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]);
|
||||
sprite->colors[1] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
|
||||
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]);
|
||||
sprite->colors[0] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
|
||||
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const float* vertex = draw->coords->vertex;
|
||||
const float* tex_coord = draw->coords->tex_coord;
|
||||
const float* color = draw->coords->color;
|
||||
|
||||
for (i = 0; i < vertex_count; i++)
|
||||
{
|
||||
d3d11_vertex_t* v = (d3d11_vertex_t*)sprite;
|
||||
v->position[0] = *vertex++;
|
||||
v->position[1] = *vertex++;
|
||||
v->texcoord[0] = *tex_coord++;
|
||||
v->texcoord[1] = *tex_coord++;
|
||||
v->color[0] = *color++;
|
||||
v->color[1] = *color++;
|
||||
v->color[2] = *color++;
|
||||
v->color[3] = *color++;
|
||||
|
||||
sprite++;
|
||||
}
|
||||
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND];
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
}
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->Unmap(d3d11->context, (D3D11Resource)d3d11->sprites.vbo, 0);
|
||||
}
|
||||
|
||||
{
|
||||
d3d11_texture_t *texture = (d3d11_texture_t*)draw->texture;
|
||||
d3d11->context->lpVtbl->PSSetShaderResources(
|
||||
d3d11->context, 0, 1, &texture->view);
|
||||
d3d11->context->lpVtbl->PSSetSamplers(
|
||||
d3d11->context, 0, 1, (D3D11SamplerState*)&texture->sampler);
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->Draw(d3d11->context, vertex_count,
|
||||
d3d11->sprites.offset);
|
||||
d3d11->sprites.offset += vertex_count;
|
||||
|
||||
if (vertex_count > 1)
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->sprites.shader;
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_d3d11_draw_pipeline(gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11 || !draw)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
{
|
||||
video_coord_array_t* ca = &p_disp->dispca;
|
||||
|
||||
if (!d3d11->menu_pipeline_vbo)
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float);
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
desc.StructureByteStride = 0;
|
||||
|
||||
{
|
||||
D3D11_SUBRESOURCE_DATA vertex_data;
|
||||
vertex_data.pSysMem = ca->coords.vertex;
|
||||
vertex_data.SysMemPitch = 0;
|
||||
vertex_data.SysMemSlicePitch = 0;
|
||||
d3d11->device->lpVtbl->CreateBuffer(
|
||||
d3d11->device, &desc, &vertex_data,
|
||||
&d3d11->menu_pipeline_vbo);
|
||||
}
|
||||
}
|
||||
{
|
||||
UINT stride = 2 * sizeof(float);
|
||||
UINT offset = 0;
|
||||
d3d11->context->lpVtbl->IASetVertexBuffers(
|
||||
d3d11->context, 0, 1,
|
||||
&d3d11->menu_pipeline_vbo, &stride, &offset);
|
||||
}
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
d3d11->context->lpVtbl->OMSetBlendState(
|
||||
d3d11->context, d3d11->blend_pipeline,
|
||||
NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
{
|
||||
UINT stride = sizeof(d3d11_vertex_t);
|
||||
UINT offset = 0;
|
||||
d3d11->context->lpVtbl->IASetVertexBuffers(
|
||||
d3d11->context, 0, 1,
|
||||
&d3d11->frame.vbo, &stride, &offset);
|
||||
}
|
||||
draw->coords->vertices = 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(
|
||||
d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
d3d11->ubo_values.time += 0.01f;
|
||||
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
|
||||
d3d11->context->lpVtbl->Map(
|
||||
d3d11->context, (D3D11Resource)d3d11->ubo,
|
||||
0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
|
||||
*(d3d11_uniform_t*)mapped_ubo.pData = d3d11->ubo_values;
|
||||
d3d11->context->lpVtbl->Unmap(d3d11->context,
|
||||
(D3D11Resource)d3d11->ubo, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d11_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
D3D11_RECT rect;
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
d3d11->context->lpVtbl->RSSetScissorRects(d3d11->context, 1, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d11_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
D3D11_RECT rect;
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
d3d11->context->lpVtbl->RSSetScissorRects(d3d11->context, 1, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d11 = {
|
||||
gfx_display_d3d11_draw,
|
||||
gfx_display_d3d11_draw_pipeline,
|
||||
gfx_display_d3d11_blend_begin,
|
||||
gfx_display_d3d11_blend_end,
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_D3D11_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D11,
|
||||
"d3d11",
|
||||
true,
|
||||
gfx_display_d3d11_scissor_begin,
|
||||
gfx_display_d3d11_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
|
@ -58,7 +58,7 @@
|
||||
|
||||
#include "../common/d3d_common.h"
|
||||
#include "../common/dxgi_common.h"
|
||||
#include "../common/d3d12_common.h"
|
||||
#include "../common/d3d12_defines.h"
|
||||
#include "../common/d3dcompiler_common.h"
|
||||
#ifdef HAVE_SLANG
|
||||
#include "../drivers_shader/slang_process.h"
|
||||
@ -71,6 +71,45 @@
|
||||
/*
|
||||
* D3D12 COMMON
|
||||
*/
|
||||
static INLINE HRESULT
|
||||
D3D12Map(void* resource, UINT subresource, D3D12_RANGE* read_range, void** data)
|
||||
{
|
||||
return ((ID3D12Resource*)resource)
|
||||
->lpVtbl->Map((ID3D12Resource*)resource, subresource, read_range, data);
|
||||
}
|
||||
|
||||
static INLINE void D3D12Unmap(void* resource, UINT subresource, D3D12_RANGE* written_range)
|
||||
{
|
||||
((ID3D12Resource*)resource)
|
||||
->lpVtbl->Unmap((ID3D12Resource*)resource, subresource, written_range);
|
||||
}
|
||||
|
||||
static INLINE D3D12_GPU_VIRTUAL_ADDRESS D3D12GetGPUVirtualAddress(void* resource)
|
||||
{
|
||||
return ((ID3D12Resource*)resource)->lpVtbl->GetGPUVirtualAddress((ID3D12Resource*)resource);
|
||||
}
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS
|
||||
d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer)
|
||||
{
|
||||
D3D12_HEAP_PROPERTIES heap_props = { D3D12_HEAP_TYPE_UPLOAD, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
|
||||
D3D12_MEMORY_POOL_UNKNOWN, 1, 1 };
|
||||
D3D12_RESOURCE_DESC resource_desc = { D3D12_RESOURCE_DIMENSION_BUFFER };
|
||||
|
||||
resource_desc.Width = size_in_bytes;
|
||||
resource_desc.Height = 1;
|
||||
resource_desc.DepthOrArraySize = 1;
|
||||
resource_desc.MipLevels = 1;
|
||||
resource_desc.SampleDesc.Count = 1;
|
||||
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
|
||||
device->lpVtbl->CreateCommittedResource(
|
||||
device, (D3D12_HEAP_PROPERTIES*)&heap_props, D3D12_HEAP_FLAG_NONE, &resource_desc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, uuidof(ID3D12Resource), (void**)buffer);
|
||||
|
||||
return D3D12GetGPUVirtualAddress(*buffer);
|
||||
}
|
||||
|
||||
static INLINE D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
D3D12GetCPUDescriptorHandleForHeapStart(D3D12DescriptorHeap descriptor_heap)
|
||||
{
|
||||
@ -262,6 +301,90 @@ static void d3d12_init_texture(D3D12Device device, d3d12_texture_t* texture)
|
||||
texture->size_data.w = 1.0f / texture->desc.Height;
|
||||
}
|
||||
|
||||
static void d3d12_upload_texture(D3D12GraphicsCommandList cmd,
|
||||
d3d12_texture_t* texture, void *userdata)
|
||||
{
|
||||
D3D12_TEXTURE_COPY_LOCATION src, dst;
|
||||
|
||||
src.pResource = texture->upload_buffer;
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.PlacedFootprint = texture->layout;
|
||||
|
||||
dst.pResource = texture->handle;
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dst.SubresourceIndex = 0;
|
||||
|
||||
D3D12_RESOURCE_TRANSITION(
|
||||
cmd,
|
||||
texture->handle,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
cmd->lpVtbl->CopyTextureRegion(cmd, &dst, 0, 0, 0, &src, NULL);
|
||||
|
||||
D3D12_RESOURCE_TRANSITION(
|
||||
cmd,
|
||||
texture->handle,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
if (texture->desc.MipLevels > 1)
|
||||
{
|
||||
unsigned i;
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)userdata;
|
||||
|
||||
cmd->lpVtbl->SetComputeRootSignature(cmd, d3d12->desc.cs_rootSignature);
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->mipmapgen_pipe);
|
||||
cmd->lpVtbl->SetComputeRootDescriptorTable(cmd, CS_ROOT_ID_TEXTURE_T, texture->gpu_descriptor[0]);
|
||||
|
||||
for (i = 1; i < texture->desc.MipLevels; i++)
|
||||
{
|
||||
unsigned width = texture->desc.Width >> i;
|
||||
unsigned height = texture->desc.Height >> i;
|
||||
struct
|
||||
{
|
||||
uint32_t src_level;
|
||||
float texel_size[2];
|
||||
} cbuffer = { i - 1, { 1.0f / width, 1.0f / height } };
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier = { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION };
|
||||
barrier.Transition.pResource = texture->handle;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
barrier.Transition.Subresource = i;
|
||||
cmd->lpVtbl->ResourceBarrier(cmd, 1, &barrier);
|
||||
}
|
||||
|
||||
{
|
||||
UINT thread_group_count_x = (width + 0x7) >> 3;
|
||||
UINT thread_group_count_y = (height + 0x7) >> 3;
|
||||
cmd->lpVtbl->SetComputeRootDescriptorTable(cmd, CS_ROOT_ID_UAV_T, texture->gpu_descriptor[i]);
|
||||
cmd->lpVtbl->SetComputeRoot32BitConstants(
|
||||
cmd, CS_ROOT_ID_CONSTANTS, sizeof(cbuffer) / sizeof(uint32_t), &cbuffer, 0);
|
||||
cmd->lpVtbl->Dispatch(cmd, thread_group_count_x, thread_group_count_y, 1);
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier = { D3D12_RESOURCE_BARRIER_TYPE_UAV };
|
||||
barrier.UAV.pResource = texture->handle;
|
||||
cmd->lpVtbl->ResourceBarrier(cmd, 1, &barrier);
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier = { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION };
|
||||
barrier.Transition.pResource = texture->handle;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||
barrier.Transition.Subresource = i;
|
||||
cmd->lpVtbl->ResourceBarrier(cmd, 1, &barrier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
texture->dirty = false;
|
||||
}
|
||||
|
||||
static void d3d12_update_texture(
|
||||
int width,
|
||||
int height,
|
||||
@ -282,6 +405,298 @@ static void d3d12_update_texture(
|
||||
texture->dirty = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static void gfx_display_d3d12_blend_begin(void *data)
|
||||
{
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
|
||||
D3D12GraphicsCommandList cmd = d3d12->queue.cmd;
|
||||
d3d12->sprites.pipe = d3d12->sprites.pipe_blend;
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d12_blend_end(void *data)
|
||||
{
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
|
||||
D3D12GraphicsCommandList cmd = d3d12->queue.cmd;
|
||||
d3d12->sprites.pipe = d3d12->sprites.pipe_noblend;
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d12_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
D3D12GraphicsCommandList cmd;
|
||||
int vertex_count = 1;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12 || !draw || !draw->texture)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->pipes[draw->pipeline_id]);
|
||||
cmd->lpVtbl->DrawInstanced(cmd, draw->coords->vertices, 1, 0, 0);
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
cmd->lpVtbl->IASetVertexBuffers(cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||
return;
|
||||
}
|
||||
|
||||
if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color)
|
||||
vertex_count = draw->coords->vertices;
|
||||
|
||||
if ( (!(d3d12->flags & D3D12_ST_FLAG_SPRITES_ENABLE))
|
||||
|| (vertex_count > d3d12->sprites.capacity))
|
||||
return;
|
||||
|
||||
if (d3d12->sprites.offset + vertex_count > d3d12->sprites.capacity)
|
||||
d3d12->sprites.offset = 0;
|
||||
|
||||
{
|
||||
d3d12_sprite_t* sprite;
|
||||
D3D12_RANGE range;
|
||||
range.Begin = 0;
|
||||
range.End = 0;
|
||||
D3D12Map(d3d12->sprites.vbo, 0, &range, (void**)&sprite);
|
||||
sprite += d3d12->sprites.offset;
|
||||
|
||||
if (vertex_count == 1)
|
||||
{
|
||||
|
||||
sprite->pos.x = draw->x / (float)d3d12->chain.viewport.Width;
|
||||
sprite->pos.y =
|
||||
(d3d12->chain.viewport.Height - draw->y - draw->height) /
|
||||
(float)d3d12->chain.viewport.Height;
|
||||
sprite->pos.w = draw->width / (float)d3d12->chain.viewport.Width;
|
||||
sprite->pos.h = draw->height / (float)d3d12->chain.viewport.Height;
|
||||
|
||||
sprite->coords.u = 0.0f;
|
||||
sprite->coords.v = 0.0f;
|
||||
sprite->coords.w = 1.0f;
|
||||
sprite->coords.h = 1.0f;
|
||||
|
||||
if (draw->scale_factor)
|
||||
sprite->params.scaling = draw->scale_factor;
|
||||
else
|
||||
sprite->params.scaling = 1.0f;
|
||||
|
||||
sprite->params.rotation = draw->rotation;
|
||||
|
||||
sprite->colors[3] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
sprite->colors[2] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5],
|
||||
0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]);
|
||||
sprite->colors[1] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
|
||||
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]);
|
||||
sprite->colors[0] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
|
||||
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const float* vertex = draw->coords->vertex;
|
||||
const float* tex_coord = draw->coords->tex_coord;
|
||||
const float* color = draw->coords->color;
|
||||
|
||||
for (i = 0; i < vertex_count; i++)
|
||||
{
|
||||
d3d12_vertex_t* v = (d3d12_vertex_t*)sprite;
|
||||
v->position[0] = *vertex++;
|
||||
v->position[1] = *vertex++;
|
||||
v->texcoord[0] = *tex_coord++;
|
||||
v->texcoord[1] = *tex_coord++;
|
||||
v->color[0] = *color++;
|
||||
v->color[1] = *color++;
|
||||
v->color[2] = *color++;
|
||||
v->color[3] = *color++;
|
||||
|
||||
sprite++;
|
||||
}
|
||||
cmd->lpVtbl->SetPipelineState(cmd,
|
||||
(D3D12PipelineState)d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd,
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
range.Begin = d3d12->sprites.offset * sizeof(*sprite);
|
||||
range.End = (d3d12->sprites.offset + vertex_count) * sizeof(*sprite);
|
||||
D3D12Unmap(d3d12->sprites.vbo, 0, &range);
|
||||
}
|
||||
|
||||
{
|
||||
d3d12_texture_t* texture = (d3d12_texture_t*)draw->texture;
|
||||
if (texture->dirty)
|
||||
{
|
||||
d3d12_upload_texture(cmd, texture, d3d12);
|
||||
|
||||
if (vertex_count > 1)
|
||||
cmd->lpVtbl->SetPipelineState(cmd,
|
||||
(D3D12PipelineState)d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
else
|
||||
cmd->lpVtbl->SetPipelineState(cmd,
|
||||
(D3D12PipelineState)d3d12->sprites.pipe);
|
||||
}
|
||||
cmd->lpVtbl->SetGraphicsRootDescriptorTable(cmd, ROOT_ID_TEXTURE_T, texture->gpu_descriptor[0]);
|
||||
cmd->lpVtbl->SetGraphicsRootDescriptorTable(cmd, ROOT_ID_SAMPLER_T, texture->sampler);
|
||||
}
|
||||
|
||||
cmd->lpVtbl->DrawInstanced(cmd, vertex_count, 1, d3d12->sprites.offset, 0);
|
||||
d3d12->sprites.offset += vertex_count;
|
||||
|
||||
if (vertex_count > 1)
|
||||
{
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_d3d12_draw_pipeline(gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
D3D12GraphicsCommandList cmd;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12 || !draw)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
{
|
||||
video_coord_array_t* ca = &p_disp->dispca;
|
||||
|
||||
if (!d3d12->menu_pipeline_vbo)
|
||||
{
|
||||
D3D12_RANGE read_range;
|
||||
void* vertex_data_begin;
|
||||
|
||||
d3d12->menu_pipeline_vbo_view.StrideInBytes = 2 * sizeof(float);
|
||||
d3d12->menu_pipeline_vbo_view.SizeInBytes =
|
||||
ca->coords.vertices * d3d12->menu_pipeline_vbo_view.StrideInBytes;
|
||||
d3d12->menu_pipeline_vbo_view.BufferLocation = d3d12_create_buffer(
|
||||
d3d12->device, d3d12->menu_pipeline_vbo_view.SizeInBytes,
|
||||
&d3d12->menu_pipeline_vbo);
|
||||
|
||||
read_range.Begin = 0;
|
||||
read_range.End = 0;
|
||||
D3D12Map(d3d12->menu_pipeline_vbo, 0,
|
||||
&read_range, &vertex_data_begin);
|
||||
memcpy(vertex_data_begin, ca->coords.vertex,
|
||||
d3d12->menu_pipeline_vbo_view.SizeInBytes);
|
||||
D3D12Unmap(d3d12->menu_pipeline_vbo, 0, NULL);
|
||||
}
|
||||
cmd->lpVtbl->IASetVertexBuffers(cmd, 0, 1,
|
||||
&d3d12->menu_pipeline_vbo_view);
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
cmd->lpVtbl->IASetVertexBuffers(cmd, 0, 1, &d3d12->frame.vbo_view);
|
||||
draw->coords->vertices = 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd,
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
d3d12->ubo_values.time += 0.01f;
|
||||
|
||||
{
|
||||
D3D12_RANGE read_range;
|
||||
d3d12_uniform_t* mapped_ubo;
|
||||
|
||||
read_range.Begin = 0;
|
||||
read_range.End = 0;
|
||||
D3D12Map(d3d12->ubo, 0, &read_range, (void**)&mapped_ubo);
|
||||
*mapped_ubo = d3d12->ubo_values;
|
||||
D3D12Unmap(d3d12->ubo, 0, NULL);
|
||||
}
|
||||
cmd->lpVtbl->SetGraphicsRootConstantBufferView(cmd, ROOT_ID_UBO,
|
||||
d3d12->ubo_view.BufferLocation);
|
||||
}
|
||||
|
||||
void gfx_display_d3d12_scissor_begin(void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
D3D12_RECT rect;
|
||||
D3D12GraphicsCommandList cmd;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
cmd->lpVtbl->RSSetScissorRects(cmd, 1, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d12_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
D3D12_RECT rect;
|
||||
D3D12GraphicsCommandList cmd;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
cmd->lpVtbl->RSSetScissorRects(cmd, 1, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d12 = {
|
||||
gfx_display_d3d12_draw,
|
||||
gfx_display_d3d12_draw_pipeline,
|
||||
gfx_display_d3d12_blend_begin,
|
||||
gfx_display_d3d12_blend_end,
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_D3D12_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D12,
|
||||
"d3d12",
|
||||
true,
|
||||
gfx_display_d3d12_scissor_begin,
|
||||
gfx_display_d3d12_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -70,6 +70,16 @@
|
||||
#error "UWP does not support D3D8"
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX
|
||||
#define D3D8_RGB565_FORMAT D3DFMT_LIN_R5G6B5
|
||||
#define D3D8_XRGB8888_FORMAT D3DFMT_LIN_X8R8G8B8
|
||||
#define D3D8_ARGB8888_FORMAT D3DFMT_LIN_A8R8G8B8
|
||||
#else
|
||||
#define D3D8_RGB565_FORMAT D3DFMT_R5G6B5
|
||||
#define D3D8_XRGB8888_FORMAT D3DFMT_X8R8G8B8
|
||||
#define D3D8_ARGB8888_FORMAT D3DFMT_A8R8G8B8
|
||||
#endif
|
||||
|
||||
static LPDIRECT3D8 g_pD3D8;
|
||||
|
||||
void *dinput;
|
||||
@ -96,6 +106,92 @@ struct d3d8_texture_info
|
||||
enum texture_filter_type type;
|
||||
};
|
||||
|
||||
/*
|
||||
* D3D8 COMMON
|
||||
*/
|
||||
|
||||
static INLINE void *
|
||||
d3d8_vertex_buffer_lock(LPDIRECT3DVERTEXBUFFER8 vertbuf)
|
||||
{
|
||||
void *buf = NULL;
|
||||
IDirect3DVertexBuffer8_Lock(vertbuf, 0, 0, (BYTE**)&buf, 0);
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool d3d8_reset(void *data, void *d3dpp)
|
||||
{
|
||||
const char *err = NULL;
|
||||
LPDIRECT3DDEVICE8 dev = (LPDIRECT3DDEVICE8)data;
|
||||
if (dev && IDirect3DDevice8_Reset(dev, (D3DPRESENT_PARAMETERS*)d3dpp) ==
|
||||
D3D_OK)
|
||||
return true;
|
||||
#ifndef _XBOX
|
||||
RARCH_WARN("[D3D]: Attempting to recover from dead state...\n");
|
||||
/* Try to recreate the device completely. */
|
||||
switch (IDirect3DDevice8_TestCooperativeLevel(dev))
|
||||
{
|
||||
case D3DERR_DEVICELOST:
|
||||
err = "DEVICELOST";
|
||||
break;
|
||||
|
||||
case D3DERR_DEVICENOTRESET:
|
||||
err = "DEVICENOTRESET";
|
||||
break;
|
||||
|
||||
case D3DERR_DRIVERINTERNALERROR:
|
||||
err = "DRIVERINTERNALERROR";
|
||||
break;
|
||||
|
||||
default:
|
||||
err = "Unknown";
|
||||
}
|
||||
RARCH_WARN("[D3D]: recovering from dead state: (%s).\n", err);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool d3d8_create_device_internal(
|
||||
LPDIRECT3DDEVICE8 dev,
|
||||
D3DPRESENT_PARAMETERS *d3dpp,
|
||||
LPDIRECT3D8 d3d,
|
||||
HWND focus_window,
|
||||
unsigned cur_mon_id,
|
||||
DWORD behavior_flags)
|
||||
{
|
||||
if (dev &&
|
||||
SUCCEEDED(IDirect3D8_CreateDevice(d3d,
|
||||
cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
focus_window,
|
||||
behavior_flags,
|
||||
d3dpp,
|
||||
(IDirect3DDevice8**)dev)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool d3d8_create_device(void *dev,
|
||||
void *d3dpp,
|
||||
LPDIRECT3D8 d3d,
|
||||
HWND focus_window,
|
||||
unsigned cur_mon_id)
|
||||
{
|
||||
if (!d3d8_create_device_internal(dev,
|
||||
(D3DPRESENT_PARAMETERS*)d3dpp,
|
||||
d3d,
|
||||
focus_window,
|
||||
cur_mon_id,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING))
|
||||
if (!d3d8_create_device_internal(
|
||||
dev,
|
||||
(D3DPRESENT_PARAMETERS*)d3dpp, d3d, focus_window,
|
||||
cur_mon_id,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void *d3d8_texture_new(LPDIRECT3DDEVICE8 dev,
|
||||
unsigned width, unsigned height,
|
||||
unsigned miplevels, unsigned usage, INT32 format,
|
||||
@ -112,7 +208,7 @@ static void *d3d8_texture_new(LPDIRECT3DDEVICE8 dev,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void d3d8_set_mvp(void *data, const void *mat_data)
|
||||
static void d3d8_set_mvp(void *data, const void *mat_data)
|
||||
{
|
||||
struct d3d_matrix matrix;
|
||||
LPDIRECT3DDEVICE8 d3dr = (LPDIRECT3DDEVICE8)data;
|
||||
@ -289,16 +385,6 @@ static INLINE void *d3d8_vertex_buffer_new(
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
#define D3D8_RGB565_FORMAT D3DFMT_LIN_R5G6B5
|
||||
#define D3D8_XRGB8888_FORMAT D3DFMT_LIN_X8R8G8B8
|
||||
#define D3D8_ARGB8888_FORMAT D3DFMT_LIN_A8R8G8B8
|
||||
#else
|
||||
#define D3D8_RGB565_FORMAT D3DFMT_R5G6B5
|
||||
#define D3D8_XRGB8888_FORMAT D3DFMT_X8R8G8B8
|
||||
#define D3D8_ARGB8888_FORMAT D3DFMT_A8R8G8B8
|
||||
#endif
|
||||
|
||||
static bool d3d8_setup_init(void *data,
|
||||
const video_info_t *video_info,
|
||||
void *dev_data,
|
||||
@ -369,6 +455,235 @@ static void *d3d8_renderchain_new(void)
|
||||
return renderchain;
|
||||
}
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float d3d8_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float d3d8_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_d3d8_get_default_vertices(void)
|
||||
{
|
||||
return &d3d8_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_d3d8_get_default_tex_coords(void)
|
||||
{
|
||||
return &d3d8_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_d3d8_get_default_mvp(void *data)
|
||||
{
|
||||
static float id[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
return &id;
|
||||
}
|
||||
|
||||
static INT32 gfx_display_prim_to_d3d8_enum(
|
||||
enum gfx_display_prim_type prim_type)
|
||||
{
|
||||
switch (prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return D3DPT_COMM_TRIANGLESTRIP;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - hack */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d8_blend_begin(void *data)
|
||||
{
|
||||
d3d8_video_t *d3d = (d3d8_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, true);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d8_blend_end(void *data)
|
||||
{
|
||||
d3d8_video_t *d3d = (d3d8_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d8_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
static float default_mvp[] ={ 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
unsigned i;
|
||||
math_matrix_4x4 mop, m1, m2;
|
||||
LPDIRECT3DVERTEXBUFFER8 vbo;
|
||||
LPDIRECT3DDEVICE8 dev;
|
||||
D3DPRIMITIVETYPE type;
|
||||
unsigned start = 0;
|
||||
unsigned count = 0;
|
||||
d3d8_video_t *d3d = (d3d8_video_t*)data;
|
||||
Vertex * pv = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
|
||||
if (!d3d || !draw || draw->pipeline_id)
|
||||
return;
|
||||
if ((d3d->menu_display.offset + draw->coords->vertices )
|
||||
> (unsigned)d3d->menu_display.size)
|
||||
return;
|
||||
vbo = (LPDIRECT3DVERTEXBUFFER8)d3d->menu_display.buffer;
|
||||
dev = d3d->dev;
|
||||
pv = (Vertex*)d3d8_vertex_buffer_lock(vbo);
|
||||
|
||||
if (!pv)
|
||||
return;
|
||||
|
||||
pv += d3d->menu_display.offset;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &d3d8_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &d3d8_tex_coords[0];
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
int colors[4];
|
||||
|
||||
colors[0] = *color++ * 0xFF;
|
||||
colors[1] = *color++ * 0xFF;
|
||||
colors[2] = *color++ * 0xFF;
|
||||
colors[3] = *color++ * 0xFF;
|
||||
|
||||
pv[i].x = *vertex++;
|
||||
pv[i].y = *vertex++;
|
||||
pv[i].z = 0.5f;
|
||||
pv[i].u = *tex_coord++;
|
||||
pv[i].v = *tex_coord++;
|
||||
|
||||
if ((void*)draw->texture)
|
||||
{
|
||||
D3DSURFACE_DESC desc;
|
||||
LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)draw->texture;
|
||||
if (SUCCEEDED(IDirect3DTexture8_GetLevelDesc(tex,
|
||||
0, (D3DSURFACE_DESC*)&desc)))
|
||||
{
|
||||
pv[i].u *= desc.Width;
|
||||
pv[i].v *= desc.Height;
|
||||
}
|
||||
}
|
||||
|
||||
pv[i].color =
|
||||
D3DCOLOR_ARGB(
|
||||
colors[3], /* A */
|
||||
colors[0], /* R */
|
||||
colors[1], /* G */
|
||||
colors[2] /* B */
|
||||
);
|
||||
}
|
||||
IDirect3DVertexBuffer8_Unlock(vbo);
|
||||
|
||||
if (!draw->matrix_data)
|
||||
draw->matrix_data = &default_mvp;
|
||||
|
||||
/* ugh */
|
||||
matrix_4x4_scale(m1, 2.0, 2.0, 0);
|
||||
matrix_4x4_translate(mop, -1.0, -1.0, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_multiply(m1,
|
||||
*((math_matrix_4x4*)draw->matrix_data), m2);
|
||||
matrix_4x4_scale(mop,
|
||||
(draw->width / 2.0) / video_width,
|
||||
(draw->height / 2.0) / video_height, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_translate(mop,
|
||||
(draw->x + (draw->width / 2.0)) / video_width,
|
||||
(draw->y + (draw->height / 2.0)) / video_height,
|
||||
0);
|
||||
matrix_4x4_multiply(m1, mop, m2);
|
||||
matrix_4x4_multiply(m2, d3d->mvp_transposed, m1);
|
||||
d3d_matrix_transpose(&m1, &m2);
|
||||
|
||||
d3d8_set_mvp(dev, &m1);
|
||||
|
||||
if (draw->texture)
|
||||
{
|
||||
IDirect3DDevice8_SetTexture(dev, 0,
|
||||
(IDirect3DBaseTexture8*)draw->texture);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, D3DTEXF_COMM_LINEAR);
|
||||
}
|
||||
|
||||
type = gfx_display_prim_to_d3d8_enum(draw->prim_type);
|
||||
start = d3d->menu_display.offset;
|
||||
count = draw->coords->vertices -
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP)
|
||||
? 2 : 0);
|
||||
|
||||
IDirect3DDevice8_BeginScene(dev);
|
||||
IDirect3DDevice8_DrawPrimitive(dev, type, start, count);
|
||||
IDirect3DDevice8_EndScene(dev);
|
||||
|
||||
d3d->menu_display.offset += draw->coords->vertices;
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d8 = {
|
||||
gfx_display_d3d8_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
gfx_display_d3d8_blend_begin,
|
||||
gfx_display_d3d8_blend_end,
|
||||
gfx_display_d3d8_get_default_mvp,
|
||||
gfx_display_d3d8_get_default_vertices,
|
||||
gfx_display_d3d8_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_D3D8_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D8,
|
||||
"d3d8",
|
||||
false,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* VIDEO DRIVER
|
||||
*/
|
||||
|
||||
static void d3d8_viewport_info(void *data, struct video_viewport *vp)
|
||||
{
|
||||
unsigned width, height;
|
||||
|
@ -101,6 +101,301 @@ typedef struct cg_renderchain
|
||||
CGcontext cgCtx;
|
||||
} cg_renderchain_t;
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float d3d9_cg_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float d3d9_cg_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_d3d9_cg_get_default_vertices(void)
|
||||
{
|
||||
return &d3d9_cg_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_d3d9_cg_get_default_tex_coords(void)
|
||||
{
|
||||
return &d3d9_cg_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_d3d9_cg_get_default_mvp(void *data)
|
||||
{
|
||||
static float id[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
return &id;
|
||||
}
|
||||
|
||||
static INT32 gfx_display_prim_to_d3d9_cg_enum(
|
||||
enum gfx_display_prim_type prim_type)
|
||||
{
|
||||
switch (prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return D3DPT_COMM_TRIANGLESTRIP;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - hack */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_blend_begin(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, true);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_blend_end(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
math_matrix_4x4 mop, m1, m2;
|
||||
LPDIRECT3DDEVICE9 dev;
|
||||
D3DPRIMITIVETYPE type;
|
||||
unsigned start = 0;
|
||||
unsigned count = 0;
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
Vertex * pv = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
|
||||
if (!d3d || !draw || draw->pipeline_id)
|
||||
return;
|
||||
|
||||
dev = d3d->dev;
|
||||
|
||||
if ((d3d->menu_display.offset + draw->coords->vertices )
|
||||
> (unsigned)d3d->menu_display.size)
|
||||
return;
|
||||
|
||||
IDirect3DVertexBuffer9_Lock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer, 0, 0, (void**)&pv, 0);
|
||||
if (!pv)
|
||||
return;
|
||||
|
||||
pv += d3d->menu_display.offset;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &d3d9_cg_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &d3d9_cg_tex_coords[0];
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
int colors[4];
|
||||
|
||||
colors[0] = *color++ * 0xFF;
|
||||
colors[1] = *color++ * 0xFF;
|
||||
colors[2] = *color++ * 0xFF;
|
||||
colors[3] = *color++ * 0xFF;
|
||||
|
||||
pv[i].x = *vertex++;
|
||||
pv[i].y = *vertex++;
|
||||
pv[i].z = 0.5f;
|
||||
pv[i].u = *tex_coord++;
|
||||
pv[i].v = *tex_coord++;
|
||||
|
||||
pv[i].color =
|
||||
D3DCOLOR_ARGB(
|
||||
colors[3], /* A */
|
||||
colors[0], /* R */
|
||||
colors[1], /* G */
|
||||
colors[2] /* B */
|
||||
);
|
||||
}
|
||||
IDirect3DVertexBuffer9_Unlock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer);
|
||||
|
||||
if (!draw->matrix_data)
|
||||
draw->matrix_data = gfx_display_d3d9_cg_get_default_mvp(d3d);
|
||||
|
||||
/* ugh */
|
||||
matrix_4x4_scale(m1, 2.0, 2.0, 0);
|
||||
matrix_4x4_translate(mop, -1.0, -1.0, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_multiply(m1,
|
||||
*((math_matrix_4x4*)draw->matrix_data), m2);
|
||||
matrix_4x4_scale(mop,
|
||||
(draw->width / 2.0) / video_width,
|
||||
(draw->height / 2.0) / video_height, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_translate(mop,
|
||||
(draw->x + (draw->width / 2.0)) / video_width,
|
||||
(draw->y + (draw->height / 2.0)) / video_height,
|
||||
0);
|
||||
matrix_4x4_multiply(m1, mop, m2);
|
||||
matrix_4x4_multiply(m2, d3d->mvp_transposed, m1);
|
||||
d3d_matrix_transpose(&m1, &m2);
|
||||
|
||||
IDirect3DDevice9_SetVertexShaderConstantF(dev,
|
||||
0, (const float*)&m1, 4);
|
||||
|
||||
if (draw->texture)
|
||||
{
|
||||
IDirect3DDevice9_SetTexture(dev, 0,
|
||||
(IDirect3DBaseTexture9*)draw->texture);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSU, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSV, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MINFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MAGFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev, 0,
|
||||
D3DSAMP_MIPFILTER, D3DTEXF_COMM_LINEAR);
|
||||
}
|
||||
|
||||
type = (D3DPRIMITIVETYPE)gfx_display_prim_to_d3d9_cg_enum(draw->prim_type);
|
||||
start = d3d->menu_display.offset;
|
||||
count = draw->coords->vertices -
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP)
|
||||
? 2 : 0);
|
||||
|
||||
IDirect3DDevice9_BeginScene(dev);
|
||||
IDirect3DDevice9_DrawPrimitive(dev, type, start, count);
|
||||
IDirect3DDevice9_EndScene(dev);
|
||||
|
||||
d3d->menu_display.offset += draw->coords->vertices;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_draw_pipeline(gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
static float t = 0;
|
||||
video_coord_array_t *ca = NULL;
|
||||
|
||||
if (!draw)
|
||||
return;
|
||||
|
||||
ca = &p_disp->dispca;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->coords = NULL;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
if (ca)
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
{
|
||||
struct uniform_info uniform_param = {0};
|
||||
t += 0.01;
|
||||
|
||||
(void)uniform_param;
|
||||
|
||||
uniform_param.enabled = true;
|
||||
uniform_param.lookup.enable = true;
|
||||
uniform_param.lookup.add_prefix = true;
|
||||
uniform_param.lookup.idx = draw->pipeline_id;
|
||||
uniform_param.lookup.type = SHADER_PROGRAM_VERTEX;
|
||||
uniform_param.type = UNIFORM_1F;
|
||||
uniform_param.lookup.ident = "time";
|
||||
uniform_param.result.f.v0 = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_cg_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_cg_scissor_end(void *data,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d9_cg = {
|
||||
gfx_display_d3d9_cg_draw,
|
||||
gfx_display_d3d9_cg_draw_pipeline,
|
||||
gfx_display_d3d9_cg_blend_begin,
|
||||
gfx_display_d3d9_cg_blend_end,
|
||||
gfx_display_d3d9_cg_get_default_mvp,
|
||||
gfx_display_d3d9_cg_get_default_vertices,
|
||||
gfx_display_d3d9_cg_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_D3D9_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D9_CG,
|
||||
"d3d9_cg",
|
||||
false,
|
||||
gfx_display_d3d9_cg_scissor_begin,
|
||||
gfx_display_d3d9_cg_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* VIDEO DRIVER
|
||||
*/
|
||||
|
||||
static INLINE bool d3d9_cg_validate_param_name(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
@ -91,6 +91,306 @@ typedef struct hlsl_renderchain
|
||||
struct shader_pass stock_shader;
|
||||
} hlsl_renderchain_t;
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float d3d9_hlsl_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float d3d9_hlsl_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_d3d9_hlsl_get_default_vertices(void)
|
||||
{
|
||||
return &d3d9_hlsl_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_d3d9_hlsl_get_default_tex_coords(void)
|
||||
{
|
||||
return &d3d9_hlsl_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_d3d9_hlsl_get_default_mvp(void *data)
|
||||
{
|
||||
static float id[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
return &id;
|
||||
}
|
||||
|
||||
static INT32 gfx_display_prim_to_d3d9_hlsl_enum(
|
||||
enum gfx_display_prim_type prim_type)
|
||||
{
|
||||
switch (prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return D3DPT_COMM_TRIANGLESTRIP;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - hack */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_blend_begin(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, true);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_blend_end(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (d3d)
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_bind_texture(gfx_display_ctx_draw_t *draw,
|
||||
d3d9_video_t *d3d)
|
||||
{
|
||||
LPDIRECT3DDEVICE9 dev = d3d->dev;
|
||||
|
||||
IDirect3DDevice9_SetTexture(dev, 0,
|
||||
(IDirect3DBaseTexture9*)draw->texture);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSU, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSV, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MINFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MAGFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev, 0,
|
||||
D3DSAMP_MIPFILTER, D3DTEXF_COMM_LINEAR);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
math_matrix_4x4 mop, m1, m2;
|
||||
LPDIRECT3DDEVICE9 dev;
|
||||
D3DPRIMITIVETYPE type;
|
||||
unsigned start = 0;
|
||||
unsigned count = 0;
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
Vertex * pv = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
|
||||
if (!d3d || !draw || draw->pipeline_id)
|
||||
return;
|
||||
|
||||
dev = d3d->dev;
|
||||
|
||||
if ((d3d->menu_display.offset + draw->coords->vertices )
|
||||
> (unsigned)d3d->menu_display.size)
|
||||
return;
|
||||
|
||||
IDirect3DVertexBuffer9_Lock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer, 0, 0, (void**)&pv, 0);
|
||||
if (!pv)
|
||||
return;
|
||||
|
||||
pv += d3d->menu_display.offset;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &d3d9_hlsl_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &d3d9_hlsl_tex_coords[0];
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
int colors[4];
|
||||
|
||||
colors[0] = *color++ * 0xFF;
|
||||
colors[1] = *color++ * 0xFF;
|
||||
colors[2] = *color++ * 0xFF;
|
||||
colors[3] = *color++ * 0xFF;
|
||||
|
||||
pv[i].x = *vertex++;
|
||||
pv[i].y = *vertex++;
|
||||
pv[i].z = 0.5f;
|
||||
pv[i].u = *tex_coord++;
|
||||
pv[i].v = *tex_coord++;
|
||||
|
||||
pv[i].color =
|
||||
D3DCOLOR_ARGB(
|
||||
colors[3], /* A */
|
||||
colors[0], /* R */
|
||||
colors[1], /* G */
|
||||
colors[2] /* B */
|
||||
);
|
||||
}
|
||||
IDirect3DVertexBuffer9_Unlock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer);
|
||||
|
||||
if (!draw->matrix_data)
|
||||
draw->matrix_data = gfx_display_d3d9_hlsl_get_default_mvp(d3d);
|
||||
|
||||
/* ugh */
|
||||
matrix_4x4_scale(m1, 2.0, 2.0, 0);
|
||||
matrix_4x4_translate(mop, -1.0, -1.0, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_multiply(m1,
|
||||
*((math_matrix_4x4*)draw->matrix_data), m2);
|
||||
matrix_4x4_scale(mop,
|
||||
(draw->width / 2.0) / video_width,
|
||||
(draw->height / 2.0) / video_height, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_translate(mop,
|
||||
(draw->x + (draw->width / 2.0)) / video_width,
|
||||
(draw->y + (draw->height / 2.0)) / video_height,
|
||||
0);
|
||||
matrix_4x4_multiply(m1, mop, m2);
|
||||
matrix_4x4_multiply(m2, d3d->mvp_transposed, m1);
|
||||
|
||||
IDirect3DDevice9_SetVertexShaderConstantF(d3d->dev,
|
||||
0, (const float*)&m2, 4);
|
||||
|
||||
if (draw && draw->texture)
|
||||
gfx_display_d3d9_bind_texture(draw, d3d);
|
||||
|
||||
type = (D3DPRIMITIVETYPE)gfx_display_prim_to_d3d9_hlsl_enum(draw->prim_type);
|
||||
start = d3d->menu_display.offset;
|
||||
count = draw->coords->vertices -
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP)
|
||||
? 2 : 0);
|
||||
|
||||
IDirect3DDevice9_BeginScene(dev);
|
||||
IDirect3DDevice9_DrawPrimitive(dev, type, start, count);
|
||||
IDirect3DDevice9_EndScene(dev);
|
||||
|
||||
d3d->menu_display.offset += draw->coords->vertices;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
static float t = 0;
|
||||
video_coord_array_t *ca = NULL;
|
||||
|
||||
if (!draw)
|
||||
return;
|
||||
|
||||
ca = &p_disp->dispca;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->coords = NULL;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
if (ca)
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
/* TODO/FIXME - implement */
|
||||
#if 0
|
||||
{
|
||||
struct uniform_info uniform_param = {0};
|
||||
t += 0.01;
|
||||
|
||||
uniform_param.enabled = true;
|
||||
uniform_param.lookup.enable = true;
|
||||
uniform_param.lookup.add_prefix = true;
|
||||
uniform_param.lookup.idx = draw->pipeline_id;
|
||||
uniform_param.lookup.type = SHADER_PROGRAM_VERTEX;
|
||||
uniform_param.type = UNIFORM_1F;
|
||||
uniform_param.lookup.ident = "time";
|
||||
uniform_param.result.f.v0 = t;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_hlsl_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_hlsl_scissor_end(void *data,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d9_hlsl = {
|
||||
gfx_display_d3d9_hlsl_draw,
|
||||
gfx_display_d3d9_hlsl_draw_pipeline,
|
||||
gfx_display_d3d9_hlsl_blend_begin,
|
||||
gfx_display_d3d9_hlsl_blend_end,
|
||||
gfx_display_d3d9_hlsl_get_default_mvp,
|
||||
gfx_display_d3d9_hlsl_get_default_vertices,
|
||||
gfx_display_d3d9_hlsl_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_D3D9_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D9_HLSL,
|
||||
"d3d9_hlsl",
|
||||
false,
|
||||
gfx_display_d3d9_hlsl_scissor_begin,
|
||||
gfx_display_d3d9_hlsl_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* VIDEO DRIVER
|
||||
*/
|
||||
|
||||
static void *d3d9_hlsl_get_constant_by_name(LPD3DXCONSTANTTABLE prog, const char *name)
|
||||
{
|
||||
char lbl[64];
|
||||
|
@ -46,6 +46,108 @@
|
||||
#include "../common/win32_common.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float *gfx_display_gdi_get_default_vertices(void)
|
||||
{
|
||||
static float dummy[16] = {0.0f};
|
||||
return &dummy[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gdi_get_default_tex_coords(void)
|
||||
{
|
||||
static float dummy[16] = {0.0f};
|
||||
return &dummy[0];
|
||||
}
|
||||
|
||||
static void gfx_display_gdi_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
struct gdi_texture *texture = NULL;
|
||||
gdi_t *gdi = (gdi_t*)data;
|
||||
BITMAPINFO info = {{0}};
|
||||
|
||||
if (!gdi || !draw || draw->x < 0 || draw->y < 0 || draw->width <= 1 || draw->height <= 1)
|
||||
return;
|
||||
|
||||
texture = (struct gdi_texture*)draw->texture;
|
||||
|
||||
if (!texture || texture->width <= 1 || texture->height <= 1)
|
||||
return;
|
||||
|
||||
info.bmiHeader.biBitCount = 32;
|
||||
info.bmiHeader.biWidth = texture->width;
|
||||
info.bmiHeader.biHeight = -texture->height;
|
||||
info.bmiHeader.biPlanes = 1;
|
||||
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
info.bmiHeader.biSizeImage = 0;
|
||||
info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
if (gdi->memDC)
|
||||
{
|
||||
#if _WIN32_WINNT >= 0x0410 /* Win98 */
|
||||
BLENDFUNCTION blend = {0};
|
||||
#endif
|
||||
|
||||
if (!gdi->texDC)
|
||||
gdi->texDC = CreateCompatibleDC(gdi->winDC);
|
||||
|
||||
if (texture->bmp)
|
||||
texture->bmp_old = (HBITMAP)SelectObject(gdi->texDC, texture->bmp);
|
||||
else
|
||||
{
|
||||
/* scale texture data into a bitmap we can easily blit later */
|
||||
texture->bmp = CreateCompatibleBitmap(gdi->winDC, draw->width, draw->height);
|
||||
texture->bmp_old = (HBITMAP)SelectObject(gdi->texDC, texture->bmp);
|
||||
|
||||
StretchDIBits(gdi->texDC, 0, 0, draw->width, draw->height, 0, 0, texture->width, texture->height, texture->data, &info, DIB_RGB_COLORS, SRCCOPY);
|
||||
}
|
||||
|
||||
gdi->bmp_old = (HBITMAP)SelectObject(gdi->memDC, gdi->bmp);
|
||||
|
||||
#if _WIN32_WINNT >= 0x0410 /* Win98 */
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
blend.BlendFlags = 0;
|
||||
blend.SourceConstantAlpha = 255;
|
||||
#if 0
|
||||
clamp_8bit(draw->coords->color[3] * 255.0f);
|
||||
#endif
|
||||
blend.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
/* AlphaBlend() is only available since Win98 */
|
||||
AlphaBlend(gdi->memDC, draw->x, video_height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, blend);
|
||||
#if 0
|
||||
TransparentBlt(gdi->memDC, draw->x, video_height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, 0);
|
||||
#endif
|
||||
#else
|
||||
/* Just draw without the blending */
|
||||
StretchBlt(gdi->memDC, draw->x, video_height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, SRCCOPY);
|
||||
|
||||
#endif
|
||||
|
||||
SelectObject(gdi->memDC, gdi->bmp_old);
|
||||
SelectObject(gdi->texDC, texture->bmp_old);
|
||||
}
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gdi = {
|
||||
gfx_display_gdi_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
NULL, /* get_default_mvp */
|
||||
gfx_display_gdi_get_default_vertices,
|
||||
gfx_display_gdi_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_GDI,
|
||||
GFX_VIDEO_DRIVER_GDI,
|
||||
"gdi",
|
||||
false,
|
||||
NULL, /* scissor_begin */
|
||||
NULL /* scissor_end */
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -75,6 +75,187 @@ static void gl1_set_viewport(gl1_t *gl1,
|
||||
unsigned viewport_height,
|
||||
bool force_full, bool allow_rotate);
|
||||
|
||||
/**
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const GLfloat gl1_menu_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const GLfloat gl1_menu_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_gl1_get_default_vertices(void)
|
||||
{
|
||||
return &gl1_menu_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl1_get_default_tex_coords(void)
|
||||
{
|
||||
return &gl1_menu_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_gl1_get_default_mvp(void *data)
|
||||
{
|
||||
gl1_t *gl1 = (gl1_t*)data;
|
||||
|
||||
if (!gl1)
|
||||
return NULL;
|
||||
|
||||
return &gl1->mvp_no_rot;
|
||||
}
|
||||
|
||||
static GLenum gfx_display_prim_to_gl1_enum(
|
||||
enum gfx_display_prim_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return GL_TRIANGLE_STRIP;
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
return GL_TRIANGLES;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_blend_begin(void *data)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_blend_end(void *data)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
const GLfloat *mvp_matrix;
|
||||
gl1_t *gl1 = (gl1_t*)data;
|
||||
|
||||
if (!gl1 || !draw)
|
||||
return;
|
||||
|
||||
if (!draw->coords->vertex)
|
||||
draw->coords->vertex = &gl1_menu_vertexes[0];
|
||||
if (!draw->coords->tex_coord)
|
||||
draw->coords->tex_coord = &gl1_menu_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &gl1_menu_tex_coords[0];
|
||||
if (!draw->texture)
|
||||
return;
|
||||
|
||||
glViewport(draw->x, draw->y, draw->width, draw->height);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture);
|
||||
|
||||
mvp_matrix = draw->matrix_data ? (const GLfloat*)draw->matrix_data
|
||||
: (const GLfloat*)&gl1->mvp_no_rot;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadMatrixf(mvp_matrix);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
#ifdef VITA
|
||||
{
|
||||
unsigned i;
|
||||
static float *vertices3 = NULL;
|
||||
|
||||
if (vertices3)
|
||||
free(vertices3);
|
||||
vertices3 = (float*)malloc(sizeof(float) * 3 * draw->coords->vertices);
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
memcpy(&vertices3[i * 3],
|
||||
&draw->coords->vertex[i * 2],
|
||||
sizeof(float) * 2);
|
||||
vertices3[i * 3 + 2] = 0.0f;
|
||||
}
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertices3);
|
||||
}
|
||||
#else
|
||||
glVertexPointer(2, GL_FLOAT, 0, draw->coords->vertex);
|
||||
#endif
|
||||
|
||||
glColorPointer(4, GL_FLOAT, 0, draw->coords->color);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, draw->coords->tex_coord);
|
||||
|
||||
glDrawArrays(gfx_display_prim_to_gl1_enum(
|
||||
draw->prim_type), 0, draw->coords->vertices);
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
gl1->coords.color = gl1->white_color_ptr;
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
glScissor(x, video_height - y - height, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
glScissor(0, 0, video_width, video_height);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gl1 = {
|
||||
gfx_display_gl1_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
gfx_display_gl1_blend_begin,
|
||||
gfx_display_gl1_blend_end,
|
||||
gfx_display_gl1_get_default_mvp,
|
||||
gfx_display_gl1_get_default_vertices,
|
||||
gfx_display_gl1_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_OPENGL1_API,
|
||||
GFX_VIDEO_DRIVER_OPENGL1,
|
||||
"gl1",
|
||||
false,
|
||||
gfx_display_gl1_scissor_begin,
|
||||
gfx_display_gl1_scissor_end
|
||||
};
|
||||
|
||||
/**
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -106,6 +106,366 @@ static void gl2_set_viewport(gl2_t *gl,
|
||||
unsigned viewport_height,
|
||||
bool force_full, bool allow_rotate);
|
||||
|
||||
/**
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
static int scx0, scx1, scy0, scy1;
|
||||
|
||||
/* This array contains problematic GPU drivers
|
||||
* that have problems when we draw outside the
|
||||
* bounds of the framebuffer */
|
||||
static const struct
|
||||
{
|
||||
const char *str;
|
||||
int len;
|
||||
} scissor_device_strings[] = {
|
||||
{ "ARM Mali-4xx", 10 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void scissor_set_rectangle(
|
||||
int x0, int x1, int y0, int y1, int sc)
|
||||
{
|
||||
const int dx = sc ? 10 : 2;
|
||||
const int dy = dx;
|
||||
scx0 = x0 + dx;
|
||||
scx1 = x1 - dx;
|
||||
scy0 = y0 + dy;
|
||||
scy1 = y1 - dy;
|
||||
}
|
||||
|
||||
static bool scissor_is_outside_rectangle(
|
||||
int x0, int x1, int y0, int y1)
|
||||
{
|
||||
if (x1 < scx0)
|
||||
return true;
|
||||
if (scx1 < x0)
|
||||
return true;
|
||||
if (y1 < scy0)
|
||||
return true;
|
||||
if (scy1 < y0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MALI_BUG
|
||||
#endif
|
||||
|
||||
static const GLfloat gl2_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const GLfloat gl2_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_gl2_get_default_vertices(void)
|
||||
{
|
||||
return &gl2_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl2_get_default_tex_coords(void)
|
||||
{
|
||||
return &gl2_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_gl2_get_default_mvp(void *data)
|
||||
{
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
|
||||
if (!gl)
|
||||
return NULL;
|
||||
|
||||
return &gl->mvp_no_rot;
|
||||
}
|
||||
|
||||
static GLenum gfx_display_prim_to_gl_enum(
|
||||
enum gfx_display_prim_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return GL_TRIANGLE_STRIP;
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
return GL_TRIANGLES;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_blend_begin(void *data)
|
||||
{
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl->shader->use(gl, gl->shader_data, VIDEO_SHADER_STOCK_BLEND,
|
||||
true);
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_blend_end(void *data)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
#ifdef MALI_BUG
|
||||
static bool
|
||||
gfx_display_gl2_discard_draw_rectangle(gfx_display_ctx_draw_t *draw,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
static bool mali_4xx_detected = false;
|
||||
static bool scissor_inited = false;
|
||||
static unsigned last_video_width = 0;
|
||||
static unsigned last_video_height = 0;
|
||||
|
||||
if (!scissor_inited)
|
||||
{
|
||||
unsigned i;
|
||||
const char *gpu_device_string = NULL;
|
||||
scissor_inited = true;
|
||||
|
||||
scissor_set_rectangle(0,
|
||||
width - 1,
|
||||
0,
|
||||
height - 1,
|
||||
0);
|
||||
|
||||
/* TODO/FIXME - This might be thread unsafe in the long run -
|
||||
* preferably call this once outside of the menu display driver
|
||||
* and then just pass this string as a parameter */
|
||||
gpu_device_string = video_driver_get_gpu_device_string();
|
||||
|
||||
if (gpu_device_string)
|
||||
{
|
||||
for (i = 0; scissor_device_strings[i].len; ++i)
|
||||
{
|
||||
if (strncmp(gpu_device_string,
|
||||
scissor_device_strings[i].str,
|
||||
scissor_device_strings[i].len) == 0)
|
||||
{
|
||||
mali_4xx_detected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_video_width = width;
|
||||
last_video_height = height;
|
||||
}
|
||||
|
||||
/* Early out, to minimise performance impact on
|
||||
* non-mali_4xx devices */
|
||||
if (!mali_4xx_detected)
|
||||
return false;
|
||||
|
||||
/* Have to update scissor_set_rectangle() if the
|
||||
* video dimensions change */
|
||||
if ( (width != last_video_width)
|
||||
|| (height != last_video_height))
|
||||
{
|
||||
scissor_set_rectangle(0,
|
||||
width - 1,
|
||||
0,
|
||||
height - 1,
|
||||
0);
|
||||
|
||||
last_video_width = width;
|
||||
last_video_height = height;
|
||||
}
|
||||
|
||||
/* Discards not only out-of-bounds scissoring,
|
||||
* but also out-of-view draws.
|
||||
*
|
||||
* This is intentional.
|
||||
*/
|
||||
return scissor_is_outside_rectangle(
|
||||
draw->x, draw->x + draw->width - 1,
|
||||
draw->y, draw->y + draw->height - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gfx_display_gl2_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
|
||||
if (!gl || !draw)
|
||||
return;
|
||||
|
||||
#ifdef MALI_BUG
|
||||
if (gfx_display_gl2_discard_draw_rectangle(draw, video_width,
|
||||
video_height))
|
||||
{
|
||||
/*RARCH_WARN("[Menu]: discarded draw rect: %.4i %.4i %.4i %.4i\n",
|
||||
(int)draw->x, (int)draw->y, (int)draw->width, (int)draw->height);*/
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!draw->coords->vertex)
|
||||
draw->coords->vertex = &gl2_vertexes[0];
|
||||
if (!draw->coords->tex_coord)
|
||||
draw->coords->tex_coord = &gl2_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &gl2_tex_coords[0];
|
||||
|
||||
glViewport(draw->x, draw->y, draw->width, draw->height);
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture);
|
||||
|
||||
gl->shader->set_coords(gl->shader_data, draw->coords);
|
||||
gl->shader->set_mvp(gl->shader_data,
|
||||
draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data
|
||||
: (math_matrix_4x4*)&gl->mvp_no_rot);
|
||||
|
||||
|
||||
glDrawArrays(gfx_display_prim_to_gl_enum(
|
||||
draw->prim_type), 0, draw->coords->vertices);
|
||||
|
||||
gl->coords.color = gl->white_color_ptr;
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
struct uniform_info uniform_param;
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
static float t = 0;
|
||||
video_coord_array_t *ca = &p_disp->dispca;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->coords = (struct video_coords*)(&ca->coords);
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
break;
|
||||
default:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
gl->shader->use(gl, gl->shader_data, draw->pipeline_id,
|
||||
true);
|
||||
|
||||
t += 0.01;
|
||||
|
||||
uniform_param.type = UNIFORM_1F;
|
||||
uniform_param.enabled = true;
|
||||
uniform_param.location = 0;
|
||||
uniform_param.count = 0;
|
||||
|
||||
uniform_param.lookup.type = SHADER_PROGRAM_VERTEX;
|
||||
uniform_param.lookup.ident = "time";
|
||||
uniform_param.lookup.idx = draw->pipeline_id;
|
||||
uniform_param.lookup.add_prefix = true;
|
||||
uniform_param.lookup.enable = true;
|
||||
|
||||
uniform_param.result.f.v0 = t;
|
||||
|
||||
gl->shader->set_uniform_parameter(gl->shader_data,
|
||||
&uniform_param, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
#ifndef HAVE_PSGL
|
||||
uniform_param.type = UNIFORM_2F;
|
||||
uniform_param.lookup.ident = "OutputSize";
|
||||
uniform_param.result.f.v0 = draw->width;
|
||||
uniform_param.result.f.v1 = draw->height;
|
||||
|
||||
gl->shader->set_uniform_parameter(gl->shader_data,
|
||||
&uniform_param, NULL);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
glScissor(x, video_height - y - height, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#ifdef MALI_BUG
|
||||
/* TODO/FIXME: If video width/height changes between
|
||||
* a call of gfx_display_gl2_scissor_begin() and the
|
||||
* next call of gfx_display_gl2_draw() (or if
|
||||
* gfx_display_gl2_scissor_begin() is called before the
|
||||
* first call of gfx_display_gl2_draw()), the scissor
|
||||
* rectangle set here will be overwritten by the initialisation
|
||||
* procedure inside gfx_display_gl2_discard_draw_rectangle(),
|
||||
* causing the next frame to render glitched content */
|
||||
scissor_set_rectangle(x, x + width - 1, y, y + height - 1, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
glScissor(0, 0, video_width, video_height);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
#ifdef MALI_BUG
|
||||
scissor_set_rectangle(0, video_width - 1, 0, video_height - 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gl = {
|
||||
gfx_display_gl2_draw,
|
||||
gfx_display_gl2_draw_pipeline,
|
||||
gfx_display_gl2_blend_begin,
|
||||
gfx_display_gl2_blend_end,
|
||||
gfx_display_gl2_get_default_mvp,
|
||||
gfx_display_gl2_get_default_vertices,
|
||||
gfx_display_gl2_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_OPENGL_API,
|
||||
GFX_VIDEO_DRIVER_OPENGL,
|
||||
"gl",
|
||||
false,
|
||||
gfx_display_gl2_scissor_begin,
|
||||
gfx_display_gl2_scissor_end
|
||||
};
|
||||
|
||||
/**
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -67,6 +67,309 @@ static void gl3_set_viewport(gl3_t *gl,
|
||||
unsigned viewport_height,
|
||||
bool force_full, bool allow_rotate);
|
||||
|
||||
/**
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float gl3_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float gl3_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float gl3_colors[16] = {
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static void *gfx_display_gl3_get_default_mvp(void *data)
|
||||
{
|
||||
gl3_t *gl3 = (gl3_t*)data;
|
||||
if (!gl3)
|
||||
return NULL;
|
||||
return &gl3->mvp_no_rot;
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl3_get_default_vertices(void)
|
||||
{
|
||||
return &gl3_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl3_get_default_tex_coords(void)
|
||||
{
|
||||
return &gl3_tex_coords[0];
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
float output_size[2];
|
||||
static struct video_coords blank_coords;
|
||||
static uint8_t ubo_scratch_data[768];
|
||||
static float t = 0.0f;
|
||||
float yflip = 0.0f;
|
||||
video_coord_array_t *ca = NULL;
|
||||
gl3_t *gl = (gl3_t*)data;
|
||||
|
||||
if (!gl || !draw)
|
||||
return;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
output_size[0] = (float)video_width;
|
||||
output_size[1] = (float)video_height;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
/* Ribbon */
|
||||
default:
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
ca = &p_disp->dispca;
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = 2 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
yflip = -1.0f;
|
||||
memcpy(ubo_scratch_data, &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(float), &yflip, sizeof(yflip));
|
||||
break;
|
||||
|
||||
/* Snow simple */
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = sizeof(math_matrix_4x4)
|
||||
+ 4 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
memcpy(ubo_scratch_data,
|
||||
&gl->mvp_no_rot,
|
||||
sizeof(math_matrix_4x4));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4),
|
||||
output_size,
|
||||
sizeof(output_size));
|
||||
|
||||
if (draw->pipeline_id == VIDEO_SHADER_MENU_5)
|
||||
yflip = 1.0f;
|
||||
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 2 * sizeof(float), &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 3 * sizeof(float), &yflip, sizeof(yflip));
|
||||
draw->coords = &blank_coords;
|
||||
blank_coords.vertices = 4;
|
||||
draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP;
|
||||
break;
|
||||
}
|
||||
|
||||
t += 0.01;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
GLuint texture = 0;
|
||||
gl3_t *gl = (gl3_t*)data;
|
||||
const struct
|
||||
gl3_buffer_locations
|
||||
*loc = NULL;
|
||||
|
||||
if (!gl || !draw)
|
||||
return;
|
||||
|
||||
texture = (GLuint)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = gfx_display_gl3_get_default_vertices();
|
||||
if (!tex_coord)
|
||||
tex_coord = &gl3_tex_coords[0];
|
||||
if (!color)
|
||||
color = &gl3_colors[0];
|
||||
|
||||
glViewport(draw->x, draw->y, draw->width, draw->height);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
break;
|
||||
default:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
case VIDEO_SHADER_MENU:
|
||||
glUseProgram(gl->pipelines.ribbon);
|
||||
loc = &gl->pipelines.ribbon_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
glUseProgram(gl->pipelines.ribbon_simple);
|
||||
loc = &gl->pipelines.ribbon_simple_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
glUseProgram(gl->pipelines.snow_simple);
|
||||
loc = &gl->pipelines.snow_simple_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
glUseProgram(gl->pipelines.snow);
|
||||
loc = &gl->pipelines.snow_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
glUseProgram(gl->pipelines.bokeh);
|
||||
loc = &gl->pipelines.bokeh_loc;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
glUseProgram(gl->pipelines.alpha_blend);
|
||||
break;
|
||||
}
|
||||
|
||||
if (loc)
|
||||
{
|
||||
if (loc->flat_ubo_vertex >= 0)
|
||||
glUniform4fv(loc->flat_ubo_vertex,
|
||||
(GLsizei)((draw->backend_data_size + 15) / 16),
|
||||
(const GLfloat*)draw->backend_data);
|
||||
|
||||
if (loc->flat_ubo_fragment >= 0)
|
||||
glUniform4fv(loc->flat_ubo_fragment,
|
||||
(GLsizei)((draw->backend_data_size + 15) / 16),
|
||||
(const GLfloat*)draw->backend_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
const math_matrix_4x4 *mat = draw->matrix_data
|
||||
? (const math_matrix_4x4*)draw->matrix_data
|
||||
: (const math_matrix_4x4*)&gl->mvp_no_rot;
|
||||
if (gl->pipelines.alpha_blend_loc.flat_ubo_vertex >= 0)
|
||||
glUniform4fv(gl->pipelines.alpha_blend_loc.flat_ubo_vertex,
|
||||
4, mat->data);
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
gl3_bind_scratch_vbo(gl, vertex,
|
||||
2 * sizeof(float) * draw->coords->vertices);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), (void *)(uintptr_t)0);
|
||||
gl3_bind_scratch_vbo(gl, tex_coord,
|
||||
2 * sizeof(float) * draw->coords->vertices);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), (void *)(uintptr_t)0);
|
||||
gl3_bind_scratch_vbo(gl, color,
|
||||
4 * sizeof(float) * draw->coords->vertices);
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE,
|
||||
4 * sizeof(float), (void *)(uintptr_t)0);
|
||||
|
||||
switch (draw->prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices);
|
||||
break;
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
glDrawArrays(GL_TRIANGLES, 0, draw->coords->vertices);
|
||||
break;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glDisableVertexAttribArray(2);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_blend_begin(void *data)
|
||||
{
|
||||
gl3_t *gl = (gl3_t*)data;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUseProgram(gl->pipelines.alpha_blend);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_blend_end(void *data)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
glScissor(x, video_height - y - height, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gl3 = {
|
||||
gfx_display_gl3_draw,
|
||||
gfx_display_gl3_draw_pipeline,
|
||||
gfx_display_gl3_blend_begin,
|
||||
gfx_display_gl3_blend_end,
|
||||
gfx_display_gl3_get_default_mvp,
|
||||
gfx_display_gl3_get_default_vertices,
|
||||
gfx_display_gl3_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_OPENGL_CORE_API,
|
||||
GFX_VIDEO_DRIVER_OPENGL_CORE,
|
||||
"glcore",
|
||||
false,
|
||||
gfx_display_gl3_scissor_begin,
|
||||
gfx_display_gl3_scissor_end
|
||||
};
|
||||
|
||||
/**
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -47,15 +47,304 @@
|
||||
#include "../gfx_widgets.h"
|
||||
#endif
|
||||
|
||||
#include "gfx/common/gx2_defines.h"
|
||||
#include "gfx/video_shader_parse.h"
|
||||
#include "gfx/drivers_shader/slang_process.h"
|
||||
#include "system/memory.h"
|
||||
|
||||
#include "wiiu_dbg.h"
|
||||
#include "../common/gx2_defines.h"
|
||||
#include "../video_shader_parse.h"
|
||||
#include "../drivers_shader/slang_process.h"
|
||||
#include "../../wiiu/system/memory.h"
|
||||
#include "../../wiiu/wiiu_dbg.h"
|
||||
|
||||
#include "../font_driver.h"
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static void gfx_display_wiiu_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
wiiu_video_t *wiiu = (wiiu_video_t*)data;
|
||||
|
||||
if (!wiiu || !draw)
|
||||
return;
|
||||
|
||||
if (draw->pipeline_id)
|
||||
{
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK);
|
||||
|
||||
switch(draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
GX2SetShader(&ribbon_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
GX2SetShader(&ribbon_simple_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
GX2SetShader(&snow_simple_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
GX2SetShader(&snow_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
GX2SetShader(&bokeh_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
GX2SetShader(&snowflake_shader);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLE_STRIP, draw->coords->vertices, 0, 1);
|
||||
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
|
||||
GX2_BLEND_COMBINE_MODE_ADD,
|
||||
GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
|
||||
GX2_BLEND_COMBINE_MODE_ADD);
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
/* TODO come up with a better check for "not all vertexes are the same color" */
|
||||
else if (draw->coords->vertex || draw->coords->color[0] != draw->coords->color[12])
|
||||
{
|
||||
int i;
|
||||
if (wiiu->vertex_cache_tex.current + 4 > wiiu->vertex_cache_tex.size)
|
||||
return;
|
||||
|
||||
tex_shader_vertex_t* v = wiiu->vertex_cache_tex.v + wiiu->vertex_cache_tex.current;
|
||||
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK);
|
||||
GX2SetShader(&tex_shader);
|
||||
GX2SetVertexUniformBlock(tex_shader.vs.uniformBlocks[0].offset,
|
||||
tex_shader.vs.uniformBlocks[0].size,
|
||||
wiiu->ubo_mvp);
|
||||
GX2SetAttribBuffer(0, wiiu->vertex_cache_tex.size * sizeof(*wiiu->vertex_cache_tex.v),
|
||||
sizeof(*wiiu->vertex_cache_tex.v), wiiu->vertex_cache_tex.v);
|
||||
|
||||
if (!draw->coords->vertex)
|
||||
{
|
||||
/* Convert the libretro bottom-up coordinate system to GX2 - low y at
|
||||
the top of the screen, large y at the bottom
|
||||
The compiler will optimise 90% of this out anyway */
|
||||
float y = -(draw->y + draw->height - video_height);
|
||||
/* Remember: this is a triangle strip, not a quad, draw in a Z shape
|
||||
Bottom-left, right, top-left, right */
|
||||
v[0].pos.x = (draw->x ) / video_width;
|
||||
v[0].pos.y = (y + draw->height) / video_height;
|
||||
v[1].pos.x = (draw->x + draw->width ) / video_width;
|
||||
v[1].pos.y = (y + draw->height) / video_height;
|
||||
v[2].pos.x = (draw->x ) / video_width;
|
||||
v[2].pos.y = (y ) / video_height;
|
||||
v[3].pos.x = (draw->x + draw->width ) / video_width;
|
||||
v[3].pos.y = (y ) / video_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0].pos.x = draw->coords->vertex[0];
|
||||
v[0].pos.y = 1.0 - draw->coords->vertex[1];
|
||||
v[1].pos.x = draw->coords->vertex[2];
|
||||
v[1].pos.y = 1.0 - draw->coords->vertex[3];
|
||||
v[2].pos.x = draw->coords->vertex[4];
|
||||
v[2].pos.y = 1.0 - draw->coords->vertex[5];
|
||||
v[3].pos.x = draw->coords->vertex[6];
|
||||
v[3].pos.y = 1.0 - draw->coords->vertex[7];
|
||||
}
|
||||
|
||||
if (!draw->coords->tex_coord)
|
||||
{
|
||||
v[0].coord.u = 0.0f;
|
||||
v[0].coord.v = 1.0f;
|
||||
v[1].coord.u = 1.0f;
|
||||
v[1].coord.v = 1.0f;
|
||||
v[2].coord.u = 0.0f;
|
||||
v[2].coord.v = 0.0f;
|
||||
v[3].coord.u = 1.0f;
|
||||
v[3].coord.v = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0].coord.u = draw->coords->tex_coord[0];
|
||||
v[0].coord.v = draw->coords->tex_coord[1];
|
||||
v[1].coord.u = draw->coords->tex_coord[2];
|
||||
v[1].coord.v = draw->coords->tex_coord[3];
|
||||
v[2].coord.u = draw->coords->tex_coord[4];
|
||||
v[2].coord.v = draw->coords->tex_coord[5];
|
||||
v[3].coord.u = draw->coords->tex_coord[6];
|
||||
v[3].coord.v = draw->coords->tex_coord[7];
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
v[i].color.r = draw->coords->color[(i << 2) + 0];
|
||||
v[i].color.g = draw->coords->color[(i << 2) + 1];
|
||||
v[i].color.b = draw->coords->color[(i << 2) + 2];
|
||||
v[i].color.a = draw->coords->color[(i << 2) + 3];
|
||||
}
|
||||
|
||||
if (draw->texture)
|
||||
GX2SetPixelTexture((GX2Texture*)draw->texture, tex_shader.ps.samplerVars[0].location);
|
||||
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLE_STRIP, 4, wiiu->vertex_cache_tex.current, 1);
|
||||
wiiu->vertex_cache_tex.current += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite_vertex_t* v;
|
||||
if (wiiu->vertex_cache.current + 1 > wiiu->vertex_cache.size)
|
||||
return;
|
||||
|
||||
v = wiiu->vertex_cache.v + wiiu->vertex_cache.current;
|
||||
v->pos.x = draw->x;
|
||||
v->pos.y = wiiu->color_buffer.surface.height -
|
||||
draw->y - draw->height;
|
||||
v->pos.width = draw->width;
|
||||
v->pos.height = draw->height;
|
||||
v->coord.u = 0.0f;
|
||||
v->coord.v = 0.0f;
|
||||
v->coord.width = 1.0f;
|
||||
v->coord.height = 1.0f;
|
||||
|
||||
v->color = COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
|
||||
if (draw->texture)
|
||||
GX2SetPixelTexture((GX2Texture*)draw->texture, sprite_shader.ps.samplerVars[0].location);
|
||||
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, 1, wiiu->vertex_cache.current, 1);
|
||||
wiiu->vertex_cache.current ++;
|
||||
return;
|
||||
}
|
||||
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_GEOMETRY_SHADER);
|
||||
GX2SetShader(&sprite_shader);
|
||||
#if 0
|
||||
GX2SetGeometryShaderInputRingBuffer(wiiu->input_ring_buffer,
|
||||
wiiu->input_ring_buffer_size);
|
||||
GX2SetGeometryShaderOutputRingBuffer(wiiu->output_ring_buffer,
|
||||
wiiu->output_ring_buffer_size);
|
||||
#endif
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset,
|
||||
sprite_shader.vs.uniformBlocks[0].size,
|
||||
wiiu->ubo_vp);
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset,
|
||||
sprite_shader.vs.uniformBlocks[1].size,
|
||||
wiiu->ubo_tex);
|
||||
GX2SetAttribBuffer(0, wiiu->vertex_cache.size
|
||||
* sizeof(*wiiu->vertex_cache.v),
|
||||
sizeof(*wiiu->vertex_cache.v),
|
||||
wiiu->vertex_cache.v);
|
||||
}
|
||||
|
||||
static void gfx_display_wiiu_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
video_coord_array_t *ca = NULL;
|
||||
wiiu_video_t *wiiu = (wiiu_video_t*)data;
|
||||
|
||||
if (!wiiu || !draw)
|
||||
return;
|
||||
|
||||
switch(draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
ca = &p_disp->dispca;
|
||||
if (!wiiu->menu_shader_vbo)
|
||||
{
|
||||
wiiu->menu_shader_vbo = MEM2_alloc(ca->coords.vertices * 2 * sizeof(float), GX2_VERTEX_BUFFER_ALIGNMENT);
|
||||
memcpy(wiiu->menu_shader_vbo, ca->coords.vertex, ca->coords.vertices * 2 * sizeof(float));
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->menu_shader_vbo, ca->coords.vertices * 2 * sizeof(float));
|
||||
}
|
||||
|
||||
draw->coords->vertex = wiiu->menu_shader_vbo;
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
GX2SetAttribBuffer(0,
|
||||
draw->coords->vertices * 2 * sizeof(float),
|
||||
2 * sizeof(float), wiiu->menu_shader_vbo);
|
||||
GX2SetBlendControl(GX2_RENDER_TARGET_0,
|
||||
GX2_BLEND_MODE_SRC_ALPHA,
|
||||
GX2_BLEND_MODE_ONE,
|
||||
GX2_BLEND_COMBINE_MODE_ADD,
|
||||
GX2_DISABLE, 0, 0, 0);
|
||||
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
GX2SetAttribBuffer(0,
|
||||
4 * sizeof(*wiiu->v),
|
||||
sizeof(*wiiu->v), wiiu->v);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wiiu->menu_shader_ubo)
|
||||
{
|
||||
wiiu->menu_shader_ubo = MEM2_alloc(
|
||||
sizeof(*wiiu->menu_shader_ubo),
|
||||
GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
matrix_4x4_ortho(wiiu->menu_shader_ubo->mvp, 0, 1, 1, 0, -1, 1);
|
||||
wiiu->menu_shader_ubo->OutputSize.width = wiiu->color_buffer.surface.width;
|
||||
wiiu->menu_shader_ubo->OutputSize.height = wiiu->color_buffer.surface.height;
|
||||
wiiu->menu_shader_ubo->time = 0.0f;
|
||||
}
|
||||
else
|
||||
wiiu->menu_shader_ubo->time += 0.01f;
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->menu_shader_ubo, sizeof(*wiiu->menu_shader_ubo));
|
||||
GX2SetVertexUniformBlock(1, sizeof(*wiiu->menu_shader_ubo), wiiu->menu_shader_ubo);
|
||||
GX2SetPixelUniformBlock(1, sizeof(*wiiu->menu_shader_ubo), wiiu->menu_shader_ubo);
|
||||
}
|
||||
|
||||
static void gfx_display_wiiu_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
GX2SetScissor(MAX(x, 0), MAX(y, 0), MIN(width, video_width), MIN(height, video_height));
|
||||
}
|
||||
|
||||
static void gfx_display_wiiu_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height
|
||||
)
|
||||
{
|
||||
GX2SetScissor(0, 0, video_width, video_height);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_wiiu = {
|
||||
gfx_display_wiiu_draw,
|
||||
gfx_display_wiiu_draw_pipeline,
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_WIIU,
|
||||
GFX_VIDEO_DRIVER_WIIU,
|
||||
"gx2",
|
||||
true,
|
||||
gfx_display_wiiu_scissor_begin,
|
||||
gfx_display_wiiu_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -77,6 +77,108 @@
|
||||
x = (__bridge __typeof__(x))(__bridge_retained void *)((NSObject *)__y); \
|
||||
}
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float *gfx_display_metal_get_default_vertices(void)
|
||||
{
|
||||
return [MenuDisplay defaultVertices];
|
||||
}
|
||||
|
||||
static const float *gfx_display_metal_get_default_tex_coords(void)
|
||||
{
|
||||
return [MenuDisplay defaultTexCoords];
|
||||
}
|
||||
|
||||
static void *gfx_display_metal_get_default_mvp(void *data)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (!md)
|
||||
return NULL;
|
||||
|
||||
return (void *)&md.viewportMVP->projectionMatrix;
|
||||
}
|
||||
|
||||
static void gfx_display_metal_blend_begin(void *data)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md)
|
||||
md.display.blend = YES;
|
||||
}
|
||||
|
||||
static void gfx_display_metal_blend_end(void *data)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md)
|
||||
md.display.blend = NO;
|
||||
}
|
||||
|
||||
static void gfx_display_metal_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md && draw)
|
||||
[md.display draw:draw];
|
||||
}
|
||||
|
||||
static void gfx_display_metal_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md && draw)
|
||||
[md.display drawPipeline:draw];
|
||||
}
|
||||
|
||||
static void gfx_display_metal_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
MTLScissorRect r;
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (!md)
|
||||
return;
|
||||
|
||||
r.x = (NSUInteger)x;
|
||||
r.y = (NSUInteger)y;
|
||||
r.width = width;
|
||||
r.height = height;
|
||||
[md.display setScissorRect:r];
|
||||
}
|
||||
|
||||
static void gfx_display_metal_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md)
|
||||
[md.display clearScissorRect];
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_metal = {
|
||||
gfx_display_metal_draw,
|
||||
gfx_display_metal_draw_pipeline,
|
||||
gfx_display_metal_blend_begin,
|
||||
gfx_display_metal_blend_end,
|
||||
gfx_display_metal_get_default_mvp,
|
||||
gfx_display_metal_get_default_vertices,
|
||||
gfx_display_metal_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_METAL_API,
|
||||
GFX_VIDEO_DRIVER_METAL,
|
||||
"metal",
|
||||
false,
|
||||
gfx_display_metal_scissor_begin,
|
||||
gfx_display_metal_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -80,6 +80,216 @@
|
||||
static void rsx_set_viewport(void *data, unsigned viewport_width,
|
||||
unsigned viewport_height, bool force_full, bool allow_rotate);
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float rsx_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float rsx_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_rsx_get_default_vertices(void)
|
||||
{
|
||||
return &rsx_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_rsx_get_default_tex_coords(void)
|
||||
{
|
||||
return &rsx_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_rsx_get_default_mvp(void *data)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t*)data;
|
||||
|
||||
if (!rsx)
|
||||
return NULL;
|
||||
|
||||
return &rsx->mvp_no_rot;
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
rsx_viewport_t vp;
|
||||
int end_vert_idx;
|
||||
rsx_vertex_t *vertices = NULL;
|
||||
rsx_texture_t *texture = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
rsx_t *rsx = (rsx_t*)data;
|
||||
|
||||
if (!rsx || !draw)
|
||||
return;
|
||||
|
||||
texture = (rsx_texture_t *)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &rsx_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &rsx_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &rsx_tex_coords[0];
|
||||
if (!draw->texture)
|
||||
return;
|
||||
|
||||
vp.x = fabs(draw->x);
|
||||
vp.y = fabs(rsx->height - draw->y - draw->height);
|
||||
vp.w = MIN(draw->width, rsx->width);
|
||||
vp.h = MIN(draw->height, rsx->height);
|
||||
vp.min = 0.0f;
|
||||
vp.max = 1.0f;
|
||||
vp.scale[0] = vp.w * 0.5f;
|
||||
vp.scale[1] = vp.h * -0.5f;
|
||||
vp.scale[2] = (vp.max - vp.min) * 0.5f;
|
||||
vp.scale[3] = 0.0f;
|
||||
vp.offset[0] = vp.x + vp.w * 0.5f;
|
||||
vp.offset[1] = vp.y + vp.h * 0.5f;
|
||||
vp.offset[2] = (vp.max + vp.min) * 0.5f;
|
||||
vp.offset[3] = 0.0f;
|
||||
|
||||
rsxSetViewport(rsx->context, vp.x, vp.y, vp.w, vp.h, vp.min, vp.max, vp.scale, vp.offset);
|
||||
|
||||
rsxInvalidateTextureCache(rsx->context, GCM_INVALIDATE_TEXTURE);
|
||||
rsxLoadTexture(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, &texture->tex);
|
||||
rsxTextureControl(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index,
|
||||
GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
|
||||
rsxTextureFilter(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
|
||||
rsxTextureWrapMode(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, texture->wrap_s,
|
||||
texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
|
||||
|
||||
#if RSX_MAX_TEXTURE_VERTICES > 0
|
||||
/* Using preallocated texture vertices uses better memory managment but may cause more flickering */
|
||||
end_vert_idx = rsx->texture_vert_idx + draw->coords->vertices;
|
||||
if (end_vert_idx > RSX_MAX_TEXTURE_VERTICES)
|
||||
{
|
||||
rsx->texture_vert_idx = 0;
|
||||
end_vert_idx = rsx->texture_vert_idx + draw->coords->vertices;
|
||||
}
|
||||
vertices = &rsx->texture_vertices[rsx->texture_vert_idx];
|
||||
#else
|
||||
/* Smoother gfx at the cost of unmanaged rsx memory */
|
||||
rsx->texture_vert_idx = 0;
|
||||
end_vert_idx = draw->coords->vertices;
|
||||
vertices = (rsx_vertex_t *)rsxMemalign(128, sizeof(rsx_vertex_t) * draw->coords->vertices);
|
||||
#endif
|
||||
for (i = rsx->texture_vert_idx; i < end_vert_idx; i++)
|
||||
{
|
||||
vertices[i].x = *vertex++;
|
||||
vertices[i].y = *vertex++;
|
||||
vertices[i].u = *tex_coord++;
|
||||
vertices[i].v = *tex_coord++;
|
||||
vertices[i].r = *color++;
|
||||
vertices[i].g = *color++;
|
||||
vertices[i].b = *color++;
|
||||
vertices[i].a = *color++;
|
||||
}
|
||||
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].x,
|
||||
&rsx->pos_offset[RSX_SHADER_STOCK_BLEND]);
|
||||
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].u,
|
||||
&rsx->uv_offset[RSX_SHADER_STOCK_BLEND]);
|
||||
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].r,
|
||||
&rsx->col_offset[RSX_SHADER_STOCK_BLEND]);
|
||||
rsx->texture_vert_idx = end_vert_idx;
|
||||
|
||||
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
rsx->pos_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2,
|
||||
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
||||
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
rsx->uv_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2,
|
||||
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
||||
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
rsx->col_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 4,
|
||||
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
||||
|
||||
rsxLoadVertexProgram(rsx->context, rsx->vpo[RSX_SHADER_STOCK_BLEND],
|
||||
rsx->vp_ucode[RSX_SHADER_STOCK_BLEND]);
|
||||
rsxSetVertexProgramParameter(rsx->context,
|
||||
rsx->vpo[RSX_SHADER_STOCK_BLEND], rsx->proj_matrix[RSX_SHADER_STOCK_BLEND],
|
||||
(float *)&rsx->mvp_no_rot);
|
||||
rsxLoadFragmentProgramLocation(rsx->context,
|
||||
rsx->fpo[RSX_SHADER_STOCK_BLEND], rsx->fp_offset[RSX_SHADER_STOCK_BLEND],
|
||||
GCM_LOCATION_RSX);
|
||||
|
||||
rsxClearSurface(rsx->context, GCM_CLEAR_Z);
|
||||
rsxDrawVertexArray(rsx->context, GCM_TYPE_TRIANGLE_STRIP, 0, draw->coords->vertices);
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetScissor(rsx->context, x, video_height - y - height, width, height);
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetScissor(rsx->context, 0, 0, video_width, video_height);
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_blend_begin(void *data)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetBlendEnable(rsx->context, GCM_TRUE);
|
||||
rsxSetBlendFunc(rsx->context, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA);
|
||||
rsxSetBlendEquation(rsx->context, GCM_FUNC_ADD, GCM_FUNC_ADD);
|
||||
#if 0
|
||||
rsxSetBlendEnableMrt(rsx->context, GCM_TRUE, GCM_TRUE, GCM_TRUE);
|
||||
rsxSetDepthFunc(rsx->context, GCM_LESS);
|
||||
rsxSetDepthTestEnable(rsx->context, GCM_FALSE);
|
||||
rsxSetAlphaFunc(rsx->context, GCM_ALWAYS, 0);
|
||||
rsxSetAlphaTestEnable(rsx->context, GCM_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_blend_end(void *data)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetBlendEnable(rsx->context, GCM_FALSE);
|
||||
#if 0
|
||||
rsxSetBlendEnableMrt(rsx->context, GCM_FALSE, GCM_FALSE, GCM_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_rsx = {
|
||||
gfx_display_rsx_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
gfx_display_rsx_blend_begin,
|
||||
gfx_display_rsx_blend_end,
|
||||
gfx_display_rsx_get_default_mvp,
|
||||
gfx_display_rsx_get_default_vertices,
|
||||
gfx_display_rsx_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_RSX,
|
||||
GFX_VIDEO_DRIVER_RSX,
|
||||
"rsx",
|
||||
true,
|
||||
gfx_display_rsx_scissor_begin,
|
||||
gfx_display_rsx_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -53,6 +53,149 @@ static void vita2d_update_viewport(vita_video_t* vita,
|
||||
static void vita2d_set_viewport_wrapper(void *data, unsigned viewport_width,
|
||||
unsigned viewport_height, bool force_full, bool allow_rotate);
|
||||
|
||||
/*
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
static const float vita2d_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float vita2d_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float vita2d_colors[16] = {
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static const float *gfx_display_vita2d_get_default_vertices(void)
|
||||
{
|
||||
return &vita2d_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_vita2d_get_default_color(void)
|
||||
{
|
||||
return &vita2d_colors[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_vita2d_get_default_tex_coords(void)
|
||||
{
|
||||
return &vita2d_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_vita2d_get_default_mvp(void *data)
|
||||
{
|
||||
vita_video_t *vita2d = (vita_video_t*)data;
|
||||
|
||||
if (!vita2d)
|
||||
return NULL;
|
||||
|
||||
return &vita2d->mvp_no_rot;
|
||||
}
|
||||
|
||||
static void gfx_display_vita2d_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
struct vita2d_texture *texture = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
vita_video_t *vita2d = (vita_video_t*)data;
|
||||
|
||||
if (!vita2d || !draw)
|
||||
return;
|
||||
|
||||
texture = (struct vita2d_texture*)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &vita2d_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &vita2d_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &vita2d_tex_coords[0];
|
||||
if (!texture)
|
||||
return;
|
||||
if (!color)
|
||||
color = &vita2d_colors[0];
|
||||
|
||||
vita2d_set_viewport(draw->x, draw->y, draw->width, draw->height);
|
||||
vita2d_texture_tint_vertex *vertices = (vita2d_texture_tint_vertex *)vita2d_pool_memalign(
|
||||
draw->coords->vertices * sizeof(vita2d_texture_tint_vertex),
|
||||
sizeof(vita2d_texture_tint_vertex));
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
vertices[i].x = *vertex++;
|
||||
vertices[i].y = *vertex++;
|
||||
vertices[i].z = 1.0f;
|
||||
vertices[i].u = *tex_coord++;
|
||||
vertices[i].v = *tex_coord++;
|
||||
vertices[i].r = *color++;
|
||||
vertices[i].g = *color++;
|
||||
vertices[i].b = *color++;
|
||||
vertices[i].a = *color++;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
default:
|
||||
{
|
||||
vita2d_draw_array_textured_mat(texture, vertices, draw->coords->vertices, &vita2d->mvp_no_rot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_vita2d_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
vita2d_set_clip_rectangle(x, y, x + width, y + height);
|
||||
vita2d_set_region_clip(SCE_GXM_REGION_CLIP_OUTSIDE, x, y, x + width, y + height);
|
||||
}
|
||||
|
||||
static void gfx_display_vita2d_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
vita2d_set_region_clip(SCE_GXM_REGION_CLIP_NONE, 0, 0,
|
||||
video_width, video_height);
|
||||
vita2d_disable_clipping();
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_vita2d = {
|
||||
gfx_display_vita2d_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
gfx_display_vita2d_get_default_mvp,
|
||||
gfx_display_vita2d_get_default_vertices,
|
||||
gfx_display_vita2d_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_VITA2D,
|
||||
GFX_VIDEO_DRIVER_VITA2D,
|
||||
"vita2d",
|
||||
true,
|
||||
gfx_display_vita2d_scissor_begin,
|
||||
gfx_display_vita2d_scissor_end
|
||||
};
|
||||
|
||||
/*
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
@ -134,6 +134,183 @@ static unsigned vulkan_num_miplevels(unsigned width, unsigned height)
|
||||
return levels;
|
||||
}
|
||||
|
||||
static void vulkan_write_quad_descriptors(
|
||||
VkDevice device,
|
||||
VkDescriptorSet set,
|
||||
VkBuffer buffer,
|
||||
VkDeviceSize offset,
|
||||
VkDeviceSize range,
|
||||
const struct vk_texture *texture,
|
||||
VkSampler sampler)
|
||||
{
|
||||
VkWriteDescriptorSet write;
|
||||
VkDescriptorBufferInfo buffer_info;
|
||||
|
||||
buffer_info.buffer = buffer;
|
||||
buffer_info.offset = offset;
|
||||
buffer_info.range = range;
|
||||
|
||||
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write.pNext = NULL;
|
||||
write.dstSet = set;
|
||||
write.dstBinding = 0;
|
||||
write.dstArrayElement = 0;
|
||||
write.descriptorCount = 1;
|
||||
write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
write.pImageInfo = NULL;
|
||||
write.pBufferInfo = &buffer_info;
|
||||
write.pTexelBufferView = NULL;
|
||||
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
||||
|
||||
if (texture)
|
||||
{
|
||||
VkDescriptorImageInfo image_info;
|
||||
|
||||
image_info.sampler = sampler;
|
||||
image_info.imageView = texture->view;
|
||||
image_info.imageLayout = texture->layout;
|
||||
|
||||
write.dstSet = set;
|
||||
write.dstBinding = 1;
|
||||
write.descriptorCount = 1;
|
||||
write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
write.pImageInfo = &image_info;
|
||||
vkUpdateDescriptorSets(device, 1, &write, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void vulkan_transition_texture(vk_t *vk, VkCommandBuffer cmd, struct vk_texture *texture)
|
||||
{
|
||||
/* Transition to GENERAL layout for linear streamed textures.
|
||||
* We're using linear textures here, so only
|
||||
* GENERAL layout is supported.
|
||||
* If we're already in GENERAL, add a host -> shader read memory barrier
|
||||
* to invalidate texture caches.
|
||||
*/
|
||||
if (texture->layout != VK_IMAGE_LAYOUT_PREINITIALIZED &&
|
||||
texture->layout != VK_IMAGE_LAYOUT_GENERAL)
|
||||
return;
|
||||
|
||||
switch (texture->type)
|
||||
{
|
||||
case VULKAN_TEXTURE_STREAMED:
|
||||
VULKAN_IMAGE_LAYOUT_TRANSITION(cmd, texture->image,
|
||||
texture->layout, VK_IMAGE_LAYOUT_GENERAL,
|
||||
VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
|
||||
VK_PIPELINE_STAGE_HOST_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
break;
|
||||
|
||||
default:
|
||||
retro_assert(0 && "Attempting to transition invalid texture type.\n");
|
||||
break;
|
||||
}
|
||||
texture->layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
|
||||
/* The VBO needs to be written to before calling this.
|
||||
* Use vulkan_buffer_chain_alloc. */
|
||||
static void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call)
|
||||
{
|
||||
if (call->texture && call->texture->image)
|
||||
vulkan_transition_texture(vk, vk->cmd, call->texture);
|
||||
|
||||
if (call->pipeline != vk->tracker.pipeline)
|
||||
{
|
||||
VkRect2D sci;
|
||||
vkCmdBindPipeline(vk->cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS, call->pipeline);
|
||||
vk->tracker.pipeline = call->pipeline;
|
||||
|
||||
/* Changing pipeline invalidates dynamic state. */
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
|
||||
if (vk->flags & VK_FLAG_TRACKER_USE_SCISSOR)
|
||||
sci = vk->tracker.scissor;
|
||||
else
|
||||
{
|
||||
/* No scissor -> viewport */
|
||||
sci.offset.x = vk->vp.x;
|
||||
sci.offset.y = vk->vp.y;
|
||||
sci.extent.width = vk->vp.width;
|
||||
sci.extent.height = vk->vp.height;
|
||||
}
|
||||
|
||||
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
||||
vkCmdSetScissor (vk->cmd, 0, 1, &sci);
|
||||
|
||||
vk->tracker.dirty &= ~VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
else if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT)
|
||||
{
|
||||
VkRect2D sci;
|
||||
if (vk->flags & VK_FLAG_TRACKER_USE_SCISSOR)
|
||||
sci = vk->tracker.scissor;
|
||||
else
|
||||
{
|
||||
/* No scissor -> viewport */
|
||||
sci.offset.x = vk->vp.x;
|
||||
sci.offset.y = vk->vp.y;
|
||||
sci.extent.width = vk->vp.width;
|
||||
sci.extent.height = vk->vp.height;
|
||||
}
|
||||
|
||||
vkCmdSetViewport(vk->cmd, 0, 1, &vk->vk_vp);
|
||||
vkCmdSetScissor (vk->cmd, 0, 1, &sci);
|
||||
|
||||
vk->tracker.dirty &= ~VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
/* Upload descriptors */
|
||||
{
|
||||
VkDescriptorSet set;
|
||||
/* Upload UBO */
|
||||
struct vk_buffer_range range;
|
||||
float *mvp_data_ptr = NULL;
|
||||
|
||||
if (!vulkan_buffer_chain_alloc(vk->context, &vk->chain->ubo,
|
||||
call->uniform_size, &range))
|
||||
return;
|
||||
|
||||
memcpy(range.data, call->uniform, call->uniform_size);
|
||||
|
||||
set = vulkan_descriptor_manager_alloc(
|
||||
vk->context->device,
|
||||
&vk->chain->descriptor_manager);
|
||||
|
||||
vulkan_write_quad_descriptors(
|
||||
vk->context->device,
|
||||
set,
|
||||
range.buffer,
|
||||
range.offset,
|
||||
call->uniform_size,
|
||||
call->texture,
|
||||
call->sampler);
|
||||
|
||||
vkCmdBindDescriptorSets(vk->cmd,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
vk->pipelines.layout, 0,
|
||||
1, &set, 0, NULL);
|
||||
|
||||
vk->tracker.view = VK_NULL_HANDLE;
|
||||
vk->tracker.sampler = VK_NULL_HANDLE;
|
||||
for (
|
||||
mvp_data_ptr = &vk->tracker.mvp.data[0]
|
||||
; mvp_data_ptr < vk->tracker.mvp.data + 16
|
||||
; mvp_data_ptr++)
|
||||
*mvp_data_ptr = 0.0f;
|
||||
}
|
||||
|
||||
/* VBO is already uploaded. */
|
||||
vkCmdBindVertexBuffers(vk->cmd, 0, 1,
|
||||
&call->vbo->buffer, &call->vbo->offset);
|
||||
|
||||
/* Draw the quad */
|
||||
vkCmdDraw(vk->cmd, call->vertices, 1, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static void vulkan_destroy_texture(
|
||||
VkDevice device,
|
||||
struct vk_texture *tex)
|
||||
@ -782,9 +959,321 @@ static void vulkan_render_overlay(vk_t *vk, unsigned width, unsigned height);
|
||||
#endif
|
||||
static void vulkan_viewport_info(void *data, struct video_viewport *vp);
|
||||
|
||||
/**
|
||||
* DISPLAY DRIVER
|
||||
*/
|
||||
|
||||
/* Will do Y-flip later, but try to make it similar to GL. */
|
||||
static const float vk_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float vk_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float vk_colors[16] = {
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static void *gfx_display_vk_get_default_mvp(void *data)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
if (!vk)
|
||||
return NULL;
|
||||
return &vk->mvp_no_rot;
|
||||
}
|
||||
|
||||
static const float *gfx_display_vk_get_default_vertices(void)
|
||||
{
|
||||
return &vk_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_vk_get_default_tex_coords(void)
|
||||
{
|
||||
return &vk_tex_coords[0];
|
||||
}
|
||||
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
static unsigned to_menu_pipeline(
|
||||
enum gfx_display_prim_type type, unsigned pipeline)
|
||||
{
|
||||
switch (pipeline)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
return 6 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
return 8 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
return 10 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
return 12 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
return 14 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
static uint8_t ubo_scratch_data[768];
|
||||
static struct video_coords blank_coords;
|
||||
static float t = 0.0f;
|
||||
float output_size[2];
|
||||
float yflip = 1.0f;
|
||||
video_coord_array_t *ca = NULL;
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (!vk || !draw)
|
||||
return;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
output_size[0] = (float)vk->context->swapchain_width;
|
||||
output_size[1] = (float)vk->context->swapchain_height;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
/* Ribbon */
|
||||
default:
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
ca = &p_disp->dispca;
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = 2 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
memcpy(ubo_scratch_data, &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(float), &yflip, sizeof(yflip));
|
||||
break;
|
||||
|
||||
/* Snow simple */
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = sizeof(math_matrix_4x4)
|
||||
+ 4 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
memcpy(ubo_scratch_data,
|
||||
&vk->mvp_no_rot,
|
||||
sizeof(math_matrix_4x4));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4),
|
||||
output_size,
|
||||
sizeof(output_size));
|
||||
|
||||
/* Shader uses FragCoord, need to fix up. */
|
||||
if (draw->pipeline_id == VIDEO_SHADER_MENU_5)
|
||||
yflip = -1.0f;
|
||||
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 2 * sizeof(float), &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 3 * sizeof(float), &yflip, sizeof(yflip));
|
||||
draw->coords = &blank_coords;
|
||||
blank_coords.vertices = 4;
|
||||
draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP;
|
||||
break;
|
||||
}
|
||||
|
||||
t += 0.01;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gfx_display_vk_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
struct vk_buffer_range range;
|
||||
struct vk_texture *texture = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
struct vk_vertex *pv = NULL;
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (!vk || !draw)
|
||||
return;
|
||||
|
||||
texture = (struct vk_texture*)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &vk_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &vk_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &vk_tex_coords[0];
|
||||
if (!texture)
|
||||
texture = &vk->display.blank_texture;
|
||||
if (!color)
|
||||
color = &vk_colors[0];
|
||||
|
||||
vk->vk_vp.x = draw->x;
|
||||
vk->vk_vp.y = vk->context->swapchain_height - draw->y - draw->height;
|
||||
vk->vk_vp.width = draw->width;
|
||||
vk->vk_vp.height = draw->height;
|
||||
vk->vk_vp.minDepth = 0.0f;
|
||||
vk->vk_vp.maxDepth = 1.0f;
|
||||
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
|
||||
/* Bake interleaved VBO. Kinda ugly, we should probably try to move to
|
||||
* an interleaved model to begin with ... */
|
||||
if (!vulkan_buffer_chain_alloc(vk->context, &vk->chain->vbo,
|
||||
draw->coords->vertices * sizeof(struct vk_vertex), &range))
|
||||
return;
|
||||
|
||||
pv = (struct vk_vertex*)range.data;
|
||||
for (i = 0; i < draw->coords->vertices; i++, pv++)
|
||||
{
|
||||
pv->x = *vertex++;
|
||||
/* Y-flip. Vulkan is top-left clip space */
|
||||
pv->y = 1.0f - (*vertex++);
|
||||
pv->tex_x = *tex_coord++;
|
||||
pv->tex_y = *tex_coord++;
|
||||
pv->color.r = *color++;
|
||||
pv->color.g = *color++;
|
||||
pv->color.b = *color++;
|
||||
pv->color.a = *color++;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
{
|
||||
struct vk_draw_triangles call;
|
||||
|
||||
call.pipeline = vk->display.pipelines[
|
||||
to_menu_pipeline(draw->prim_type, draw->pipeline_id)];
|
||||
call.texture = NULL;
|
||||
call.sampler = VK_NULL_HANDLE;
|
||||
call.uniform = draw->backend_data;
|
||||
call.uniform_size = draw->backend_data_size;
|
||||
call.vbo = ⦥
|
||||
call.vertices = draw->coords->vertices;
|
||||
|
||||
vulkan_draw_triangles(vk, &call);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
struct vk_draw_triangles call;
|
||||
unsigned
|
||||
disp_pipeline =
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP) << 1)
|
||||
| (((vk->flags & VK_FLAG_DISPLAY_BLEND) > 0) << 0);
|
||||
call.pipeline = vk->display.pipelines[disp_pipeline];
|
||||
call.texture = texture;
|
||||
call.sampler = (texture->flags & VK_TEX_FLAG_MIPMAP) ?
|
||||
vk->samplers.mipmap_linear :
|
||||
((texture->flags & VK_TEX_FLAG_DEFAULT_SMOOTH) ? vk->samplers.linear
|
||||
: vk->samplers.nearest);
|
||||
call.uniform = draw->matrix_data
|
||||
? draw->matrix_data : &vk->mvp_no_rot;
|
||||
call.uniform_size = sizeof(math_matrix_4x4);
|
||||
call.vbo = ⦥
|
||||
call.vertices = draw->coords->vertices;
|
||||
|
||||
vulkan_draw_triangles(vk, &call);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_vk_blend_begin(void *data)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (vk)
|
||||
vk->flags |= VK_FLAG_DISPLAY_BLEND;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_blend_end(void *data)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (vk)
|
||||
vk->flags &= ~VK_FLAG_DISPLAY_BLEND;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
vk->tracker.scissor.offset.x = x;
|
||||
vk->tracker.scissor.offset.y = y;
|
||||
vk->tracker.scissor.extent.width = width;
|
||||
vk->tracker.scissor.extent.height = height;
|
||||
vk->flags |= VK_FLAG_TRACKER_USE_SCISSOR;
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
vk->flags &= ~VK_FLAG_TRACKER_USE_SCISSOR;
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_vulkan = {
|
||||
gfx_display_vk_draw,
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
gfx_display_vk_draw_pipeline,
|
||||
#else
|
||||
NULL, /* draw_pipeline */
|
||||
#endif
|
||||
gfx_display_vk_blend_begin,
|
||||
gfx_display_vk_blend_end,
|
||||
gfx_display_vk_get_default_mvp,
|
||||
gfx_display_vk_get_default_vertices,
|
||||
gfx_display_vk_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_VULKAN_API,
|
||||
GFX_VIDEO_DRIVER_VULKAN,
|
||||
"vulkan",
|
||||
false,
|
||||
gfx_display_vk_scissor_begin,
|
||||
gfx_display_vk_scissor_end
|
||||
};
|
||||
|
||||
/**
|
||||
* FONT DRIVER
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vk_t *vk;
|
||||
|
@ -1,149 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/ctr_defines.h"
|
||||
#include "../drivers/ctr_gu.h"
|
||||
#include "../../ctr/gpu_old.h"
|
||||
|
||||
static void gfx_display_ctr_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
ctr_scale_vector_t scale_vector;
|
||||
int colorR, colorG, colorB, colorA;
|
||||
ctr_scale_vector_t *vec = NULL;
|
||||
ctr_vertex_t *v = NULL;
|
||||
struct ctr_texture *texture = NULL;
|
||||
const float *color = NULL;
|
||||
ctr_video_t *ctr = (ctr_video_t*)data;
|
||||
|
||||
if (!ctr || !draw)
|
||||
return;
|
||||
|
||||
texture = (struct ctr_texture*)draw->texture;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!texture)
|
||||
return;
|
||||
|
||||
vec = &scale_vector;
|
||||
CTR_SET_SCALE_VECTOR(
|
||||
vec,
|
||||
CTR_TOP_FRAMEBUFFER_WIDTH,
|
||||
CTR_TOP_FRAMEBUFFER_HEIGHT,
|
||||
texture->width,
|
||||
texture->height);
|
||||
GPUCMD_AddWrite(GPUREG_GSH_BOOLUNIFORM, 0);
|
||||
ctrGuSetVertexShaderFloatUniform(0, (float*)&scale_vector, 1);
|
||||
|
||||
if ((ctr->vertex_cache.size - (ctr->vertex_cache.current
|
||||
- ctr->vertex_cache.buffer)) < 1)
|
||||
ctr->vertex_cache.current = ctr->vertex_cache.buffer;
|
||||
|
||||
v = ctr->vertex_cache.current++;
|
||||
|
||||
v->x0 = draw->x;
|
||||
v->y0 = 240 - draw->height - draw->y;
|
||||
v->x1 = v->x0 + draw->width;
|
||||
v->y1 = v->y0 + draw->height;
|
||||
v->u0 = 0;
|
||||
v->v0 = 0;
|
||||
v->u1 = texture->active_width;
|
||||
v->v1 = texture->active_height;
|
||||
|
||||
ctrGuSetAttributeBuffers(2,
|
||||
VIRT_TO_PHYS(v),
|
||||
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 |
|
||||
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 4,
|
||||
sizeof(ctr_vertex_t));
|
||||
|
||||
color = draw->coords->color;
|
||||
colorR = (int)((*color++)*255.f);
|
||||
colorG = (int)((*color++)*255.f);
|
||||
colorB = (int)((*color++)*255.f);
|
||||
colorA = (int)((*color++)*255.f);
|
||||
|
||||
GPU_SetTexEnv(0,
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
|
||||
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
|
||||
0,
|
||||
0,
|
||||
GPU_MODULATE, GPU_MODULATE,
|
||||
COLOR_ABGR(colorR,colorG,colorB,colorA)
|
||||
);
|
||||
|
||||
#if 0
|
||||
GPU_SetTexEnv(0,
|
||||
GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, 0),
|
||||
GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, 0),
|
||||
0,
|
||||
GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR, 0),
|
||||
GPU_REPLACE, GPU_REPLACE,
|
||||
0x3FFFFFFF);
|
||||
#endif
|
||||
|
||||
ctrGuSetTexture(GPU_TEXUNIT0,
|
||||
VIRT_TO_PHYS(texture->data),
|
||||
texture->width,
|
||||
texture->height,
|
||||
GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)
|
||||
| GPU_TEXTURE_MIN_FILTER(GPU_LINEAR)
|
||||
| GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE)
|
||||
| GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
|
||||
GPU_RGBA8);
|
||||
|
||||
GPU_SetViewport(NULL,
|
||||
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
|
||||
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
|
||||
ctr->video_mode == CTR_VIDEO_MODE_2D_800X240
|
||||
? CTR_TOP_FRAMEBUFFER_WIDTH * 2
|
||||
: CTR_TOP_FRAMEBUFFER_WIDTH);
|
||||
|
||||
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
|
||||
|
||||
if (ctr->video_mode == CTR_VIDEO_MODE_3D)
|
||||
{
|
||||
GPU_SetViewport(NULL,
|
||||
VIRT_TO_PHYS(ctr->drawbuffers.top.right),
|
||||
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
|
||||
CTR_TOP_FRAMEBUFFER_WIDTH);
|
||||
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
|
||||
}
|
||||
|
||||
GPU_SetTexEnv(0, GPU_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_ctr = {
|
||||
gfx_display_ctr_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_CTR,
|
||||
GFX_VIDEO_DRIVER_CTR,
|
||||
"ctr",
|
||||
true,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
@ -1,298 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2018 - Daniel De Matteis
|
||||
* Copyright (C) 2014-2018 - Ali Bouhlel
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/d3d10_common.h"
|
||||
|
||||
static void gfx_display_d3d10_blend_begin(void *data)
|
||||
{
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_enable,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d10_blend_end(void *data)
|
||||
{
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_disable,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d10_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
UINT offset = 0, stride = 0;
|
||||
int vertex_count = 1;
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10 || !draw || !draw->texture)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
d3d10_set_shader(d3d10->device, &d3d10->shaders[draw->pipeline_id]);
|
||||
d3d10->device->lpVtbl->Draw(d3d10->device, draw->coords->vertices, 0);
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_enable,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
d3d10_set_shader(d3d10->device, &d3d10->sprites.shader);
|
||||
stride = sizeof(d3d10_sprite_t);
|
||||
d3d10->device->lpVtbl->IASetVertexBuffers(
|
||||
d3d10->device, 0, 1, (D3D10Buffer* const)&d3d10->sprites.vbo, &stride, &offset);
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color)
|
||||
vertex_count = draw->coords->vertices;
|
||||
|
||||
if ( (!(d3d10->flags & D3D10_ST_FLAG_SPRITES_ENABLE))
|
||||
|| (vertex_count > d3d10->sprites.capacity))
|
||||
return;
|
||||
|
||||
if (d3d10->sprites.offset + vertex_count > d3d10->sprites.capacity)
|
||||
d3d10->sprites.offset = 0;
|
||||
|
||||
{
|
||||
void* mapped_vbo = NULL;
|
||||
d3d10_sprite_t* sprite = NULL;
|
||||
|
||||
d3d10->sprites.vbo->lpVtbl->Map(d3d10->sprites.vbo,
|
||||
D3D10_MAP_WRITE_NO_OVERWRITE, 0,
|
||||
(void**)&mapped_vbo);
|
||||
|
||||
sprite = (d3d10_sprite_t*)mapped_vbo + d3d10->sprites.offset;
|
||||
|
||||
if (vertex_count == 1)
|
||||
{
|
||||
sprite->pos.x = draw->x / (float)d3d10->viewport.Width;
|
||||
sprite->pos.y =
|
||||
(d3d10->viewport.Height - draw->y - draw->height)
|
||||
/ (float)d3d10->viewport.Height;
|
||||
sprite->pos.w = draw->width / (float)d3d10->viewport.Width;
|
||||
sprite->pos.h = draw->height / (float)d3d10->viewport.Height;
|
||||
|
||||
sprite->coords.u = 0.0f;
|
||||
sprite->coords.v = 0.0f;
|
||||
sprite->coords.w = 1.0f;
|
||||
sprite->coords.h = 1.0f;
|
||||
|
||||
if (draw->scale_factor)
|
||||
sprite->params.scaling = draw->scale_factor;
|
||||
else
|
||||
sprite->params.scaling = 1.0f;
|
||||
|
||||
sprite->params.rotation = draw->rotation;
|
||||
|
||||
sprite->colors[3] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
sprite->colors[2] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5],
|
||||
0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]);
|
||||
sprite->colors[1] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
|
||||
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]);
|
||||
sprite->colors[0] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
|
||||
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const float* vertex = draw->coords->vertex;
|
||||
const float* tex_coord = draw->coords->tex_coord;
|
||||
const float* color = draw->coords->color;
|
||||
|
||||
for (i = 0; i < vertex_count; i++)
|
||||
{
|
||||
d3d10_vertex_t* v = (d3d10_vertex_t*)sprite;
|
||||
v->position[0] = *vertex++;
|
||||
v->position[1] = *vertex++;
|
||||
v->texcoord[0] = *tex_coord++;
|
||||
v->texcoord[1] = *tex_coord++;
|
||||
v->color[0] = *color++;
|
||||
v->color[1] = *color++;
|
||||
v->color[2] = *color++;
|
||||
v->color[3] = *color++;
|
||||
|
||||
sprite++;
|
||||
}
|
||||
|
||||
d3d10_set_shader(d3d10->device,
|
||||
&d3d10->shaders[VIDEO_SHADER_STOCK_BLEND]);
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
d3d10->sprites.vbo->lpVtbl->Unmap(d3d10->sprites.vbo);
|
||||
}
|
||||
|
||||
d3d10_set_texture_and_sampler(d3d10->device, 0,
|
||||
(d3d10_texture_t*)draw->texture);
|
||||
d3d10->device->lpVtbl->Draw(d3d10->device, vertex_count,
|
||||
d3d10->sprites.offset);
|
||||
d3d10->sprites.offset += vertex_count;
|
||||
|
||||
if (vertex_count > 1)
|
||||
{
|
||||
d3d10_set_shader(d3d10->device, &d3d10->sprites.shader);
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_d3d10_draw_pipeline(gfx_display_ctx_draw_t* draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
UINT stride = 0, offset = 0;
|
||||
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10 || !draw)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
{
|
||||
video_coord_array_t* ca = &p_disp->dispca;
|
||||
|
||||
if (!d3d10->menu_pipeline_vbo)
|
||||
{
|
||||
D3D10_BUFFER_DESC desc;
|
||||
D3D10_SUBRESOURCE_DATA vertex_data;
|
||||
|
||||
desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float);
|
||||
desc.Usage = D3D10_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
vertex_data.pSysMem = ca->coords.vertex;
|
||||
vertex_data.SysMemPitch = 0;
|
||||
vertex_data.SysMemSlicePitch = 0;
|
||||
d3d10->device->lpVtbl->CreateBuffer(d3d10->device, &desc,
|
||||
&vertex_data, &d3d10->menu_pipeline_vbo);
|
||||
}
|
||||
stride = 2 * sizeof(float);
|
||||
d3d10->device->lpVtbl->IASetVertexBuffers(
|
||||
d3d10->device, 0, 1, (D3D10Buffer* const)&d3d10->menu_pipeline_vbo, &stride, &offset);
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
d3d10->device->lpVtbl->OMSetBlendState(d3d10->device,
|
||||
d3d10->blend_pipeline,
|
||||
NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
stride = sizeof(d3d10_vertex_t);
|
||||
d3d10->device->lpVtbl->IASetVertexBuffers(
|
||||
d3d10->device, 0, 1, (D3D10Buffer* const)&d3d10->frame.vbo, &stride, &offset);
|
||||
draw->coords->vertices = 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
d3d10->device->lpVtbl->IASetPrimitiveTopology(d3d10->device,
|
||||
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
d3d10->ubo_values.time += 0.01f;
|
||||
|
||||
{
|
||||
void *mapped_ubo = NULL;
|
||||
d3d10->ubo->lpVtbl->Map(d3d10->ubo, D3D10_MAP_WRITE_DISCARD, 0,
|
||||
(void**)&mapped_ubo);
|
||||
*(d3d10_uniform_t*)mapped_ubo = d3d10->ubo_values;
|
||||
d3d10->ubo->lpVtbl->Unmap(d3d10->ubo);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d10_scissor_begin(void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
D3D10_RECT rect;
|
||||
d3d10_video_t *d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
d3d10->device->lpVtbl->RSSetScissorRects(d3d10->device, 1, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d10_scissor_end(void *data,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
D3D10_RECT rect;
|
||||
d3d10_video_t *d3d10 = (d3d10_video_t*)data;
|
||||
|
||||
if (!d3d10)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
d3d10->device->lpVtbl->RSSetScissorRects(d3d10->device, 1, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d10 = {
|
||||
gfx_display_d3d10_draw,
|
||||
gfx_display_d3d10_draw_pipeline,
|
||||
gfx_display_d3d10_blend_begin,
|
||||
gfx_display_d3d10_blend_end,
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_D3D10_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D10,
|
||||
"d3d10",
|
||||
true,
|
||||
gfx_display_d3d10_scissor_begin,
|
||||
gfx_display_d3d10_scissor_end
|
||||
};
|
@ -1,330 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2018 - Ali Bouhlel
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/d3d11_common.h"
|
||||
|
||||
static void gfx_display_d3d11_blend_begin(void *data)
|
||||
{
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d11_blend_end(void *data)
|
||||
{
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d11_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
int vertex_count = 1;
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11 || !draw || !draw->texture)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->shaders[draw->pipeline_id];
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->Draw(d3d11->context, draw->coords->vertices, 0);
|
||||
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->sprites.shader;
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
}
|
||||
{
|
||||
UINT stride = sizeof(d3d11_sprite_t);
|
||||
UINT offset = 0;
|
||||
d3d11->context->lpVtbl->IASetVertexBuffers(
|
||||
d3d11->context, 0, 1,
|
||||
&d3d11->sprites.vbo, &stride, &offset);
|
||||
}
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
return;
|
||||
}
|
||||
|
||||
if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color)
|
||||
vertex_count = draw->coords->vertices;
|
||||
|
||||
if ( (!(d3d11->flags & D3D11_ST_FLAG_SPRITES_ENABLE))
|
||||
|| (vertex_count > d3d11->sprites.capacity))
|
||||
return;
|
||||
|
||||
if (d3d11->sprites.offset + vertex_count > d3d11->sprites.capacity)
|
||||
d3d11->sprites.offset = 0;
|
||||
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_vbo;
|
||||
d3d11_sprite_t* sprite = NULL;
|
||||
|
||||
d3d11->context->lpVtbl->Map(
|
||||
d3d11->context, (D3D11Resource)d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo);
|
||||
|
||||
sprite = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset;
|
||||
|
||||
if (vertex_count == 1)
|
||||
{
|
||||
sprite->pos.x = draw->x / (float)d3d11->viewport.Width;
|
||||
sprite->pos.y =
|
||||
(d3d11->viewport.Height - draw->y - draw->height) / (float)d3d11->viewport.Height;
|
||||
sprite->pos.w = draw->width / (float)d3d11->viewport.Width;
|
||||
sprite->pos.h = draw->height / (float)d3d11->viewport.Height;
|
||||
|
||||
sprite->coords.u = 0.0f;
|
||||
sprite->coords.v = 0.0f;
|
||||
sprite->coords.w = 1.0f;
|
||||
sprite->coords.h = 1.0f;
|
||||
|
||||
if (draw->scale_factor)
|
||||
sprite->params.scaling = draw->scale_factor;
|
||||
else
|
||||
sprite->params.scaling = 1.0f;
|
||||
|
||||
sprite->params.rotation = draw->rotation;
|
||||
|
||||
sprite->colors[3] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
sprite->colors[2] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5],
|
||||
0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]);
|
||||
sprite->colors[1] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
|
||||
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]);
|
||||
sprite->colors[0] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
|
||||
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const float* vertex = draw->coords->vertex;
|
||||
const float* tex_coord = draw->coords->tex_coord;
|
||||
const float* color = draw->coords->color;
|
||||
|
||||
for (i = 0; i < vertex_count; i++)
|
||||
{
|
||||
d3d11_vertex_t* v = (d3d11_vertex_t*)sprite;
|
||||
v->position[0] = *vertex++;
|
||||
v->position[1] = *vertex++;
|
||||
v->texcoord[0] = *tex_coord++;
|
||||
v->texcoord[1] = *tex_coord++;
|
||||
v->color[0] = *color++;
|
||||
v->color[1] = *color++;
|
||||
v->color[2] = *color++;
|
||||
v->color[3] = *color++;
|
||||
|
||||
sprite++;
|
||||
}
|
||||
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND];
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
}
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->Unmap(d3d11->context, (D3D11Resource)d3d11->sprites.vbo, 0);
|
||||
}
|
||||
|
||||
{
|
||||
d3d11_texture_t *texture = (d3d11_texture_t*)draw->texture;
|
||||
d3d11->context->lpVtbl->PSSetShaderResources(
|
||||
d3d11->context, 0, 1, &texture->view);
|
||||
d3d11->context->lpVtbl->PSSetSamplers(
|
||||
d3d11->context, 0, 1, (D3D11SamplerState*)&texture->sampler);
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->Draw(d3d11->context, vertex_count,
|
||||
d3d11->sprites.offset);
|
||||
d3d11->sprites.offset += vertex_count;
|
||||
|
||||
if (vertex_count > 1)
|
||||
{
|
||||
d3d11_shader_t *shader = &d3d11->sprites.shader;
|
||||
d3d11->context->lpVtbl->IASetInputLayout(d3d11->context, shader->layout);
|
||||
d3d11->context->lpVtbl->VSSetShader(d3d11->context, shader->vs, NULL, 0);
|
||||
d3d11->context->lpVtbl->PSSetShader(d3d11->context, shader->ps, NULL, 0);
|
||||
d3d11->context->lpVtbl->GSSetShader(d3d11->context, shader->gs, NULL, 0);
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_d3d11_draw_pipeline(gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11 || !draw)
|
||||
return;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
{
|
||||
video_coord_array_t* ca = &p_disp->dispca;
|
||||
|
||||
if (!d3d11->menu_pipeline_vbo)
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float);
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
desc.StructureByteStride = 0;
|
||||
|
||||
{
|
||||
D3D11_SUBRESOURCE_DATA vertex_data;
|
||||
vertex_data.pSysMem = ca->coords.vertex;
|
||||
vertex_data.SysMemPitch = 0;
|
||||
vertex_data.SysMemSlicePitch = 0;
|
||||
d3d11->device->lpVtbl->CreateBuffer(
|
||||
d3d11->device, &desc, &vertex_data,
|
||||
&d3d11->menu_pipeline_vbo);
|
||||
}
|
||||
}
|
||||
{
|
||||
UINT stride = 2 * sizeof(float);
|
||||
UINT offset = 0;
|
||||
d3d11->context->lpVtbl->IASetVertexBuffers(
|
||||
d3d11->context, 0, 1,
|
||||
&d3d11->menu_pipeline_vbo, &stride, &offset);
|
||||
}
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
d3d11->context->lpVtbl->OMSetBlendState(
|
||||
d3d11->context, d3d11->blend_pipeline,
|
||||
NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
{
|
||||
UINT stride = sizeof(d3d11_vertex_t);
|
||||
UINT offset = 0;
|
||||
d3d11->context->lpVtbl->IASetVertexBuffers(
|
||||
d3d11->context, 0, 1,
|
||||
&d3d11->frame.vbo, &stride, &offset);
|
||||
}
|
||||
draw->coords->vertices = 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
d3d11->context->lpVtbl->IASetPrimitiveTopology(
|
||||
d3d11->context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
d3d11->ubo_values.time += 0.01f;
|
||||
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
|
||||
d3d11->context->lpVtbl->Map(
|
||||
d3d11->context, (D3D11Resource)d3d11->ubo,
|
||||
0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
|
||||
*(d3d11_uniform_t*)mapped_ubo.pData = d3d11->ubo_values;
|
||||
d3d11->context->lpVtbl->Unmap(d3d11->context,
|
||||
(D3D11Resource)d3d11->ubo, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d11_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
D3D11_RECT rect;
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
d3d11->context->lpVtbl->RSSetScissorRects(d3d11->context, 1, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d11_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
D3D11_RECT rect;
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
d3d11->context->lpVtbl->RSSetScissorRects(d3d11->context, 1, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d11 = {
|
||||
gfx_display_d3d11_draw,
|
||||
gfx_display_d3d11_draw_pipeline,
|
||||
gfx_display_d3d11_blend_begin,
|
||||
gfx_display_d3d11_blend_end,
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_D3D11_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D11,
|
||||
"d3d11",
|
||||
true,
|
||||
gfx_display_d3d11_scissor_begin,
|
||||
gfx_display_d3d11_scissor_end
|
||||
};
|
@ -1,314 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2018 - Ali Bouhlel
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/d3d12_common.h"
|
||||
|
||||
static void gfx_display_d3d12_blend_begin(void *data)
|
||||
{
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
|
||||
D3D12GraphicsCommandList cmd = d3d12->queue.cmd;
|
||||
d3d12->sprites.pipe = d3d12->sprites.pipe_blend;
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d12_blend_end(void *data)
|
||||
{
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
|
||||
D3D12GraphicsCommandList cmd = d3d12->queue.cmd;
|
||||
d3d12->sprites.pipe = d3d12->sprites.pipe_noblend;
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d12_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
D3D12GraphicsCommandList cmd;
|
||||
int vertex_count = 1;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12 || !draw || !draw->texture)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->pipes[draw->pipeline_id]);
|
||||
cmd->lpVtbl->DrawInstanced(cmd, draw->coords->vertices, 1, 0, 0);
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
cmd->lpVtbl->IASetVertexBuffers(cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||
return;
|
||||
}
|
||||
|
||||
if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color)
|
||||
vertex_count = draw->coords->vertices;
|
||||
|
||||
if ( (!(d3d12->flags & D3D12_ST_FLAG_SPRITES_ENABLE))
|
||||
|| (vertex_count > d3d12->sprites.capacity))
|
||||
return;
|
||||
|
||||
if (d3d12->sprites.offset + vertex_count > d3d12->sprites.capacity)
|
||||
d3d12->sprites.offset = 0;
|
||||
|
||||
{
|
||||
d3d12_sprite_t* sprite;
|
||||
D3D12_RANGE range;
|
||||
range.Begin = 0;
|
||||
range.End = 0;
|
||||
D3D12Map(d3d12->sprites.vbo, 0, &range, (void**)&sprite);
|
||||
sprite += d3d12->sprites.offset;
|
||||
|
||||
if (vertex_count == 1)
|
||||
{
|
||||
|
||||
sprite->pos.x = draw->x / (float)d3d12->chain.viewport.Width;
|
||||
sprite->pos.y =
|
||||
(d3d12->chain.viewport.Height - draw->y - draw->height) /
|
||||
(float)d3d12->chain.viewport.Height;
|
||||
sprite->pos.w = draw->width / (float)d3d12->chain.viewport.Width;
|
||||
sprite->pos.h = draw->height / (float)d3d12->chain.viewport.Height;
|
||||
|
||||
sprite->coords.u = 0.0f;
|
||||
sprite->coords.v = 0.0f;
|
||||
sprite->coords.w = 1.0f;
|
||||
sprite->coords.h = 1.0f;
|
||||
|
||||
if (draw->scale_factor)
|
||||
sprite->params.scaling = draw->scale_factor;
|
||||
else
|
||||
sprite->params.scaling = 1.0f;
|
||||
|
||||
sprite->params.rotation = draw->rotation;
|
||||
|
||||
sprite->colors[3] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
sprite->colors[2] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5],
|
||||
0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]);
|
||||
sprite->colors[1] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
|
||||
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]);
|
||||
sprite->colors[0] = DXGI_COLOR_RGBA(
|
||||
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
|
||||
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
const float* vertex = draw->coords->vertex;
|
||||
const float* tex_coord = draw->coords->tex_coord;
|
||||
const float* color = draw->coords->color;
|
||||
|
||||
for (i = 0; i < vertex_count; i++)
|
||||
{
|
||||
d3d12_vertex_t* v = (d3d12_vertex_t*)sprite;
|
||||
v->position[0] = *vertex++;
|
||||
v->position[1] = *vertex++;
|
||||
v->texcoord[0] = *tex_coord++;
|
||||
v->texcoord[1] = *tex_coord++;
|
||||
v->color[0] = *color++;
|
||||
v->color[1] = *color++;
|
||||
v->color[2] = *color++;
|
||||
v->color[3] = *color++;
|
||||
|
||||
sprite++;
|
||||
}
|
||||
cmd->lpVtbl->SetPipelineState(cmd,
|
||||
(D3D12PipelineState)d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd,
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
range.Begin = d3d12->sprites.offset * sizeof(*sprite);
|
||||
range.End = (d3d12->sprites.offset + vertex_count) * sizeof(*sprite);
|
||||
D3D12Unmap(d3d12->sprites.vbo, 0, &range);
|
||||
}
|
||||
|
||||
{
|
||||
d3d12_texture_t* texture = (d3d12_texture_t*)draw->texture;
|
||||
if (texture->dirty)
|
||||
{
|
||||
d3d12_upload_texture(cmd, texture, d3d12);
|
||||
|
||||
if (vertex_count > 1)
|
||||
cmd->lpVtbl->SetPipelineState(cmd,
|
||||
(D3D12PipelineState)d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
else
|
||||
cmd->lpVtbl->SetPipelineState(cmd,
|
||||
(D3D12PipelineState)d3d12->sprites.pipe);
|
||||
}
|
||||
cmd->lpVtbl->SetGraphicsRootDescriptorTable(cmd, ROOT_ID_TEXTURE_T, texture->gpu_descriptor[0]);
|
||||
cmd->lpVtbl->SetGraphicsRootDescriptorTable(cmd, ROOT_ID_SAMPLER_T, texture->sampler);
|
||||
}
|
||||
|
||||
cmd->lpVtbl->DrawInstanced(cmd, vertex_count, 1, d3d12->sprites.offset, 0);
|
||||
d3d12->sprites.offset += vertex_count;
|
||||
|
||||
if (vertex_count > 1)
|
||||
{
|
||||
cmd->lpVtbl->SetPipelineState(cmd, (D3D12PipelineState)d3d12->sprites.pipe);
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_d3d12_draw_pipeline(gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
D3D12GraphicsCommandList cmd;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12 || !draw)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
{
|
||||
video_coord_array_t* ca = &p_disp->dispca;
|
||||
|
||||
if (!d3d12->menu_pipeline_vbo)
|
||||
{
|
||||
D3D12_RANGE read_range;
|
||||
void* vertex_data_begin;
|
||||
|
||||
d3d12->menu_pipeline_vbo_view.StrideInBytes = 2 * sizeof(float);
|
||||
d3d12->menu_pipeline_vbo_view.SizeInBytes =
|
||||
ca->coords.vertices * d3d12->menu_pipeline_vbo_view.StrideInBytes;
|
||||
d3d12->menu_pipeline_vbo_view.BufferLocation = d3d12_create_buffer(
|
||||
d3d12->device, d3d12->menu_pipeline_vbo_view.SizeInBytes,
|
||||
&d3d12->menu_pipeline_vbo);
|
||||
|
||||
read_range.Begin = 0;
|
||||
read_range.End = 0;
|
||||
D3D12Map(d3d12->menu_pipeline_vbo, 0,
|
||||
&read_range, &vertex_data_begin);
|
||||
memcpy(vertex_data_begin, ca->coords.vertex,
|
||||
d3d12->menu_pipeline_vbo_view.SizeInBytes);
|
||||
D3D12Unmap(d3d12->menu_pipeline_vbo, 0, NULL);
|
||||
}
|
||||
cmd->lpVtbl->IASetVertexBuffers(cmd, 0, 1,
|
||||
&d3d12->menu_pipeline_vbo_view);
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
cmd->lpVtbl->IASetVertexBuffers(cmd, 0, 1, &d3d12->frame.vbo_view);
|
||||
draw->coords->vertices = 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
cmd->lpVtbl->IASetPrimitiveTopology(cmd,
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
d3d12->ubo_values.time += 0.01f;
|
||||
|
||||
{
|
||||
D3D12_RANGE read_range;
|
||||
d3d12_uniform_t* mapped_ubo;
|
||||
|
||||
read_range.Begin = 0;
|
||||
read_range.End = 0;
|
||||
D3D12Map(d3d12->ubo, 0, &read_range, (void**)&mapped_ubo);
|
||||
*mapped_ubo = d3d12->ubo_values;
|
||||
D3D12Unmap(d3d12->ubo, 0, NULL);
|
||||
}
|
||||
cmd->lpVtbl->SetGraphicsRootConstantBufferView(cmd, ROOT_ID_UBO,
|
||||
d3d12->ubo_view.BufferLocation);
|
||||
}
|
||||
|
||||
void gfx_display_d3d12_scissor_begin(void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
D3D12_RECT rect;
|
||||
D3D12GraphicsCommandList cmd;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
cmd->lpVtbl->RSSetScissorRects(cmd, 1, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d12_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
D3D12_RECT rect;
|
||||
D3D12GraphicsCommandList cmd;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
if (!d3d12)
|
||||
return;
|
||||
|
||||
cmd = d3d12->queue.cmd;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
cmd->lpVtbl->RSSetScissorRects(cmd, 1, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d12 = {
|
||||
gfx_display_d3d12_draw,
|
||||
gfx_display_d3d12_draw_pipeline,
|
||||
gfx_display_d3d12_blend_begin,
|
||||
gfx_display_d3d12_blend_end,
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_D3D12_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D12,
|
||||
"d3d12",
|
||||
true,
|
||||
gfx_display_d3d12_scissor_begin,
|
||||
gfx_display_d3d12_scissor_end
|
||||
};
|
@ -1,250 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/d3d_common.h"
|
||||
#include "../common/d3d8_common.h"
|
||||
|
||||
static const float d3d8_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float d3d8_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_d3d8_get_default_vertices(void)
|
||||
{
|
||||
return &d3d8_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_d3d8_get_default_tex_coords(void)
|
||||
{
|
||||
return &d3d8_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_d3d8_get_default_mvp(void *data)
|
||||
{
|
||||
static float id[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
return &id;
|
||||
}
|
||||
|
||||
static INT32 gfx_display_prim_to_d3d8_enum(
|
||||
enum gfx_display_prim_type prim_type)
|
||||
{
|
||||
switch (prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return D3DPT_COMM_TRIANGLESTRIP;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - hack */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d8_blend_begin(void *data)
|
||||
{
|
||||
d3d8_video_t *d3d = (d3d8_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, true);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d8_blend_end(void *data)
|
||||
{
|
||||
d3d8_video_t *d3d = (d3d8_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice8_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d8_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
static float default_mvp[] ={ 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
unsigned i;
|
||||
math_matrix_4x4 mop, m1, m2;
|
||||
LPDIRECT3DVERTEXBUFFER8 vbo;
|
||||
LPDIRECT3DDEVICE8 dev;
|
||||
D3DPRIMITIVETYPE type;
|
||||
unsigned start = 0;
|
||||
unsigned count = 0;
|
||||
d3d8_video_t *d3d = (d3d8_video_t*)data;
|
||||
Vertex * pv = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
|
||||
if (!d3d || !draw || draw->pipeline_id)
|
||||
return;
|
||||
if ((d3d->menu_display.offset + draw->coords->vertices )
|
||||
> (unsigned)d3d->menu_display.size)
|
||||
return;
|
||||
vbo = (LPDIRECT3DVERTEXBUFFER8)d3d->menu_display.buffer;
|
||||
dev = d3d->dev;
|
||||
pv = (Vertex*)d3d8_vertex_buffer_lock(vbo);
|
||||
|
||||
if (!pv)
|
||||
return;
|
||||
|
||||
pv += d3d->menu_display.offset;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &d3d8_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &d3d8_tex_coords[0];
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
int colors[4];
|
||||
|
||||
colors[0] = *color++ * 0xFF;
|
||||
colors[1] = *color++ * 0xFF;
|
||||
colors[2] = *color++ * 0xFF;
|
||||
colors[3] = *color++ * 0xFF;
|
||||
|
||||
pv[i].x = *vertex++;
|
||||
pv[i].y = *vertex++;
|
||||
pv[i].z = 0.5f;
|
||||
pv[i].u = *tex_coord++;
|
||||
pv[i].v = *tex_coord++;
|
||||
|
||||
if ((void*)draw->texture)
|
||||
{
|
||||
D3DSURFACE_DESC desc;
|
||||
LPDIRECT3DTEXTURE8 tex = (LPDIRECT3DTEXTURE8)draw->texture;
|
||||
if (SUCCEEDED(IDirect3DTexture8_GetLevelDesc(tex,
|
||||
0, (D3DSURFACE_DESC*)&desc)))
|
||||
{
|
||||
pv[i].u *= desc.Width;
|
||||
pv[i].v *= desc.Height;
|
||||
}
|
||||
}
|
||||
|
||||
pv[i].color =
|
||||
D3DCOLOR_ARGB(
|
||||
colors[3], /* A */
|
||||
colors[0], /* R */
|
||||
colors[1], /* G */
|
||||
colors[2] /* B */
|
||||
);
|
||||
}
|
||||
IDirect3DVertexBuffer8_Unlock(vbo);
|
||||
|
||||
if (!draw->matrix_data)
|
||||
draw->matrix_data = &default_mvp;
|
||||
|
||||
/* ugh */
|
||||
matrix_4x4_scale(m1, 2.0, 2.0, 0);
|
||||
matrix_4x4_translate(mop, -1.0, -1.0, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_multiply(m1,
|
||||
*((math_matrix_4x4*)draw->matrix_data), m2);
|
||||
matrix_4x4_scale(mop,
|
||||
(draw->width / 2.0) / video_width,
|
||||
(draw->height / 2.0) / video_height, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_translate(mop,
|
||||
(draw->x + (draw->width / 2.0)) / video_width,
|
||||
(draw->y + (draw->height / 2.0)) / video_height,
|
||||
0);
|
||||
matrix_4x4_multiply(m1, mop, m2);
|
||||
matrix_4x4_multiply(m2, d3d->mvp_transposed, m1);
|
||||
d3d_matrix_transpose(&m1, &m2);
|
||||
|
||||
d3d8_set_mvp(dev, &m1);
|
||||
|
||||
if (draw->texture)
|
||||
{
|
||||
IDirect3DDevice8_SetTexture(dev, 0,
|
||||
(IDirect3DBaseTexture8*)draw->texture);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice8_SetTextureStageState(dev, 0,
|
||||
(D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, D3DTEXF_COMM_LINEAR);
|
||||
}
|
||||
|
||||
type = gfx_display_prim_to_d3d8_enum(draw->prim_type);
|
||||
start = d3d->menu_display.offset;
|
||||
count = draw->coords->vertices -
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP)
|
||||
? 2 : 0);
|
||||
|
||||
IDirect3DDevice8_BeginScene(dev);
|
||||
IDirect3DDevice8_DrawPrimitive(dev, type, start, count);
|
||||
IDirect3DDevice8_EndScene(dev);
|
||||
|
||||
d3d->menu_display.offset += draw->coords->vertices;
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d8 = {
|
||||
gfx_display_d3d8_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
gfx_display_d3d8_blend_begin,
|
||||
gfx_display_d3d8_blend_end,
|
||||
gfx_display_d3d8_get_default_mvp,
|
||||
gfx_display_d3d8_get_default_vertices,
|
||||
gfx_display_d3d8_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_D3D8_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D8,
|
||||
"d3d8",
|
||||
false,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
@ -1,316 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/d3d_common.h"
|
||||
#include "../common/d3d9_common.h"
|
||||
|
||||
static const float d3d9_cg_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float d3d9_cg_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_d3d9_cg_get_default_vertices(void)
|
||||
{
|
||||
return &d3d9_cg_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_d3d9_cg_get_default_tex_coords(void)
|
||||
{
|
||||
return &d3d9_cg_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_d3d9_cg_get_default_mvp(void *data)
|
||||
{
|
||||
static float id[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
return &id;
|
||||
}
|
||||
|
||||
static INT32 gfx_display_prim_to_d3d9_cg_enum(
|
||||
enum gfx_display_prim_type prim_type)
|
||||
{
|
||||
switch (prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return D3DPT_COMM_TRIANGLESTRIP;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - hack */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_blend_begin(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, true);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_blend_end(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
math_matrix_4x4 mop, m1, m2;
|
||||
LPDIRECT3DDEVICE9 dev;
|
||||
D3DPRIMITIVETYPE type;
|
||||
unsigned start = 0;
|
||||
unsigned count = 0;
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
Vertex * pv = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
|
||||
if (!d3d || !draw || draw->pipeline_id)
|
||||
return;
|
||||
|
||||
dev = d3d->dev;
|
||||
|
||||
if ((d3d->menu_display.offset + draw->coords->vertices )
|
||||
> (unsigned)d3d->menu_display.size)
|
||||
return;
|
||||
|
||||
IDirect3DVertexBuffer9_Lock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer, 0, 0, (void**)&pv, 0);
|
||||
if (!pv)
|
||||
return;
|
||||
|
||||
pv += d3d->menu_display.offset;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &d3d9_cg_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &d3d9_cg_tex_coords[0];
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
int colors[4];
|
||||
|
||||
colors[0] = *color++ * 0xFF;
|
||||
colors[1] = *color++ * 0xFF;
|
||||
colors[2] = *color++ * 0xFF;
|
||||
colors[3] = *color++ * 0xFF;
|
||||
|
||||
pv[i].x = *vertex++;
|
||||
pv[i].y = *vertex++;
|
||||
pv[i].z = 0.5f;
|
||||
pv[i].u = *tex_coord++;
|
||||
pv[i].v = *tex_coord++;
|
||||
|
||||
pv[i].color =
|
||||
D3DCOLOR_ARGB(
|
||||
colors[3], /* A */
|
||||
colors[0], /* R */
|
||||
colors[1], /* G */
|
||||
colors[2] /* B */
|
||||
);
|
||||
}
|
||||
IDirect3DVertexBuffer9_Unlock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer);
|
||||
|
||||
if (!draw->matrix_data)
|
||||
draw->matrix_data = gfx_display_d3d9_cg_get_default_mvp(d3d);
|
||||
|
||||
/* ugh */
|
||||
matrix_4x4_scale(m1, 2.0, 2.0, 0);
|
||||
matrix_4x4_translate(mop, -1.0, -1.0, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_multiply(m1,
|
||||
*((math_matrix_4x4*)draw->matrix_data), m2);
|
||||
matrix_4x4_scale(mop,
|
||||
(draw->width / 2.0) / video_width,
|
||||
(draw->height / 2.0) / video_height, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_translate(mop,
|
||||
(draw->x + (draw->width / 2.0)) / video_width,
|
||||
(draw->y + (draw->height / 2.0)) / video_height,
|
||||
0);
|
||||
matrix_4x4_multiply(m1, mop, m2);
|
||||
matrix_4x4_multiply(m2, d3d->mvp_transposed, m1);
|
||||
d3d_matrix_transpose(&m1, &m2);
|
||||
|
||||
IDirect3DDevice9_SetVertexShaderConstantF(dev,
|
||||
0, (const float*)&m1, 4);
|
||||
|
||||
if (draw->texture)
|
||||
{
|
||||
IDirect3DDevice9_SetTexture(dev, 0,
|
||||
(IDirect3DBaseTexture9*)draw->texture);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSU, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSV, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MINFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MAGFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev, 0,
|
||||
D3DSAMP_MIPFILTER, D3DTEXF_COMM_LINEAR);
|
||||
}
|
||||
|
||||
type = (D3DPRIMITIVETYPE)gfx_display_prim_to_d3d9_cg_enum(draw->prim_type);
|
||||
start = d3d->menu_display.offset;
|
||||
count = draw->coords->vertices -
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP)
|
||||
? 2 : 0);
|
||||
|
||||
IDirect3DDevice9_BeginScene(dev);
|
||||
IDirect3DDevice9_DrawPrimitive(dev, type, start, count);
|
||||
IDirect3DDevice9_EndScene(dev);
|
||||
|
||||
d3d->menu_display.offset += draw->coords->vertices;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_cg_draw_pipeline(gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
static float t = 0;
|
||||
video_coord_array_t *ca = NULL;
|
||||
|
||||
if (!draw)
|
||||
return;
|
||||
|
||||
ca = &p_disp->dispca;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->coords = NULL;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
if (ca)
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
{
|
||||
struct uniform_info uniform_param = {0};
|
||||
t += 0.01;
|
||||
|
||||
(void)uniform_param;
|
||||
|
||||
uniform_param.enabled = true;
|
||||
uniform_param.lookup.enable = true;
|
||||
uniform_param.lookup.add_prefix = true;
|
||||
uniform_param.lookup.idx = draw->pipeline_id;
|
||||
uniform_param.lookup.type = SHADER_PROGRAM_VERTEX;
|
||||
uniform_param.type = UNIFORM_1F;
|
||||
uniform_param.lookup.ident = "time";
|
||||
uniform_param.result.f.v0 = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_cg_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_cg_scissor_end(void *data,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d9_cg = {
|
||||
gfx_display_d3d9_cg_draw,
|
||||
gfx_display_d3d9_cg_draw_pipeline,
|
||||
gfx_display_d3d9_cg_blend_begin,
|
||||
gfx_display_d3d9_cg_blend_end,
|
||||
gfx_display_d3d9_cg_get_default_mvp,
|
||||
gfx_display_d3d9_cg_get_default_vertices,
|
||||
gfx_display_d3d9_cg_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_D3D9_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D9_CG,
|
||||
"d3d9_cg",
|
||||
false,
|
||||
gfx_display_d3d9_cg_scissor_begin,
|
||||
gfx_display_d3d9_cg_scissor_end
|
||||
};
|
@ -1,321 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/d3d_common.h"
|
||||
#include "../common/d3d9_common.h"
|
||||
|
||||
static const float d3d9_hlsl_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float d3d9_hlsl_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_d3d9_hlsl_get_default_vertices(void)
|
||||
{
|
||||
return &d3d9_hlsl_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_d3d9_hlsl_get_default_tex_coords(void)
|
||||
{
|
||||
return &d3d9_hlsl_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_d3d9_hlsl_get_default_mvp(void *data)
|
||||
{
|
||||
static float id[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
return &id;
|
||||
}
|
||||
|
||||
static INT32 gfx_display_prim_to_d3d9_hlsl_enum(
|
||||
enum gfx_display_prim_type prim_type)
|
||||
{
|
||||
switch (prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return D3DPT_COMM_TRIANGLESTRIP;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - hack */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_blend_begin(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d)
|
||||
return;
|
||||
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, true);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_blend_end(void *data)
|
||||
{
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
|
||||
if (d3d)
|
||||
IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_bind_texture(gfx_display_ctx_draw_t *draw,
|
||||
d3d9_video_t *d3d)
|
||||
{
|
||||
LPDIRECT3DDEVICE9 dev = d3d->dev;
|
||||
|
||||
IDirect3DDevice9_SetTexture(dev, 0,
|
||||
(IDirect3DBaseTexture9*)draw->texture);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSU, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_ADDRESSV, D3DTADDRESS_COMM_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MINFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev,
|
||||
0, D3DSAMP_MAGFILTER, D3DTEXF_COMM_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(dev, 0,
|
||||
D3DSAMP_MIPFILTER, D3DTEXF_COMM_LINEAR);
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
math_matrix_4x4 mop, m1, m2;
|
||||
LPDIRECT3DDEVICE9 dev;
|
||||
D3DPRIMITIVETYPE type;
|
||||
unsigned start = 0;
|
||||
unsigned count = 0;
|
||||
d3d9_video_t *d3d = (d3d9_video_t*)data;
|
||||
Vertex * pv = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
|
||||
if (!d3d || !draw || draw->pipeline_id)
|
||||
return;
|
||||
|
||||
dev = d3d->dev;
|
||||
|
||||
if ((d3d->menu_display.offset + draw->coords->vertices )
|
||||
> (unsigned)d3d->menu_display.size)
|
||||
return;
|
||||
|
||||
IDirect3DVertexBuffer9_Lock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer, 0, 0, (void**)&pv, 0);
|
||||
if (!pv)
|
||||
return;
|
||||
|
||||
pv += d3d->menu_display.offset;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &d3d9_hlsl_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &d3d9_hlsl_tex_coords[0];
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
int colors[4];
|
||||
|
||||
colors[0] = *color++ * 0xFF;
|
||||
colors[1] = *color++ * 0xFF;
|
||||
colors[2] = *color++ * 0xFF;
|
||||
colors[3] = *color++ * 0xFF;
|
||||
|
||||
pv[i].x = *vertex++;
|
||||
pv[i].y = *vertex++;
|
||||
pv[i].z = 0.5f;
|
||||
pv[i].u = *tex_coord++;
|
||||
pv[i].v = *tex_coord++;
|
||||
|
||||
pv[i].color =
|
||||
D3DCOLOR_ARGB(
|
||||
colors[3], /* A */
|
||||
colors[0], /* R */
|
||||
colors[1], /* G */
|
||||
colors[2] /* B */
|
||||
);
|
||||
}
|
||||
IDirect3DVertexBuffer9_Unlock((LPDIRECT3DVERTEXBUFFER9)
|
||||
d3d->menu_display.buffer);
|
||||
|
||||
if (!draw->matrix_data)
|
||||
draw->matrix_data = gfx_display_d3d9_hlsl_get_default_mvp(d3d);
|
||||
|
||||
/* ugh */
|
||||
matrix_4x4_scale(m1, 2.0, 2.0, 0);
|
||||
matrix_4x4_translate(mop, -1.0, -1.0, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_multiply(m1,
|
||||
*((math_matrix_4x4*)draw->matrix_data), m2);
|
||||
matrix_4x4_scale(mop,
|
||||
(draw->width / 2.0) / video_width,
|
||||
(draw->height / 2.0) / video_height, 0);
|
||||
matrix_4x4_multiply(m2, mop, m1);
|
||||
matrix_4x4_translate(mop,
|
||||
(draw->x + (draw->width / 2.0)) / video_width,
|
||||
(draw->y + (draw->height / 2.0)) / video_height,
|
||||
0);
|
||||
matrix_4x4_multiply(m1, mop, m2);
|
||||
matrix_4x4_multiply(m2, d3d->mvp_transposed, m1);
|
||||
|
||||
IDirect3DDevice9_SetVertexShaderConstantF(d3d->dev,
|
||||
0, (const float*)&m2, 4);
|
||||
|
||||
if (draw && draw->texture)
|
||||
gfx_display_d3d9_bind_texture(draw, d3d);
|
||||
|
||||
type = (D3DPRIMITIVETYPE)gfx_display_prim_to_d3d9_hlsl_enum(draw->prim_type);
|
||||
start = d3d->menu_display.offset;
|
||||
count = draw->coords->vertices -
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP)
|
||||
? 2 : 0);
|
||||
|
||||
IDirect3DDevice9_BeginScene(dev);
|
||||
IDirect3DDevice9_DrawPrimitive(dev, type, start, count);
|
||||
IDirect3DDevice9_EndScene(dev);
|
||||
|
||||
d3d->menu_display.offset += draw->coords->vertices;
|
||||
}
|
||||
|
||||
static void gfx_display_d3d9_hlsl_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
static float t = 0;
|
||||
video_coord_array_t *ca = NULL;
|
||||
|
||||
if (!draw)
|
||||
return;
|
||||
|
||||
ca = &p_disp->dispca;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->coords = NULL;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
if (ca)
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
/* TODO/FIXME - implement */
|
||||
#if 0
|
||||
{
|
||||
struct uniform_info uniform_param = {0};
|
||||
t += 0.01;
|
||||
|
||||
uniform_param.enabled = true;
|
||||
uniform_param.lookup.enable = true;
|
||||
uniform_param.lookup.add_prefix = true;
|
||||
uniform_param.lookup.idx = draw->pipeline_id;
|
||||
uniform_param.lookup.type = SHADER_PROGRAM_VERTEX;
|
||||
uniform_param.type = UNIFORM_1F;
|
||||
uniform_param.lookup.ident = "time";
|
||||
uniform_param.result.f.v0 = t;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_hlsl_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width, unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = x;
|
||||
rect.top = y;
|
||||
rect.right = width + x;
|
||||
rect.bottom = height + y;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
void gfx_display_d3d9_hlsl_scissor_end(void *data,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
RECT rect;
|
||||
d3d9_video_t *d3d9 = (d3d9_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = video_width;
|
||||
rect.bottom = video_height;
|
||||
|
||||
IDirect3DDevice9_SetScissorRect(d3d9->dev, &rect);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_d3d9_hlsl = {
|
||||
gfx_display_d3d9_hlsl_draw,
|
||||
gfx_display_d3d9_hlsl_draw_pipeline,
|
||||
gfx_display_d3d9_hlsl_blend_begin,
|
||||
gfx_display_d3d9_hlsl_blend_end,
|
||||
gfx_display_d3d9_hlsl_get_default_mvp,
|
||||
gfx_display_d3d9_hlsl_get_default_vertices,
|
||||
gfx_display_d3d9_hlsl_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_D3D9_API,
|
||||
GFX_VIDEO_DRIVER_DIRECT3D9_HLSL,
|
||||
"d3d9_hlsl",
|
||||
false,
|
||||
gfx_display_d3d9_hlsl_scissor_begin,
|
||||
gfx_display_d3d9_hlsl_scissor_end
|
||||
};
|
@ -1,125 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
* Copyright (C) 2016-2019 - Brad Parker
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#include <clamping.h>
|
||||
#endif
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include "../common/win32_common.h"
|
||||
#include "../common/gdi_defines.h"
|
||||
#endif
|
||||
|
||||
static const float *gfx_display_gdi_get_default_vertices(void)
|
||||
{
|
||||
static float dummy[16] = {0.0f};
|
||||
return &dummy[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gdi_get_default_tex_coords(void)
|
||||
{
|
||||
static float dummy[16] = {0.0f};
|
||||
return &dummy[0];
|
||||
}
|
||||
|
||||
static void gfx_display_gdi_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
struct gdi_texture *texture = NULL;
|
||||
gdi_t *gdi = (gdi_t*)data;
|
||||
BITMAPINFO info = {{0}};
|
||||
|
||||
if (!gdi || !draw || draw->x < 0 || draw->y < 0 || draw->width <= 1 || draw->height <= 1)
|
||||
return;
|
||||
|
||||
texture = (struct gdi_texture*)draw->texture;
|
||||
|
||||
if (!texture || texture->width <= 1 || texture->height <= 1)
|
||||
return;
|
||||
|
||||
info.bmiHeader.biBitCount = 32;
|
||||
info.bmiHeader.biWidth = texture->width;
|
||||
info.bmiHeader.biHeight = -texture->height;
|
||||
info.bmiHeader.biPlanes = 1;
|
||||
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
info.bmiHeader.biSizeImage = 0;
|
||||
info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
if (gdi->memDC)
|
||||
{
|
||||
#if _WIN32_WINNT >= 0x0410 /* Win98 */
|
||||
BLENDFUNCTION blend = {0};
|
||||
#endif
|
||||
|
||||
if (!gdi->texDC)
|
||||
gdi->texDC = CreateCompatibleDC(gdi->winDC);
|
||||
|
||||
if (texture->bmp)
|
||||
texture->bmp_old = (HBITMAP)SelectObject(gdi->texDC, texture->bmp);
|
||||
else
|
||||
{
|
||||
/* scale texture data into a bitmap we can easily blit later */
|
||||
texture->bmp = CreateCompatibleBitmap(gdi->winDC, draw->width, draw->height);
|
||||
texture->bmp_old = (HBITMAP)SelectObject(gdi->texDC, texture->bmp);
|
||||
|
||||
StretchDIBits(gdi->texDC, 0, 0, draw->width, draw->height, 0, 0, texture->width, texture->height, texture->data, &info, DIB_RGB_COLORS, SRCCOPY);
|
||||
}
|
||||
|
||||
gdi->bmp_old = (HBITMAP)SelectObject(gdi->memDC, gdi->bmp);
|
||||
|
||||
#if _WIN32_WINNT >= 0x0410 /* Win98 */
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
blend.BlendFlags = 0;
|
||||
blend.SourceConstantAlpha = 255;
|
||||
#if 0
|
||||
clamp_8bit(draw->coords->color[3] * 255.0f);
|
||||
#endif
|
||||
blend.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
/* AlphaBlend() is only available since Win98 */
|
||||
AlphaBlend(gdi->memDC, draw->x, video_height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, blend);
|
||||
#if 0
|
||||
TransparentBlt(gdi->memDC, draw->x, video_height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, 0);
|
||||
#endif
|
||||
#else
|
||||
/* Just draw without the blending */
|
||||
StretchBlt(gdi->memDC, draw->x, video_height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, SRCCOPY);
|
||||
|
||||
#endif
|
||||
|
||||
SelectObject(gdi->memDC, gdi->bmp_old);
|
||||
SelectObject(gdi->texDC, texture->bmp_old);
|
||||
}
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gdi = {
|
||||
gfx_display_gdi_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
NULL, /* get_default_mvp */
|
||||
gfx_display_gdi_get_default_vertices,
|
||||
gfx_display_gdi_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_GDI,
|
||||
GFX_VIDEO_DRIVER_GDI,
|
||||
"gdi",
|
||||
false,
|
||||
NULL, /* scissor_begin */
|
||||
NULL /* scissor_end */
|
||||
};
|
@ -1,201 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
* Copyright (C) 2016-2019 - Brad Parker
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
#include "../common/gl1_defines.h"
|
||||
|
||||
static const GLfloat gl1_menu_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const GLfloat gl1_menu_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_gl1_get_default_vertices(void)
|
||||
{
|
||||
return &gl1_menu_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl1_get_default_tex_coords(void)
|
||||
{
|
||||
return &gl1_menu_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_gl1_get_default_mvp(void *data)
|
||||
{
|
||||
gl1_t *gl1 = (gl1_t*)data;
|
||||
|
||||
if (!gl1)
|
||||
return NULL;
|
||||
|
||||
return &gl1->mvp_no_rot;
|
||||
}
|
||||
|
||||
static GLenum gfx_display_prim_to_gl1_enum(
|
||||
enum gfx_display_prim_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return GL_TRIANGLE_STRIP;
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
return GL_TRIANGLES;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_blend_begin(void *data)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_blend_end(void *data)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
const GLfloat *mvp_matrix;
|
||||
gl1_t *gl1 = (gl1_t*)data;
|
||||
|
||||
if (!gl1 || !draw)
|
||||
return;
|
||||
|
||||
if (!draw->coords->vertex)
|
||||
draw->coords->vertex = &gl1_menu_vertexes[0];
|
||||
if (!draw->coords->tex_coord)
|
||||
draw->coords->tex_coord = &gl1_menu_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &gl1_menu_tex_coords[0];
|
||||
if (!draw->texture)
|
||||
return;
|
||||
|
||||
glViewport(draw->x, draw->y, draw->width, draw->height);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture);
|
||||
|
||||
mvp_matrix = draw->matrix_data ? (const GLfloat*)draw->matrix_data
|
||||
: (const GLfloat*)&gl1->mvp_no_rot;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadMatrixf(mvp_matrix);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
#ifdef VITA
|
||||
{
|
||||
unsigned i;
|
||||
static float *vertices3 = NULL;
|
||||
|
||||
if (vertices3)
|
||||
free(vertices3);
|
||||
vertices3 = (float*)malloc(sizeof(float) * 3 * draw->coords->vertices);
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
memcpy(&vertices3[i * 3],
|
||||
&draw->coords->vertex[i * 2],
|
||||
sizeof(float) * 2);
|
||||
vertices3[i * 3 + 2] = 0.0f;
|
||||
}
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertices3);
|
||||
}
|
||||
#else
|
||||
glVertexPointer(2, GL_FLOAT, 0, draw->coords->vertex);
|
||||
#endif
|
||||
|
||||
glColorPointer(4, GL_FLOAT, 0, draw->coords->color);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, draw->coords->tex_coord);
|
||||
|
||||
glDrawArrays(gfx_display_prim_to_gl1_enum(
|
||||
draw->prim_type), 0, draw->coords->vertices);
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
gl1->coords.color = gl1->white_color_ptr;
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
glScissor(x, video_height - y - height, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void gfx_display_gl1_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
glScissor(0, 0, video_width, video_height);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gl1 = {
|
||||
gfx_display_gl1_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
gfx_display_gl1_blend_begin,
|
||||
gfx_display_gl1_blend_end,
|
||||
gfx_display_gl1_get_default_mvp,
|
||||
gfx_display_gl1_get_default_vertices,
|
||||
gfx_display_gl1_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_OPENGL1_API,
|
||||
GFX_VIDEO_DRIVER_OPENGL1,
|
||||
"gl1",
|
||||
false,
|
||||
gfx_display_gl1_scissor_begin,
|
||||
gfx_display_gl1_scissor_end
|
||||
};
|
@ -1,380 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/gl2_common.h"
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
static int scx0, scx1, scy0, scy1;
|
||||
|
||||
/* This array contains problematic GPU drivers
|
||||
* that have problems when we draw outside the
|
||||
* bounds of the framebuffer */
|
||||
static const struct
|
||||
{
|
||||
const char *str;
|
||||
int len;
|
||||
} scissor_device_strings[] = {
|
||||
{ "ARM Mali-4xx", 10 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void scissor_set_rectangle(
|
||||
int x0, int x1, int y0, int y1, int sc)
|
||||
{
|
||||
const int dx = sc ? 10 : 2;
|
||||
const int dy = dx;
|
||||
scx0 = x0 + dx;
|
||||
scx1 = x1 - dx;
|
||||
scy0 = y0 + dy;
|
||||
scy1 = y1 - dy;
|
||||
}
|
||||
|
||||
static bool scissor_is_outside_rectangle(
|
||||
int x0, int x1, int y0, int y1)
|
||||
{
|
||||
if (x1 < scx0)
|
||||
return true;
|
||||
if (scx1 < x0)
|
||||
return true;
|
||||
if (y1 < scy0)
|
||||
return true;
|
||||
if (scy1 < y0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MALI_BUG
|
||||
#endif
|
||||
|
||||
static const GLfloat gl2_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const GLfloat gl2_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_gl2_get_default_vertices(void)
|
||||
{
|
||||
return &gl2_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl2_get_default_tex_coords(void)
|
||||
{
|
||||
return &gl2_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_gl2_get_default_mvp(void *data)
|
||||
{
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
|
||||
if (!gl)
|
||||
return NULL;
|
||||
|
||||
return &gl->mvp_no_rot;
|
||||
}
|
||||
|
||||
static GLenum gfx_display_prim_to_gl_enum(
|
||||
enum gfx_display_prim_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
return GL_TRIANGLE_STRIP;
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
return GL_TRIANGLES;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_blend_begin(void *data)
|
||||
{
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl->shader->use(gl, gl->shader_data, VIDEO_SHADER_STOCK_BLEND,
|
||||
true);
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_blend_end(void *data)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
#ifdef MALI_BUG
|
||||
static bool
|
||||
gfx_display_gl2_discard_draw_rectangle(gfx_display_ctx_draw_t *draw,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
static bool mali_4xx_detected = false;
|
||||
static bool scissor_inited = false;
|
||||
static unsigned last_video_width = 0;
|
||||
static unsigned last_video_height = 0;
|
||||
|
||||
if (!scissor_inited)
|
||||
{
|
||||
unsigned i;
|
||||
const char *gpu_device_string = NULL;
|
||||
scissor_inited = true;
|
||||
|
||||
scissor_set_rectangle(0,
|
||||
width - 1,
|
||||
0,
|
||||
height - 1,
|
||||
0);
|
||||
|
||||
/* TODO/FIXME - This might be thread unsafe in the long run -
|
||||
* preferably call this once outside of the menu display driver
|
||||
* and then just pass this string as a parameter */
|
||||
gpu_device_string = video_driver_get_gpu_device_string();
|
||||
|
||||
if (gpu_device_string)
|
||||
{
|
||||
for (i = 0; scissor_device_strings[i].len; ++i)
|
||||
{
|
||||
if (strncmp(gpu_device_string,
|
||||
scissor_device_strings[i].str,
|
||||
scissor_device_strings[i].len) == 0)
|
||||
{
|
||||
mali_4xx_detected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_video_width = width;
|
||||
last_video_height = height;
|
||||
}
|
||||
|
||||
/* Early out, to minimise performance impact on
|
||||
* non-mali_4xx devices */
|
||||
if (!mali_4xx_detected)
|
||||
return false;
|
||||
|
||||
/* Have to update scissor_set_rectangle() if the
|
||||
* video dimensions change */
|
||||
if ( (width != last_video_width)
|
||||
|| (height != last_video_height))
|
||||
{
|
||||
scissor_set_rectangle(0,
|
||||
width - 1,
|
||||
0,
|
||||
height - 1,
|
||||
0);
|
||||
|
||||
last_video_width = width;
|
||||
last_video_height = height;
|
||||
}
|
||||
|
||||
/* Discards not only out-of-bounds scissoring,
|
||||
* but also out-of-view draws.
|
||||
*
|
||||
* This is intentional.
|
||||
*/
|
||||
return scissor_is_outside_rectangle(
|
||||
draw->x, draw->x + draw->width - 1,
|
||||
draw->y, draw->y + draw->height - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gfx_display_gl2_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
|
||||
if (!gl || !draw)
|
||||
return;
|
||||
|
||||
#ifdef MALI_BUG
|
||||
if (gfx_display_gl2_discard_draw_rectangle(draw, video_width,
|
||||
video_height))
|
||||
{
|
||||
/*RARCH_WARN("[Menu]: discarded draw rect: %.4i %.4i %.4i %.4i\n",
|
||||
(int)draw->x, (int)draw->y, (int)draw->width, (int)draw->height);*/
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!draw->coords->vertex)
|
||||
draw->coords->vertex = &gl2_vertexes[0];
|
||||
if (!draw->coords->tex_coord)
|
||||
draw->coords->tex_coord = &gl2_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &gl2_tex_coords[0];
|
||||
|
||||
glViewport(draw->x, draw->y, draw->width, draw->height);
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)draw->texture);
|
||||
|
||||
gl->shader->set_coords(gl->shader_data, draw->coords);
|
||||
gl->shader->set_mvp(gl->shader_data,
|
||||
draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data
|
||||
: (math_matrix_4x4*)&gl->mvp_no_rot);
|
||||
|
||||
|
||||
glDrawArrays(gfx_display_prim_to_gl_enum(
|
||||
draw->prim_type), 0, draw->coords->vertices);
|
||||
|
||||
gl->coords.color = gl->white_color_ptr;
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
struct uniform_info uniform_param;
|
||||
gl2_t *gl = (gl2_t*)data;
|
||||
static float t = 0;
|
||||
video_coord_array_t *ca = &p_disp->dispca;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->coords = (struct video_coords*)(&ca->coords);
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
break;
|
||||
default:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
gl->shader->use(gl, gl->shader_data, draw->pipeline_id,
|
||||
true);
|
||||
|
||||
t += 0.01;
|
||||
|
||||
uniform_param.type = UNIFORM_1F;
|
||||
uniform_param.enabled = true;
|
||||
uniform_param.location = 0;
|
||||
uniform_param.count = 0;
|
||||
|
||||
uniform_param.lookup.type = SHADER_PROGRAM_VERTEX;
|
||||
uniform_param.lookup.ident = "time";
|
||||
uniform_param.lookup.idx = draw->pipeline_id;
|
||||
uniform_param.lookup.add_prefix = true;
|
||||
uniform_param.lookup.enable = true;
|
||||
|
||||
uniform_param.result.f.v0 = t;
|
||||
|
||||
gl->shader->set_uniform_parameter(gl->shader_data,
|
||||
&uniform_param, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
#ifndef HAVE_PSGL
|
||||
uniform_param.type = UNIFORM_2F;
|
||||
uniform_param.lookup.ident = "OutputSize";
|
||||
uniform_param.result.f.v0 = draw->width;
|
||||
uniform_param.result.f.v1 = draw->height;
|
||||
|
||||
gl->shader->set_uniform_parameter(gl->shader_data,
|
||||
&uniform_param, NULL);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
glScissor(x, video_height - y - height, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#ifdef MALI_BUG
|
||||
/* TODO/FIXME: If video width/height changes between
|
||||
* a call of gfx_display_gl2_scissor_begin() and the
|
||||
* next call of gfx_display_gl2_draw() (or if
|
||||
* gfx_display_gl2_scissor_begin() is called before the
|
||||
* first call of gfx_display_gl2_draw()), the scissor
|
||||
* rectangle set here will be overwritten by the initialisation
|
||||
* procedure inside gfx_display_gl2_discard_draw_rectangle(),
|
||||
* causing the next frame to render glitched content */
|
||||
scissor_set_rectangle(x, x + width - 1, y, y + height - 1, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_gl2_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
glScissor(0, 0, video_width, video_height);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
#ifdef MALI_BUG
|
||||
scissor_set_rectangle(0, video_width - 1, 0, video_height - 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gl = {
|
||||
gfx_display_gl2_draw,
|
||||
gfx_display_gl2_draw_pipeline,
|
||||
gfx_display_gl2_blend_begin,
|
||||
gfx_display_gl2_blend_end,
|
||||
gfx_display_gl2_get_default_mvp,
|
||||
gfx_display_gl2_get_default_vertices,
|
||||
gfx_display_gl2_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_OPENGL_API,
|
||||
GFX_VIDEO_DRIVER_OPENGL,
|
||||
"gl",
|
||||
false,
|
||||
gfx_display_gl2_scissor_begin,
|
||||
gfx_display_gl2_scissor_end
|
||||
};
|
@ -1,324 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2016-2017 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/gl3_common.h"
|
||||
|
||||
static const float gl3_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float gl3_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float gl3_colors[16] = {
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static void *gfx_display_gl3_get_default_mvp(void *data)
|
||||
{
|
||||
gl3_t *gl3 = (gl3_t*)data;
|
||||
if (!gl3)
|
||||
return NULL;
|
||||
return &gl3->mvp_no_rot;
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl3_get_default_vertices(void)
|
||||
{
|
||||
return &gl3_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_gl3_get_default_tex_coords(void)
|
||||
{
|
||||
return &gl3_tex_coords[0];
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
float output_size[2];
|
||||
static struct video_coords blank_coords;
|
||||
static uint8_t ubo_scratch_data[768];
|
||||
static float t = 0.0f;
|
||||
float yflip = 0.0f;
|
||||
video_coord_array_t *ca = NULL;
|
||||
gl3_t *gl = (gl3_t*)data;
|
||||
|
||||
if (!gl || !draw)
|
||||
return;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
output_size[0] = (float)video_width;
|
||||
output_size[1] = (float)video_height;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
/* Ribbon */
|
||||
default:
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
ca = &p_disp->dispca;
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = 2 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
yflip = -1.0f;
|
||||
memcpy(ubo_scratch_data, &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(float), &yflip, sizeof(yflip));
|
||||
break;
|
||||
|
||||
/* Snow simple */
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = sizeof(math_matrix_4x4)
|
||||
+ 4 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
memcpy(ubo_scratch_data,
|
||||
&gl->mvp_no_rot,
|
||||
sizeof(math_matrix_4x4));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4),
|
||||
output_size,
|
||||
sizeof(output_size));
|
||||
|
||||
if (draw->pipeline_id == VIDEO_SHADER_MENU_5)
|
||||
yflip = 1.0f;
|
||||
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 2 * sizeof(float), &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 3 * sizeof(float), &yflip, sizeof(yflip));
|
||||
draw->coords = &blank_coords;
|
||||
blank_coords.vertices = 4;
|
||||
draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP;
|
||||
break;
|
||||
}
|
||||
|
||||
t += 0.01;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
GLuint texture = 0;
|
||||
gl3_t *gl = (gl3_t*)data;
|
||||
const struct
|
||||
gl3_buffer_locations
|
||||
*loc = NULL;
|
||||
|
||||
if (!gl || !draw)
|
||||
return;
|
||||
|
||||
texture = (GLuint)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = gfx_display_gl3_get_default_vertices();
|
||||
if (!tex_coord)
|
||||
tex_coord = &gl3_tex_coords[0];
|
||||
if (!color)
|
||||
color = &gl3_colors[0];
|
||||
|
||||
glViewport(draw->x, draw->y, draw->width, draw->height);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
break;
|
||||
default:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
case VIDEO_SHADER_MENU:
|
||||
glUseProgram(gl->pipelines.ribbon);
|
||||
loc = &gl->pipelines.ribbon_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
glUseProgram(gl->pipelines.ribbon_simple);
|
||||
loc = &gl->pipelines.ribbon_simple_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
glUseProgram(gl->pipelines.snow_simple);
|
||||
loc = &gl->pipelines.snow_simple_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
glUseProgram(gl->pipelines.snow);
|
||||
loc = &gl->pipelines.snow_loc;
|
||||
break;
|
||||
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
glUseProgram(gl->pipelines.bokeh);
|
||||
loc = &gl->pipelines.bokeh_loc;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
glUseProgram(gl->pipelines.alpha_blend);
|
||||
break;
|
||||
}
|
||||
|
||||
if (loc)
|
||||
{
|
||||
if (loc->flat_ubo_vertex >= 0)
|
||||
glUniform4fv(loc->flat_ubo_vertex,
|
||||
(GLsizei)((draw->backend_data_size + 15) / 16),
|
||||
(const GLfloat*)draw->backend_data);
|
||||
|
||||
if (loc->flat_ubo_fragment >= 0)
|
||||
glUniform4fv(loc->flat_ubo_fragment,
|
||||
(GLsizei)((draw->backend_data_size + 15) / 16),
|
||||
(const GLfloat*)draw->backend_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
const math_matrix_4x4 *mat = draw->matrix_data
|
||||
? (const math_matrix_4x4*)draw->matrix_data
|
||||
: (const math_matrix_4x4*)&gl->mvp_no_rot;
|
||||
if (gl->pipelines.alpha_blend_loc.flat_ubo_vertex >= 0)
|
||||
glUniform4fv(gl->pipelines.alpha_blend_loc.flat_ubo_vertex,
|
||||
4, mat->data);
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
gl3_bind_scratch_vbo(gl, vertex,
|
||||
2 * sizeof(float) * draw->coords->vertices);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), (void *)(uintptr_t)0);
|
||||
gl3_bind_scratch_vbo(gl, tex_coord,
|
||||
2 * sizeof(float) * draw->coords->vertices);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
||||
2 * sizeof(float), (void *)(uintptr_t)0);
|
||||
gl3_bind_scratch_vbo(gl, color,
|
||||
4 * sizeof(float) * draw->coords->vertices);
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE,
|
||||
4 * sizeof(float), (void *)(uintptr_t)0);
|
||||
|
||||
switch (draw->prim_type)
|
||||
{
|
||||
case GFX_DISPLAY_PRIM_TRIANGLESTRIP:
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices);
|
||||
break;
|
||||
case GFX_DISPLAY_PRIM_TRIANGLES:
|
||||
glDrawArrays(GL_TRIANGLES, 0, draw->coords->vertices);
|
||||
break;
|
||||
case GFX_DISPLAY_PRIM_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glDisableVertexAttribArray(2);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_blend_begin(void *data)
|
||||
{
|
||||
gl3_t *gl = (gl3_t*)data;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUseProgram(gl->pipelines.alpha_blend);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_blend_end(void *data)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
glScissor(x, video_height - y - height, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void gfx_display_gl3_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_gl3 = {
|
||||
gfx_display_gl3_draw,
|
||||
gfx_display_gl3_draw_pipeline,
|
||||
gfx_display_gl3_blend_begin,
|
||||
gfx_display_gl3_blend_end,
|
||||
gfx_display_gl3_get_default_mvp,
|
||||
gfx_display_gl3_get_default_vertices,
|
||||
gfx_display_gl3_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_OPENGL_CORE_API,
|
||||
GFX_VIDEO_DRIVER_OPENGL_CORE,
|
||||
"glcore",
|
||||
false,
|
||||
gfx_display_gl3_scissor_begin,
|
||||
gfx_display_gl3_scissor_end
|
||||
};
|
@ -1,122 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2018 - Stuart Carnie
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#import "../common/metal_common.h"
|
||||
|
||||
static const float *gfx_display_metal_get_default_vertices(void)
|
||||
{
|
||||
return [MenuDisplay defaultVertices];
|
||||
}
|
||||
|
||||
static const float *gfx_display_metal_get_default_tex_coords(void)
|
||||
{
|
||||
return [MenuDisplay defaultTexCoords];
|
||||
}
|
||||
|
||||
static void *gfx_display_metal_get_default_mvp(void *data)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (!md)
|
||||
return NULL;
|
||||
|
||||
return (void *)&md.viewportMVP->projectionMatrix;
|
||||
}
|
||||
|
||||
static void gfx_display_metal_blend_begin(void *data)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md)
|
||||
md.display.blend = YES;
|
||||
}
|
||||
|
||||
static void gfx_display_metal_blend_end(void *data)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md)
|
||||
md.display.blend = NO;
|
||||
}
|
||||
|
||||
static void gfx_display_metal_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md && draw)
|
||||
[md.display draw:draw];
|
||||
}
|
||||
|
||||
static void gfx_display_metal_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md && draw)
|
||||
[md.display drawPipeline:draw];
|
||||
}
|
||||
|
||||
static void gfx_display_metal_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
MTLScissorRect r;
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (!md)
|
||||
return;
|
||||
|
||||
r.x = (NSUInteger)x;
|
||||
r.y = (NSUInteger)y;
|
||||
r.width = width;
|
||||
r.height = height;
|
||||
[md.display setScissorRect:r];
|
||||
}
|
||||
|
||||
static void gfx_display_metal_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
MetalDriver *md = (__bridge MetalDriver *)data;
|
||||
if (md)
|
||||
[md.display clearScissorRect];
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_metal = {
|
||||
gfx_display_metal_draw,
|
||||
gfx_display_metal_draw_pipeline,
|
||||
gfx_display_metal_blend_begin,
|
||||
gfx_display_metal_blend_end,
|
||||
gfx_display_metal_get_default_mvp,
|
||||
gfx_display_metal_get_default_vertices,
|
||||
gfx_display_metal_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_METAL_API,
|
||||
GFX_VIDEO_DRIVER_METAL,
|
||||
"metal",
|
||||
false,
|
||||
gfx_display_metal_scissor_begin,
|
||||
gfx_display_metal_scissor_end
|
||||
};
|
@ -1,230 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/rsx_defines.h"
|
||||
|
||||
static const float rsx_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float rsx_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float *gfx_display_rsx_get_default_vertices(void)
|
||||
{
|
||||
return &rsx_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_rsx_get_default_tex_coords(void)
|
||||
{
|
||||
return &rsx_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_rsx_get_default_mvp(void *data)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t*)data;
|
||||
|
||||
if (!rsx)
|
||||
return NULL;
|
||||
|
||||
return &rsx->mvp_no_rot;
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
rsx_viewport_t vp;
|
||||
int end_vert_idx;
|
||||
rsx_vertex_t *vertices = NULL;
|
||||
rsx_texture_t *texture = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
rsx_t *rsx = (rsx_t*)data;
|
||||
|
||||
if (!rsx || !draw)
|
||||
return;
|
||||
|
||||
texture = (rsx_texture_t *)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &rsx_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &rsx_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &rsx_tex_coords[0];
|
||||
if (!draw->texture)
|
||||
return;
|
||||
|
||||
vp.x = fabs(draw->x);
|
||||
vp.y = fabs(rsx->height - draw->y - draw->height);
|
||||
vp.w = MIN(draw->width, rsx->width);
|
||||
vp.h = MIN(draw->height, rsx->height);
|
||||
vp.min = 0.0f;
|
||||
vp.max = 1.0f;
|
||||
vp.scale[0] = vp.w * 0.5f;
|
||||
vp.scale[1] = vp.h * -0.5f;
|
||||
vp.scale[2] = (vp.max - vp.min) * 0.5f;
|
||||
vp.scale[3] = 0.0f;
|
||||
vp.offset[0] = vp.x + vp.w * 0.5f;
|
||||
vp.offset[1] = vp.y + vp.h * 0.5f;
|
||||
vp.offset[2] = (vp.max + vp.min) * 0.5f;
|
||||
vp.offset[3] = 0.0f;
|
||||
|
||||
rsxSetViewport(rsx->context, vp.x, vp.y, vp.w, vp.h, vp.min, vp.max, vp.scale, vp.offset);
|
||||
|
||||
rsxInvalidateTextureCache(rsx->context, GCM_INVALIDATE_TEXTURE);
|
||||
rsxLoadTexture(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, &texture->tex);
|
||||
rsxTextureControl(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index,
|
||||
GCM_TRUE, 0 << 8, 12 << 8, GCM_TEXTURE_MAX_ANISO_1);
|
||||
rsxTextureFilter(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
texture->min_filter, texture->mag_filter, GCM_TEXTURE_CONVOLUTION_QUINCUNX);
|
||||
rsxTextureWrapMode(rsx->context, rsx->tex_unit[RSX_SHADER_STOCK_BLEND]->index, texture->wrap_s,
|
||||
texture->wrap_t, GCM_TEXTURE_CLAMP_TO_EDGE, 0, GCM_TEXTURE_ZFUNC_LESS, 0);
|
||||
|
||||
#if RSX_MAX_TEXTURE_VERTICES > 0
|
||||
/* Using preallocated texture vertices uses better memory managment but may cause more flickering */
|
||||
end_vert_idx = rsx->texture_vert_idx + draw->coords->vertices;
|
||||
if (end_vert_idx > RSX_MAX_TEXTURE_VERTICES)
|
||||
{
|
||||
rsx->texture_vert_idx = 0;
|
||||
end_vert_idx = rsx->texture_vert_idx + draw->coords->vertices;
|
||||
}
|
||||
vertices = &rsx->texture_vertices[rsx->texture_vert_idx];
|
||||
#else
|
||||
/* Smoother gfx at the cost of unmanaged rsx memory */
|
||||
rsx->texture_vert_idx = 0;
|
||||
end_vert_idx = draw->coords->vertices;
|
||||
vertices = (rsx_vertex_t *)rsxMemalign(128, sizeof(rsx_vertex_t) * draw->coords->vertices);
|
||||
#endif
|
||||
for (i = rsx->texture_vert_idx; i < end_vert_idx; i++)
|
||||
{
|
||||
vertices[i].x = *vertex++;
|
||||
vertices[i].y = *vertex++;
|
||||
vertices[i].u = *tex_coord++;
|
||||
vertices[i].v = *tex_coord++;
|
||||
vertices[i].r = *color++;
|
||||
vertices[i].g = *color++;
|
||||
vertices[i].b = *color++;
|
||||
vertices[i].a = *color++;
|
||||
}
|
||||
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].x,
|
||||
&rsx->pos_offset[RSX_SHADER_STOCK_BLEND]);
|
||||
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].u,
|
||||
&rsx->uv_offset[RSX_SHADER_STOCK_BLEND]);
|
||||
rsxAddressToOffset(&vertices[rsx->texture_vert_idx].r,
|
||||
&rsx->col_offset[RSX_SHADER_STOCK_BLEND]);
|
||||
rsx->texture_vert_idx = end_vert_idx;
|
||||
|
||||
rsxBindVertexArrayAttrib(rsx->context, rsx->pos_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
rsx->pos_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2,
|
||||
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
||||
rsxBindVertexArrayAttrib(rsx->context, rsx->uv_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
rsx->uv_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 2,
|
||||
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
||||
rsxBindVertexArrayAttrib(rsx->context, rsx->col_index[RSX_SHADER_STOCK_BLEND]->index, 0,
|
||||
rsx->col_offset[RSX_SHADER_STOCK_BLEND], sizeof(rsx_vertex_t), 4,
|
||||
GCM_VERTEX_DATA_TYPE_F32, GCM_LOCATION_RSX);
|
||||
|
||||
rsxLoadVertexProgram(rsx->context, rsx->vpo[RSX_SHADER_STOCK_BLEND],
|
||||
rsx->vp_ucode[RSX_SHADER_STOCK_BLEND]);
|
||||
rsxSetVertexProgramParameter(rsx->context,
|
||||
rsx->vpo[RSX_SHADER_STOCK_BLEND], rsx->proj_matrix[RSX_SHADER_STOCK_BLEND],
|
||||
(float *)&rsx->mvp_no_rot);
|
||||
rsxLoadFragmentProgramLocation(rsx->context,
|
||||
rsx->fpo[RSX_SHADER_STOCK_BLEND], rsx->fp_offset[RSX_SHADER_STOCK_BLEND],
|
||||
GCM_LOCATION_RSX);
|
||||
|
||||
rsxClearSurface(rsx->context, GCM_CLEAR_Z);
|
||||
rsxDrawVertexArray(rsx->context, GCM_TYPE_TRIANGLE_STRIP, 0, draw->coords->vertices);
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetScissor(rsx->context, x, video_height - y - height, width, height);
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetScissor(rsx->context, 0, 0, video_width, video_height);
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_blend_begin(void *data)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetBlendEnable(rsx->context, GCM_TRUE);
|
||||
rsxSetBlendFunc(rsx->context, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA, GCM_SRC_ALPHA, GCM_ONE_MINUS_SRC_ALPHA);
|
||||
rsxSetBlendEquation(rsx->context, GCM_FUNC_ADD, GCM_FUNC_ADD);
|
||||
#if 0
|
||||
rsxSetBlendEnableMrt(rsx->context, GCM_TRUE, GCM_TRUE, GCM_TRUE);
|
||||
rsxSetDepthFunc(rsx->context, GCM_LESS);
|
||||
rsxSetDepthTestEnable(rsx->context, GCM_FALSE);
|
||||
rsxSetAlphaFunc(rsx->context, GCM_ALWAYS, 0);
|
||||
rsxSetAlphaTestEnable(rsx->context, GCM_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gfx_display_rsx_blend_end(void *data)
|
||||
{
|
||||
rsx_t *rsx = (rsx_t *)data;
|
||||
rsxSetBlendEnable(rsx->context, GCM_FALSE);
|
||||
#if 0
|
||||
rsxSetBlendEnableMrt(rsx->context, GCM_FALSE, GCM_FALSE, GCM_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_rsx = {
|
||||
gfx_display_rsx_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
gfx_display_rsx_blend_begin,
|
||||
gfx_display_rsx_blend_end,
|
||||
gfx_display_rsx_get_default_mvp,
|
||||
gfx_display_rsx_get_default_vertices,
|
||||
gfx_display_rsx_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_RSX,
|
||||
GFX_VIDEO_DRIVER_RSX,
|
||||
"rsx",
|
||||
true,
|
||||
gfx_display_rsx_scissor_begin,
|
||||
gfx_display_rsx_scissor_end
|
||||
};
|
@ -1,166 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <vita2d.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/vita2d_defines.h"
|
||||
#include <defines/psp_defines.h>
|
||||
|
||||
static const float vita2d_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float vita2d_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float vita2d_colors[16] = {
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static const float *gfx_display_vita2d_get_default_vertices(void)
|
||||
{
|
||||
return &vita2d_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_vita2d_get_default_color(void)
|
||||
{
|
||||
return &vita2d_colors[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_vita2d_get_default_tex_coords(void)
|
||||
{
|
||||
return &vita2d_tex_coords[0];
|
||||
}
|
||||
|
||||
static void *gfx_display_vita2d_get_default_mvp(void *data)
|
||||
{
|
||||
vita_video_t *vita2d = (vita_video_t*)data;
|
||||
|
||||
if (!vita2d)
|
||||
return NULL;
|
||||
|
||||
return &vita2d->mvp_no_rot;
|
||||
}
|
||||
|
||||
static void gfx_display_vita2d_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
struct vita2d_texture *texture = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
vita_video_t *vita2d = (vita_video_t*)data;
|
||||
|
||||
if (!vita2d || !draw)
|
||||
return;
|
||||
|
||||
texture = (struct vita2d_texture*)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &vita2d_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &vita2d_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &vita2d_tex_coords[0];
|
||||
if (!texture)
|
||||
return;
|
||||
if (!color)
|
||||
color = &vita2d_colors[0];
|
||||
|
||||
vita2d_set_viewport(draw->x, draw->y, draw->width, draw->height);
|
||||
vita2d_texture_tint_vertex *vertices = (vita2d_texture_tint_vertex *)vita2d_pool_memalign(
|
||||
draw->coords->vertices * sizeof(vita2d_texture_tint_vertex),
|
||||
sizeof(vita2d_texture_tint_vertex));
|
||||
|
||||
for (i = 0; i < draw->coords->vertices; i++)
|
||||
{
|
||||
vertices[i].x = *vertex++;
|
||||
vertices[i].y = *vertex++;
|
||||
vertices[i].z = 1.0f;
|
||||
vertices[i].u = *tex_coord++;
|
||||
vertices[i].v = *tex_coord++;
|
||||
vertices[i].r = *color++;
|
||||
vertices[i].g = *color++;
|
||||
vertices[i].b = *color++;
|
||||
vertices[i].a = *color++;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
default:
|
||||
{
|
||||
vita2d_draw_array_textured_mat(texture, vertices, draw->coords->vertices, &vita2d->mvp_no_rot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_vita2d_scissor_begin(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
vita2d_set_clip_rectangle(x, y, x + width, y + height);
|
||||
vita2d_set_region_clip(SCE_GXM_REGION_CLIP_OUTSIDE, x, y, x + width, y + height);
|
||||
}
|
||||
|
||||
static void gfx_display_vita2d_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
vita2d_set_region_clip(SCE_GXM_REGION_CLIP_NONE, 0, 0,
|
||||
video_width, video_height);
|
||||
vita2d_disable_clipping();
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_vita2d = {
|
||||
gfx_display_vita2d_draw,
|
||||
NULL, /* draw_pipeline */
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
gfx_display_vita2d_get_default_mvp,
|
||||
gfx_display_vita2d_get_default_vertices,
|
||||
gfx_display_vita2d_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_VITA2D,
|
||||
GFX_VIDEO_DRIVER_VITA2D,
|
||||
"vita2d",
|
||||
true,
|
||||
gfx_display_vita2d_scissor_begin,
|
||||
gfx_display_vita2d_scissor_end
|
||||
};
|
@ -1,332 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2016-2017 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/vulkan_common.h"
|
||||
|
||||
/* Will do Y-flip later, but try to make it similar to GL. */
|
||||
static const float vk_vertexes[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
0, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const float vk_tex_coords[8] = {
|
||||
0, 1,
|
||||
1, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
};
|
||||
|
||||
static const float vk_colors[16] = {
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
static void *gfx_display_vk_get_default_mvp(void *data)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
if (!vk)
|
||||
return NULL;
|
||||
return &vk->mvp_no_rot;
|
||||
}
|
||||
|
||||
static const float *gfx_display_vk_get_default_vertices(void)
|
||||
{
|
||||
return &vk_vertexes[0];
|
||||
}
|
||||
|
||||
static const float *gfx_display_vk_get_default_tex_coords(void)
|
||||
{
|
||||
return &vk_tex_coords[0];
|
||||
}
|
||||
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
static unsigned to_menu_pipeline(
|
||||
enum gfx_display_prim_type type, unsigned pipeline)
|
||||
{
|
||||
switch (pipeline)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
return 6 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
return 8 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
return 10 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
return 12 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
return 14 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
static uint8_t ubo_scratch_data[768];
|
||||
static struct video_coords blank_coords;
|
||||
static float t = 0.0f;
|
||||
float output_size[2];
|
||||
float yflip = 1.0f;
|
||||
video_coord_array_t *ca = NULL;
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (!vk || !draw)
|
||||
return;
|
||||
|
||||
draw->x = 0;
|
||||
draw->y = 0;
|
||||
draw->matrix_data = NULL;
|
||||
|
||||
output_size[0] = (float)vk->context->swapchain_width;
|
||||
output_size[1] = (float)vk->context->swapchain_height;
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
/* Ribbon */
|
||||
default:
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
ca = &p_disp->dispca;
|
||||
draw->coords = (struct video_coords*)&ca->coords;
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = 2 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
memcpy(ubo_scratch_data, &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(float), &yflip, sizeof(yflip));
|
||||
break;
|
||||
|
||||
/* Snow simple */
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
draw->backend_data = ubo_scratch_data;
|
||||
draw->backend_data_size = sizeof(math_matrix_4x4)
|
||||
+ 4 * sizeof(float);
|
||||
|
||||
/* Match UBO layout in shader. */
|
||||
memcpy(ubo_scratch_data,
|
||||
&vk->mvp_no_rot,
|
||||
sizeof(math_matrix_4x4));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4),
|
||||
output_size,
|
||||
sizeof(output_size));
|
||||
|
||||
/* Shader uses FragCoord, need to fix up. */
|
||||
if (draw->pipeline_id == VIDEO_SHADER_MENU_5)
|
||||
yflip = -1.0f;
|
||||
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 2 * sizeof(float), &t, sizeof(t));
|
||||
memcpy(ubo_scratch_data + sizeof(math_matrix_4x4)
|
||||
+ 3 * sizeof(float), &yflip, sizeof(yflip));
|
||||
draw->coords = &blank_coords;
|
||||
blank_coords.vertices = 4;
|
||||
draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP;
|
||||
break;
|
||||
}
|
||||
|
||||
t += 0.01;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gfx_display_vk_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
unsigned i;
|
||||
struct vk_buffer_range range;
|
||||
struct vk_texture *texture = NULL;
|
||||
const float *vertex = NULL;
|
||||
const float *tex_coord = NULL;
|
||||
const float *color = NULL;
|
||||
struct vk_vertex *pv = NULL;
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (!vk || !draw)
|
||||
return;
|
||||
|
||||
texture = (struct vk_texture*)draw->texture;
|
||||
vertex = draw->coords->vertex;
|
||||
tex_coord = draw->coords->tex_coord;
|
||||
color = draw->coords->color;
|
||||
|
||||
if (!vertex)
|
||||
vertex = &vk_vertexes[0];
|
||||
if (!tex_coord)
|
||||
tex_coord = &vk_tex_coords[0];
|
||||
if (!draw->coords->lut_tex_coord)
|
||||
draw->coords->lut_tex_coord = &vk_tex_coords[0];
|
||||
if (!texture)
|
||||
texture = &vk->display.blank_texture;
|
||||
if (!color)
|
||||
color = &vk_colors[0];
|
||||
|
||||
vk->vk_vp.x = draw->x;
|
||||
vk->vk_vp.y = vk->context->swapchain_height - draw->y - draw->height;
|
||||
vk->vk_vp.width = draw->width;
|
||||
vk->vk_vp.height = draw->height;
|
||||
vk->vk_vp.minDepth = 0.0f;
|
||||
vk->vk_vp.maxDepth = 1.0f;
|
||||
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
|
||||
/* Bake interleaved VBO. Kinda ugly, we should probably try to move to
|
||||
* an interleaved model to begin with ... */
|
||||
if (!vulkan_buffer_chain_alloc(vk->context, &vk->chain->vbo,
|
||||
draw->coords->vertices * sizeof(struct vk_vertex), &range))
|
||||
return;
|
||||
|
||||
pv = (struct vk_vertex*)range.data;
|
||||
for (i = 0; i < draw->coords->vertices; i++, pv++)
|
||||
{
|
||||
pv->x = *vertex++;
|
||||
/* Y-flip. Vulkan is top-left clip space */
|
||||
pv->y = 1.0f - (*vertex++);
|
||||
pv->tex_x = *tex_coord++;
|
||||
pv->tex_y = *tex_coord++;
|
||||
pv->color.r = *color++;
|
||||
pv->color.g = *color++;
|
||||
pv->color.b = *color++;
|
||||
pv->color.a = *color++;
|
||||
}
|
||||
|
||||
switch (draw->pipeline_id)
|
||||
{
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
{
|
||||
struct vk_draw_triangles call;
|
||||
|
||||
call.pipeline = vk->display.pipelines[
|
||||
to_menu_pipeline(draw->prim_type, draw->pipeline_id)];
|
||||
call.texture = NULL;
|
||||
call.sampler = VK_NULL_HANDLE;
|
||||
call.uniform = draw->backend_data;
|
||||
call.uniform_size = draw->backend_data_size;
|
||||
call.vbo = ⦥
|
||||
call.vertices = draw->coords->vertices;
|
||||
|
||||
vulkan_draw_triangles(vk, &call);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
struct vk_draw_triangles call;
|
||||
unsigned
|
||||
disp_pipeline =
|
||||
((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP) << 1)
|
||||
| (((vk->flags & VK_FLAG_DISPLAY_BLEND) > 0) << 0);
|
||||
call.pipeline = vk->display.pipelines[disp_pipeline];
|
||||
call.texture = texture;
|
||||
call.sampler = (texture->flags & VK_TEX_FLAG_MIPMAP) ?
|
||||
vk->samplers.mipmap_linear :
|
||||
((texture->flags & VK_TEX_FLAG_DEFAULT_SMOOTH) ? vk->samplers.linear
|
||||
: vk->samplers.nearest);
|
||||
call.uniform = draw->matrix_data
|
||||
? draw->matrix_data : &vk->mvp_no_rot;
|
||||
call.uniform_size = sizeof(math_matrix_4x4);
|
||||
call.vbo = ⦥
|
||||
call.vertices = draw->coords->vertices;
|
||||
|
||||
vulkan_draw_triangles(vk, &call);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_display_vk_blend_begin(void *data)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (vk)
|
||||
vk->flags |= VK_FLAG_DISPLAY_BLEND;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_blend_end(void *data)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
if (vk)
|
||||
vk->flags &= ~VK_FLAG_DISPLAY_BLEND;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
vk->tracker.scissor.offset.x = x;
|
||||
vk->tracker.scissor.offset.y = y;
|
||||
vk->tracker.scissor.extent.width = width;
|
||||
vk->tracker.scissor.extent.height = height;
|
||||
vk->flags |= VK_FLAG_TRACKER_USE_SCISSOR;
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
static void gfx_display_vk_scissor_end(void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height)
|
||||
{
|
||||
vk_t *vk = (vk_t*)data;
|
||||
|
||||
vk->flags &= ~VK_FLAG_TRACKER_USE_SCISSOR;
|
||||
vk->tracker.dirty |= VULKAN_DIRTY_DYNAMIC_BIT;
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_vulkan = {
|
||||
gfx_display_vk_draw,
|
||||
#ifdef HAVE_SHADERPIPELINE
|
||||
gfx_display_vk_draw_pipeline,
|
||||
#else
|
||||
NULL, /* draw_pipeline */
|
||||
#endif
|
||||
gfx_display_vk_blend_begin,
|
||||
gfx_display_vk_blend_end,
|
||||
gfx_display_vk_get_default_mvp,
|
||||
gfx_display_vk_get_default_vertices,
|
||||
gfx_display_vk_get_default_tex_coords,
|
||||
FONT_DRIVER_RENDER_VULKAN_API,
|
||||
GFX_VIDEO_DRIVER_VULKAN,
|
||||
"vulkan",
|
||||
false,
|
||||
gfx_display_vk_scissor_begin,
|
||||
gfx_display_vk_scissor_end
|
||||
};
|
@ -1,313 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2014-2017 - Ali Bouhlel
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <wiiu/gx2.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../gfx_display.h"
|
||||
|
||||
#include "../common/gx2_defines.h"
|
||||
#include "../../wiiu/system/memory.h"
|
||||
#include "../../wiiu/wiiu_dbg.h"
|
||||
|
||||
static void gfx_display_wiiu_draw(gfx_display_ctx_draw_t *draw,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
wiiu_video_t *wiiu = (wiiu_video_t*)data;
|
||||
|
||||
if (!wiiu || !draw)
|
||||
return;
|
||||
|
||||
if (draw->pipeline_id)
|
||||
{
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK);
|
||||
|
||||
switch(draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
GX2SetShader(&ribbon_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
GX2SetShader(&ribbon_simple_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
GX2SetShader(&snow_simple_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
GX2SetShader(&snow_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
GX2SetShader(&bokeh_shader);
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
GX2SetShader(&snowflake_shader);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLE_STRIP, draw->coords->vertices, 0, 1);
|
||||
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
|
||||
GX2_BLEND_COMBINE_MODE_ADD,
|
||||
GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
|
||||
GX2_BLEND_COMBINE_MODE_ADD);
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
/* TODO come up with a better check for "not all vertexes are the same color" */
|
||||
else if (draw->coords->vertex || draw->coords->color[0] != draw->coords->color[12])
|
||||
{
|
||||
int i;
|
||||
if (wiiu->vertex_cache_tex.current + 4 > wiiu->vertex_cache_tex.size)
|
||||
return;
|
||||
|
||||
tex_shader_vertex_t* v = wiiu->vertex_cache_tex.v + wiiu->vertex_cache_tex.current;
|
||||
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK);
|
||||
GX2SetShader(&tex_shader);
|
||||
GX2SetVertexUniformBlock(tex_shader.vs.uniformBlocks[0].offset,
|
||||
tex_shader.vs.uniformBlocks[0].size,
|
||||
wiiu->ubo_mvp);
|
||||
GX2SetAttribBuffer(0, wiiu->vertex_cache_tex.size * sizeof(*wiiu->vertex_cache_tex.v),
|
||||
sizeof(*wiiu->vertex_cache_tex.v), wiiu->vertex_cache_tex.v);
|
||||
|
||||
if (!draw->coords->vertex)
|
||||
{
|
||||
/* Convert the libretro bottom-up coordinate system to GX2 - low y at
|
||||
the top of the screen, large y at the bottom
|
||||
The compiler will optimise 90% of this out anyway */
|
||||
float y = -(draw->y + draw->height - video_height);
|
||||
/* Remember: this is a triangle strip, not a quad, draw in a Z shape
|
||||
Bottom-left, right, top-left, right */
|
||||
v[0].pos.x = (draw->x ) / video_width;
|
||||
v[0].pos.y = (y + draw->height) / video_height;
|
||||
v[1].pos.x = (draw->x + draw->width ) / video_width;
|
||||
v[1].pos.y = (y + draw->height) / video_height;
|
||||
v[2].pos.x = (draw->x ) / video_width;
|
||||
v[2].pos.y = (y ) / video_height;
|
||||
v[3].pos.x = (draw->x + draw->width ) / video_width;
|
||||
v[3].pos.y = (y ) / video_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0].pos.x = draw->coords->vertex[0];
|
||||
v[0].pos.y = 1.0 - draw->coords->vertex[1];
|
||||
v[1].pos.x = draw->coords->vertex[2];
|
||||
v[1].pos.y = 1.0 - draw->coords->vertex[3];
|
||||
v[2].pos.x = draw->coords->vertex[4];
|
||||
v[2].pos.y = 1.0 - draw->coords->vertex[5];
|
||||
v[3].pos.x = draw->coords->vertex[6];
|
||||
v[3].pos.y = 1.0 - draw->coords->vertex[7];
|
||||
}
|
||||
|
||||
if (!draw->coords->tex_coord)
|
||||
{
|
||||
v[0].coord.u = 0.0f;
|
||||
v[0].coord.v = 1.0f;
|
||||
v[1].coord.u = 1.0f;
|
||||
v[1].coord.v = 1.0f;
|
||||
v[2].coord.u = 0.0f;
|
||||
v[2].coord.v = 0.0f;
|
||||
v[3].coord.u = 1.0f;
|
||||
v[3].coord.v = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
v[0].coord.u = draw->coords->tex_coord[0];
|
||||
v[0].coord.v = draw->coords->tex_coord[1];
|
||||
v[1].coord.u = draw->coords->tex_coord[2];
|
||||
v[1].coord.v = draw->coords->tex_coord[3];
|
||||
v[2].coord.u = draw->coords->tex_coord[4];
|
||||
v[2].coord.v = draw->coords->tex_coord[5];
|
||||
v[3].coord.u = draw->coords->tex_coord[6];
|
||||
v[3].coord.v = draw->coords->tex_coord[7];
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
v[i].color.r = draw->coords->color[(i << 2) + 0];
|
||||
v[i].color.g = draw->coords->color[(i << 2) + 1];
|
||||
v[i].color.b = draw->coords->color[(i << 2) + 2];
|
||||
v[i].color.a = draw->coords->color[(i << 2) + 3];
|
||||
}
|
||||
|
||||
if (draw->texture)
|
||||
GX2SetPixelTexture((GX2Texture*)draw->texture, tex_shader.ps.samplerVars[0].location);
|
||||
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_TRIANGLE_STRIP, 4, wiiu->vertex_cache_tex.current, 1);
|
||||
wiiu->vertex_cache_tex.current += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite_vertex_t* v;
|
||||
if (wiiu->vertex_cache.current + 1 > wiiu->vertex_cache.size)
|
||||
return;
|
||||
|
||||
v = wiiu->vertex_cache.v + wiiu->vertex_cache.current;
|
||||
v->pos.x = draw->x;
|
||||
v->pos.y = wiiu->color_buffer.surface.height -
|
||||
draw->y - draw->height;
|
||||
v->pos.width = draw->width;
|
||||
v->pos.height = draw->height;
|
||||
v->coord.u = 0.0f;
|
||||
v->coord.v = 0.0f;
|
||||
v->coord.width = 1.0f;
|
||||
v->coord.height = 1.0f;
|
||||
|
||||
v->color = COLOR_RGBA(
|
||||
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||
|
||||
if (draw->texture)
|
||||
GX2SetPixelTexture((GX2Texture*)draw->texture, sprite_shader.ps.samplerVars[0].location);
|
||||
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, 1, wiiu->vertex_cache.current, 1);
|
||||
wiiu->vertex_cache.current ++;
|
||||
return;
|
||||
}
|
||||
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_GEOMETRY_SHADER);
|
||||
GX2SetShader(&sprite_shader);
|
||||
#if 0
|
||||
GX2SetGeometryShaderInputRingBuffer(wiiu->input_ring_buffer,
|
||||
wiiu->input_ring_buffer_size);
|
||||
GX2SetGeometryShaderOutputRingBuffer(wiiu->output_ring_buffer,
|
||||
wiiu->output_ring_buffer_size);
|
||||
#endif
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset,
|
||||
sprite_shader.vs.uniformBlocks[0].size,
|
||||
wiiu->ubo_vp);
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset,
|
||||
sprite_shader.vs.uniformBlocks[1].size,
|
||||
wiiu->ubo_tex);
|
||||
GX2SetAttribBuffer(0, wiiu->vertex_cache.size
|
||||
* sizeof(*wiiu->vertex_cache.v),
|
||||
sizeof(*wiiu->vertex_cache.v),
|
||||
wiiu->vertex_cache.v);
|
||||
}
|
||||
|
||||
static void gfx_display_wiiu_draw_pipeline(
|
||||
gfx_display_ctx_draw_t *draw,
|
||||
gfx_display_t *p_disp,
|
||||
void *data, unsigned video_width, unsigned video_height)
|
||||
{
|
||||
video_coord_array_t *ca = NULL;
|
||||
wiiu_video_t *wiiu = (wiiu_video_t*)data;
|
||||
|
||||
if (!wiiu || !draw)
|
||||
return;
|
||||
|
||||
switch(draw->pipeline_id)
|
||||
{
|
||||
case VIDEO_SHADER_MENU:
|
||||
case VIDEO_SHADER_MENU_2:
|
||||
ca = &p_disp->dispca;
|
||||
if (!wiiu->menu_shader_vbo)
|
||||
{
|
||||
wiiu->menu_shader_vbo = MEM2_alloc(ca->coords.vertices * 2 * sizeof(float), GX2_VERTEX_BUFFER_ALIGNMENT);
|
||||
memcpy(wiiu->menu_shader_vbo, ca->coords.vertex, ca->coords.vertices * 2 * sizeof(float));
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, wiiu->menu_shader_vbo, ca->coords.vertices * 2 * sizeof(float));
|
||||
}
|
||||
|
||||
draw->coords->vertex = wiiu->menu_shader_vbo;
|
||||
draw->coords->vertices = ca->coords.vertices;
|
||||
GX2SetAttribBuffer(0,
|
||||
draw->coords->vertices * 2 * sizeof(float),
|
||||
2 * sizeof(float), wiiu->menu_shader_vbo);
|
||||
GX2SetBlendControl(GX2_RENDER_TARGET_0,
|
||||
GX2_BLEND_MODE_SRC_ALPHA,
|
||||
GX2_BLEND_MODE_ONE,
|
||||
GX2_BLEND_COMBINE_MODE_ADD,
|
||||
GX2_DISABLE, 0, 0, 0);
|
||||
|
||||
break;
|
||||
case VIDEO_SHADER_MENU_3:
|
||||
case VIDEO_SHADER_MENU_4:
|
||||
case VIDEO_SHADER_MENU_5:
|
||||
case VIDEO_SHADER_MENU_6:
|
||||
GX2SetAttribBuffer(0,
|
||||
4 * sizeof(*wiiu->v),
|
||||
sizeof(*wiiu->v), wiiu->v);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wiiu->menu_shader_ubo)
|
||||
{
|
||||
wiiu->menu_shader_ubo = MEM2_alloc(
|
||||
sizeof(*wiiu->menu_shader_ubo),
|
||||
GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
matrix_4x4_ortho(wiiu->menu_shader_ubo->mvp, 0, 1, 1, 0, -1, 1);
|
||||
wiiu->menu_shader_ubo->OutputSize.width = wiiu->color_buffer.surface.width;
|
||||
wiiu->menu_shader_ubo->OutputSize.height = wiiu->color_buffer.surface.height;
|
||||
wiiu->menu_shader_ubo->time = 0.0f;
|
||||
}
|
||||
else
|
||||
wiiu->menu_shader_ubo->time += 0.01f;
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->menu_shader_ubo, sizeof(*wiiu->menu_shader_ubo));
|
||||
GX2SetVertexUniformBlock(1, sizeof(*wiiu->menu_shader_ubo), wiiu->menu_shader_ubo);
|
||||
GX2SetPixelUniformBlock(1, sizeof(*wiiu->menu_shader_ubo), wiiu->menu_shader_ubo);
|
||||
}
|
||||
|
||||
static void gfx_display_wiiu_scissor_begin(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height,
|
||||
int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
GX2SetScissor(MAX(x, 0), MAX(y, 0), MIN(width, video_width), MIN(height, video_height));
|
||||
}
|
||||
|
||||
static void gfx_display_wiiu_scissor_end(
|
||||
void *data,
|
||||
unsigned video_width,
|
||||
unsigned video_height
|
||||
)
|
||||
{
|
||||
GX2SetScissor(0, 0, video_width, video_height);
|
||||
}
|
||||
|
||||
gfx_display_ctx_driver_t gfx_display_ctx_wiiu = {
|
||||
gfx_display_wiiu_draw,
|
||||
gfx_display_wiiu_draw_pipeline,
|
||||
NULL, /* blend_begin */
|
||||
NULL, /* blend_end */
|
||||
NULL, /* get_default_mvp */
|
||||
NULL, /* get_default_vertices */
|
||||
NULL, /* get_default_tex_coords */
|
||||
FONT_DRIVER_RENDER_WIIU,
|
||||
GFX_VIDEO_DRIVER_WIIU,
|
||||
"gx2",
|
||||
true,
|
||||
gfx_display_wiiu_scissor_begin,
|
||||
gfx_display_wiiu_scissor_end
|
||||
};
|
@ -302,7 +302,6 @@ VIDEO CONTEXT
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
#include "../gfx/common/vulkan_common.c"
|
||||
#include "../gfx/drivers_display/gfx_display_vulkan.c"
|
||||
#include "../libretro-common/vulkan/vulkan_symbol_wrapper.c"
|
||||
#ifdef HAVE_VULKAN_DISPLAY
|
||||
#include "../gfx/drivers_context/khr_display_ctx.c"
|
||||
@ -415,7 +414,6 @@ VIDEO DRIVER
|
||||
#if defined(HAVE_D3D8)
|
||||
#include "../gfx/drivers/d3d8.c"
|
||||
#include "../gfx/common/d3d8_common.c"
|
||||
#include "../gfx/drivers_display/gfx_display_d3d8.c"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_D3D9)
|
||||
@ -423,12 +421,10 @@ VIDEO DRIVER
|
||||
|
||||
#ifdef HAVE_HLSL
|
||||
#include "../gfx/drivers/d3d9hlsl.c"
|
||||
#include "../gfx/drivers_display/gfx_display_d3d9hlsl.c"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CG
|
||||
#include "../gfx/drivers/d3d9cg.c"
|
||||
#include "../gfx/drivers_display/gfx_display_d3d9cg.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -438,19 +434,16 @@ VIDEO DRIVER
|
||||
#if defined(HAVE_D3D11)
|
||||
#include "../gfx/drivers/d3d11.c"
|
||||
#include "../gfx/common/d3d11_common.c"
|
||||
#include "../gfx/drivers_display/gfx_display_d3d11.c"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_D3D12)
|
||||
#include "../gfx/drivers/d3d12.c"
|
||||
#include "../gfx/common/d3d12_common.c"
|
||||
#include "../gfx/drivers_display/gfx_display_d3d12.c"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_D3D10)
|
||||
#include "../gfx/drivers/d3d10.c"
|
||||
#include "../gfx/common/d3d10_common.c"
|
||||
#include "../gfx/drivers_display/gfx_display_d3d10.c"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_D3D10) || defined(HAVE_D3D11) || defined(HAVE_D3D12)
|
||||
@ -467,7 +460,6 @@ VIDEO DRIVER
|
||||
|
||||
#if defined(__wiiu__)
|
||||
#include "../gfx/drivers/gx2_gfx.c"
|
||||
#include "../gfx/drivers_display/gfx_display_wiiu.c"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
@ -501,17 +493,14 @@ VIDEO DRIVER
|
||||
|
||||
#ifdef HAVE_OPENGL1
|
||||
#include "../gfx/drivers/gl1.c"
|
||||
#include "../gfx/drivers_display/gfx_display_gl1.c"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENGL_CORE
|
||||
#include "../gfx/drivers/gl3.c"
|
||||
#include "../gfx/drivers_display/gfx_display_gl3.c"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
#include "../gfx/drivers/gl2.c"
|
||||
#include "../gfx/drivers_display/gfx_display_gl2.c"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGL_CORE)
|
||||
@ -536,7 +525,6 @@ VIDEO DRIVER
|
||||
|
||||
#if defined(HAVE_GCM)
|
||||
#include "../gfx/drivers/rsx_gfx.c"
|
||||
#include "../gfx/drivers_display/gfx_display_rsx.c"
|
||||
#elif defined(GEKKO)
|
||||
#include "../gfx/drivers/gx_gfx.c"
|
||||
#elif defined(PSP)
|
||||
@ -550,10 +538,8 @@ VIDEO DRIVER
|
||||
#include "../deps/libvita2d/source/utils.c"
|
||||
|
||||
#include "../gfx/drivers/vita2d_gfx.c"
|
||||
#include "../gfx/drivers_display/gfx_display_vita2d.c"
|
||||
#elif defined(_3DS)
|
||||
#include "../gfx/drivers/ctr_gfx.c"
|
||||
#include "../gfx/drivers_display/gfx_display_ctr.c"
|
||||
#elif defined(XENON)
|
||||
#include "../gfx/drivers/xenon360_gfx.c"
|
||||
#elif defined(DJGPP)
|
||||
@ -563,7 +549,6 @@ VIDEO DRIVER
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
|
||||
#ifdef HAVE_GDI
|
||||
#include "../gfx/drivers/gdi_gfx.c"
|
||||
#include "../gfx/drivers_display/gfx_display_gdi.c"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -62,5 +62,4 @@
|
||||
#ifdef HAVE_METAL
|
||||
#import "../gfx/common/metal/metal_renderer.m"
|
||||
#import "../gfx/drivers/metal.m"
|
||||
#import "../gfx/drivers_display/gfx_display_metal.m"
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user